xref: /aosp_15_r20/external/deqp/modules/gles2/stress/es2sSpecialFloatTests.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 Special float stress tests.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "es2sSpecialFloatTests.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "gluRenderContext.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "gluShaderProgram.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "gluPixelTransfer.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "gluStrUtil.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "gluContextInfo.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "tcuRenderTarget.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "tcuSurface.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "tcuVectorUtil.hpp"
36*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
37*35238bceSAndroid Build Coastguard Worker #include "deMath.h"
38*35238bceSAndroid Build Coastguard Worker #include "deRandom.hpp"
39*35238bceSAndroid Build Coastguard Worker 
40*35238bceSAndroid Build Coastguard Worker #include <limits>
41*35238bceSAndroid Build Coastguard Worker #include <sstream>
42*35238bceSAndroid Build Coastguard Worker 
43*35238bceSAndroid Build Coastguard Worker using namespace glw;
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 Stress
50*35238bceSAndroid Build Coastguard Worker {
51*35238bceSAndroid Build Coastguard Worker namespace
52*35238bceSAndroid Build Coastguard Worker {
53*35238bceSAndroid Build Coastguard Worker 
54*35238bceSAndroid Build Coastguard Worker static const int TEST_CANVAS_SIZE       = 256;
55*35238bceSAndroid Build Coastguard Worker static const int TEST_TEXTURE_SIZE      = 128;
56*35238bceSAndroid Build Coastguard Worker static const int TEST_TEXTURE_CUBE_SIZE = 32;
57*35238bceSAndroid Build Coastguard Worker static const uint32_t s_specialFloats[] = {
58*35238bceSAndroid Build Coastguard Worker     0x00000000, //          zero
59*35238bceSAndroid Build Coastguard Worker     0x80000000, // negative zero
60*35238bceSAndroid Build Coastguard Worker     0x3F800000, //          one
61*35238bceSAndroid Build Coastguard Worker     0xBF800000, // negative one
62*35238bceSAndroid Build Coastguard Worker     0x00800000, // minimum positive normalized value
63*35238bceSAndroid Build Coastguard Worker     0x80800000, // maximum negative normalized value
64*35238bceSAndroid Build Coastguard Worker     0x00000001, // minimum positive denorm value
65*35238bceSAndroid Build Coastguard Worker     0x80000001, // maximum negative denorm value
66*35238bceSAndroid Build Coastguard Worker     0x7F7FFFFF, // maximum finite value.
67*35238bceSAndroid Build Coastguard Worker     0xFF7FFFFF, // minimum finite value.
68*35238bceSAndroid Build Coastguard Worker     0x7F800000, //  inf
69*35238bceSAndroid Build Coastguard Worker     0xFF800000, // -inf
70*35238bceSAndroid Build Coastguard Worker     0x34000000, //          epsilon
71*35238bceSAndroid Build Coastguard Worker     0xB4000000, // negative epsilon
72*35238bceSAndroid Build Coastguard Worker     0x7FC00000, //          quiet_NaN
73*35238bceSAndroid Build Coastguard Worker     0xFFC00000, // negative quiet_NaN
74*35238bceSAndroid Build Coastguard Worker     0x7FC00001, //          signaling_NaN
75*35238bceSAndroid Build Coastguard Worker     0xFFC00001, // negative signaling_NaN
76*35238bceSAndroid Build Coastguard Worker     0x7FEAAAAA, //          quiet payloaded NaN        (payload of repeated pattern of 101010...)
77*35238bceSAndroid Build Coastguard Worker     0xFFEAAAAA, // negative quiet payloaded NaN        ( .. )
78*35238bceSAndroid Build Coastguard Worker     0x7FAAAAAA, //          signaling payloaded NaN    ( .. )
79*35238bceSAndroid Build Coastguard Worker     0xFFAAAAAA, // negative signaling payloaded NaN    ( .. )
80*35238bceSAndroid Build Coastguard Worker };
81*35238bceSAndroid Build Coastguard Worker 
82*35238bceSAndroid Build Coastguard Worker static const char *const s_colorPassthroughFragmentShaderSource = "varying mediump vec4 v_out;\n"
83*35238bceSAndroid Build Coastguard Worker                                                                   "void main ()\n"
84*35238bceSAndroid Build Coastguard Worker                                                                   "{\n"
85*35238bceSAndroid Build Coastguard Worker                                                                   "    gl_FragColor = v_out;\n"
86*35238bceSAndroid Build Coastguard Worker                                                                   "}\n";
87*35238bceSAndroid Build Coastguard Worker static const char *const s_attrPassthroughVertexShaderSource    = "attribute highp vec4 a_pos;\n"
88*35238bceSAndroid Build Coastguard Worker                                                                   "attribute highp vec4 a_attr;\n"
89*35238bceSAndroid Build Coastguard Worker                                                                   "varying mediump vec4 v_attr;\n"
90*35238bceSAndroid Build Coastguard Worker                                                                   "void main ()\n"
91*35238bceSAndroid Build Coastguard Worker                                                                   "{\n"
92*35238bceSAndroid Build Coastguard Worker                                                                   "    v_attr = a_attr;\n"
93*35238bceSAndroid Build Coastguard Worker                                                                   "    gl_Position = a_pos;\n"
94*35238bceSAndroid Build Coastguard Worker                                                                   "}\n";
95*35238bceSAndroid Build Coastguard Worker 
96*35238bceSAndroid Build Coastguard Worker class RenderCase : public TestCase
97*35238bceSAndroid Build Coastguard Worker {
98*35238bceSAndroid Build Coastguard Worker public:
99*35238bceSAndroid Build Coastguard Worker     enum RenderTargetType
100*35238bceSAndroid Build Coastguard Worker     {
101*35238bceSAndroid Build Coastguard Worker         RENDERTARGETTYPE_SCREEN,
102*35238bceSAndroid Build Coastguard Worker         RENDERTARGETTYPE_FBO
103*35238bceSAndroid Build Coastguard Worker     };
104*35238bceSAndroid Build Coastguard Worker 
105*35238bceSAndroid Build Coastguard Worker     RenderCase(Context &context, const char *name, const char *desc,
106*35238bceSAndroid Build Coastguard Worker                RenderTargetType renderTargetType = RENDERTARGETTYPE_SCREEN);
107*35238bceSAndroid Build Coastguard Worker     virtual ~RenderCase(void);
108*35238bceSAndroid Build Coastguard Worker 
109*35238bceSAndroid Build Coastguard Worker     virtual void init(void);
110*35238bceSAndroid Build Coastguard Worker     virtual void deinit(void);
111*35238bceSAndroid Build Coastguard Worker 
112*35238bceSAndroid Build Coastguard Worker protected:
113*35238bceSAndroid Build Coastguard Worker     bool checkResultImage(const tcu::Surface &result);
114*35238bceSAndroid Build Coastguard Worker     bool drawTestPattern(bool useTexture);
115*35238bceSAndroid Build Coastguard Worker 
116*35238bceSAndroid Build Coastguard Worker     virtual std::string genVertexSource(void) const   = 0;
117*35238bceSAndroid Build Coastguard Worker     virtual std::string genFragmentSource(void) const = 0;
118*35238bceSAndroid Build Coastguard Worker 
119*35238bceSAndroid Build Coastguard Worker     const glu::ShaderProgram *m_program;
120*35238bceSAndroid Build Coastguard Worker     const RenderTargetType m_renderTargetType;
121*35238bceSAndroid Build Coastguard Worker };
122*35238bceSAndroid Build Coastguard Worker 
RenderCase(Context & context,const char * name,const char * desc,RenderTargetType renderTargetType)123*35238bceSAndroid Build Coastguard Worker RenderCase::RenderCase(Context &context, const char *name, const char *desc, RenderTargetType renderTargetType)
124*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, desc)
125*35238bceSAndroid Build Coastguard Worker     , m_program(DE_NULL)
126*35238bceSAndroid Build Coastguard Worker     , m_renderTargetType(renderTargetType)
127*35238bceSAndroid Build Coastguard Worker {
128*35238bceSAndroid Build Coastguard Worker }
129*35238bceSAndroid Build Coastguard Worker 
~RenderCase(void)130*35238bceSAndroid Build Coastguard Worker RenderCase::~RenderCase(void)
131*35238bceSAndroid Build Coastguard Worker {
132*35238bceSAndroid Build Coastguard Worker     deinit();
133*35238bceSAndroid Build Coastguard Worker }
134*35238bceSAndroid Build Coastguard Worker 
init(void)135*35238bceSAndroid Build Coastguard Worker void RenderCase::init(void)
136*35238bceSAndroid Build Coastguard Worker {
137*35238bceSAndroid Build Coastguard Worker     const int width  = m_context.getRenderTarget().getWidth();
138*35238bceSAndroid Build Coastguard Worker     const int height = m_context.getRenderTarget().getHeight();
139*35238bceSAndroid Build Coastguard Worker 
140*35238bceSAndroid Build Coastguard Worker     // check target size
141*35238bceSAndroid Build Coastguard Worker     if (m_renderTargetType == RENDERTARGETTYPE_SCREEN)
142*35238bceSAndroid Build Coastguard Worker     {
143*35238bceSAndroid Build Coastguard Worker         if (width < TEST_CANVAS_SIZE || height < TEST_CANVAS_SIZE)
144*35238bceSAndroid Build Coastguard Worker             throw tcu::NotSupportedError(std::string("Render target size must be at least ") +
145*35238bceSAndroid Build Coastguard Worker                                          de::toString(TEST_CANVAS_SIZE) + "x" + de::toString(TEST_CANVAS_SIZE));
146*35238bceSAndroid Build Coastguard Worker     }
147*35238bceSAndroid Build Coastguard Worker     else if (m_renderTargetType == RENDERTARGETTYPE_FBO)
148*35238bceSAndroid Build Coastguard Worker     {
149*35238bceSAndroid Build Coastguard Worker         GLint maxTexSize = 0;
150*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext().getFunctions().getIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize);
151*35238bceSAndroid Build Coastguard Worker 
152*35238bceSAndroid Build Coastguard Worker         if (maxTexSize < TEST_CANVAS_SIZE)
153*35238bceSAndroid Build Coastguard Worker             throw tcu::NotSupportedError(std::string("GL_MAX_TEXTURE_SIZE must be at least ") +
154*35238bceSAndroid Build Coastguard Worker                                          de::toString(TEST_CANVAS_SIZE));
155*35238bceSAndroid Build Coastguard Worker     }
156*35238bceSAndroid Build Coastguard Worker     else
157*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
158*35238bceSAndroid Build Coastguard Worker 
159*35238bceSAndroid Build Coastguard Worker     // gen shader
160*35238bceSAndroid Build Coastguard Worker 
161*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << "Creating test shader." << tcu::TestLog::EndMessage;
162*35238bceSAndroid Build Coastguard Worker 
163*35238bceSAndroid Build Coastguard Worker     m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
164*35238bceSAndroid Build Coastguard Worker                                                                          << glu::VertexSource(genVertexSource())
165*35238bceSAndroid Build Coastguard Worker                                                                          << glu::FragmentSource(genFragmentSource()));
166*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << *m_program;
167*35238bceSAndroid Build Coastguard Worker 
168*35238bceSAndroid Build Coastguard Worker     if (!m_program->isOk())
169*35238bceSAndroid Build Coastguard Worker         throw tcu::TestError("shader compile failed");
170*35238bceSAndroid Build Coastguard Worker }
171*35238bceSAndroid Build Coastguard Worker 
deinit(void)172*35238bceSAndroid Build Coastguard Worker void RenderCase::deinit(void)
173*35238bceSAndroid Build Coastguard Worker {
174*35238bceSAndroid Build Coastguard Worker     if (m_program)
175*35238bceSAndroid Build Coastguard Worker     {
176*35238bceSAndroid Build Coastguard Worker         delete m_program;
177*35238bceSAndroid Build Coastguard Worker         m_program = DE_NULL;
178*35238bceSAndroid Build Coastguard Worker     }
179*35238bceSAndroid Build Coastguard Worker }
180*35238bceSAndroid Build Coastguard Worker 
checkResultImage(const tcu::Surface & result)181*35238bceSAndroid Build Coastguard Worker bool RenderCase::checkResultImage(const tcu::Surface &result)
182*35238bceSAndroid Build Coastguard Worker {
183*35238bceSAndroid Build Coastguard Worker     tcu::Surface errorMask(TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
184*35238bceSAndroid Build Coastguard Worker     bool error = false;
185*35238bceSAndroid Build Coastguard Worker 
186*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << "Verifying output image." << tcu::TestLog::EndMessage;
187*35238bceSAndroid Build Coastguard Worker 
188*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < TEST_CANVAS_SIZE; ++y)
189*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < TEST_CANVAS_SIZE; ++x)
190*35238bceSAndroid Build Coastguard Worker         {
191*35238bceSAndroid Build Coastguard Worker             const tcu::RGBA col = result.getPixel(x, y);
192*35238bceSAndroid Build Coastguard Worker 
193*35238bceSAndroid Build Coastguard Worker             if (col.getGreen() == 255)
194*35238bceSAndroid Build Coastguard Worker                 errorMask.setPixel(x, y, tcu::RGBA::green());
195*35238bceSAndroid Build Coastguard Worker             else
196*35238bceSAndroid Build Coastguard Worker             {
197*35238bceSAndroid Build Coastguard Worker                 errorMask.setPixel(x, y, tcu::RGBA::red());
198*35238bceSAndroid Build Coastguard Worker                 error = true;
199*35238bceSAndroid Build Coastguard Worker             }
200*35238bceSAndroid Build Coastguard Worker         }
201*35238bceSAndroid Build Coastguard Worker 
202*35238bceSAndroid Build Coastguard Worker     if (error)
203*35238bceSAndroid Build Coastguard Worker     {
204*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Result image has missing or invalid pixels"
205*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
206*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::ImageSet("Results", "Result verification")
207*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::Image("Result", "Result", result)
208*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::Image("Error mask", "Error mask", errorMask) << tcu::TestLog::EndImageSet;
209*35238bceSAndroid Build Coastguard Worker     }
210*35238bceSAndroid Build Coastguard Worker     else
211*35238bceSAndroid Build Coastguard Worker     {
212*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::ImageSet("Results", "Result verification")
213*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::Image("Result", "Result", result) << tcu::TestLog::EndImageSet;
214*35238bceSAndroid Build Coastguard Worker     }
215*35238bceSAndroid Build Coastguard Worker 
216*35238bceSAndroid Build Coastguard Worker     return !error;
217*35238bceSAndroid Build Coastguard Worker }
218*35238bceSAndroid Build Coastguard Worker 
drawTestPattern(bool useTexture)219*35238bceSAndroid Build Coastguard Worker bool RenderCase::drawTestPattern(bool useTexture)
220*35238bceSAndroid Build Coastguard Worker {
221*35238bceSAndroid Build Coastguard Worker     static const tcu::Vec4 fullscreenQuad[4] = {
222*35238bceSAndroid Build Coastguard Worker         tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
223*35238bceSAndroid Build Coastguard Worker         tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f),
224*35238bceSAndroid Build Coastguard Worker         tcu::Vec4(1.0f, -1.0f, 0.0f, 1.0f),
225*35238bceSAndroid Build Coastguard Worker         tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),
226*35238bceSAndroid Build Coastguard Worker     };
227*35238bceSAndroid Build Coastguard Worker     const char *const vertexSource        = "attribute highp vec4 a_pos;\n"
228*35238bceSAndroid Build Coastguard Worker                                             "varying mediump vec4 v_position;\n"
229*35238bceSAndroid Build Coastguard Worker                                             "void main ()\n"
230*35238bceSAndroid Build Coastguard Worker                                             "{\n"
231*35238bceSAndroid Build Coastguard Worker                                             "    v_position = a_pos;\n"
232*35238bceSAndroid Build Coastguard Worker                                             "    gl_Position = a_pos;\n"
233*35238bceSAndroid Build Coastguard Worker                                             "}\n";
234*35238bceSAndroid Build Coastguard Worker     const char *const fragmentSourceNoTex = "varying mediump vec4 v_position;\n"
235*35238bceSAndroid Build Coastguard Worker                                             "void main ()\n"
236*35238bceSAndroid Build Coastguard Worker                                             "{\n"
237*35238bceSAndroid Build Coastguard Worker                                             "    gl_FragColor = vec4((v_position.x + 1.0) * 0.5, 1.0, 1.0, 1.0);\n"
238*35238bceSAndroid Build Coastguard Worker                                             "}\n";
239*35238bceSAndroid Build Coastguard Worker     const char *const fragmentSourceTex   = "uniform mediump sampler2D u_sampler;\n"
240*35238bceSAndroid Build Coastguard Worker                                             "varying mediump vec4 v_position;\n"
241*35238bceSAndroid Build Coastguard Worker                                             "void main ()\n"
242*35238bceSAndroid Build Coastguard Worker                                             "{\n"
243*35238bceSAndroid Build Coastguard Worker                                             "    gl_FragColor = texture2D(u_sampler, v_position.xy);\n"
244*35238bceSAndroid Build Coastguard Worker                                             "}\n";
245*35238bceSAndroid Build Coastguard Worker     const char *const fragmentSource      = (useTexture) ? (fragmentSourceTex) : (fragmentSourceNoTex);
246*35238bceSAndroid Build Coastguard Worker     const tcu::RGBA formatThreshold       = m_context.getRenderTarget().getPixelFormat().getColorThreshold();
247*35238bceSAndroid Build Coastguard Worker 
248*35238bceSAndroid Build Coastguard Worker     tcu::Surface resultImage(TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
249*35238bceSAndroid Build Coastguard Worker     tcu::Surface errorMask(TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
250*35238bceSAndroid Build Coastguard Worker     bool error = false;
251*35238bceSAndroid Build Coastguard Worker 
252*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << "Drawing a test pattern to detect "
253*35238bceSAndroid Build Coastguard Worker                        << ((useTexture) ? ("texture sampling") : ("")) << " side-effects." << tcu::TestLog::EndMessage;
254*35238bceSAndroid Build Coastguard Worker 
255*35238bceSAndroid Build Coastguard Worker     // draw pattern
256*35238bceSAndroid Build Coastguard Worker     {
257*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
258*35238bceSAndroid Build Coastguard Worker         const glu::ShaderProgram patternProgram(m_context.getRenderContext(),
259*35238bceSAndroid Build Coastguard Worker                                                 glu::ProgramSources() << glu::VertexSource(vertexSource)
260*35238bceSAndroid Build Coastguard Worker                                                                       << glu::FragmentSource(fragmentSource));
261*35238bceSAndroid Build Coastguard Worker         const GLint positionLoc = gl.getAttribLocation(patternProgram.getProgram(), "a_pos");
262*35238bceSAndroid Build Coastguard Worker         GLuint textureID        = 0;
263*35238bceSAndroid Build Coastguard Worker 
264*35238bceSAndroid Build Coastguard Worker         if (useTexture)
265*35238bceSAndroid Build Coastguard Worker         {
266*35238bceSAndroid Build Coastguard Worker             const int textureSize = 32;
267*35238bceSAndroid Build Coastguard Worker             std::vector<tcu::Vector<uint8_t, 4>> buffer(textureSize * textureSize);
268*35238bceSAndroid Build Coastguard Worker 
269*35238bceSAndroid Build Coastguard Worker             for (int x = 0; x < textureSize; ++x)
270*35238bceSAndroid Build Coastguard Worker                 for (int y = 0; y < textureSize; ++y)
271*35238bceSAndroid Build Coastguard Worker                 {
272*35238bceSAndroid Build Coastguard Worker                     // sum of two axis aligned gradients. Each gradient is 127 at the edges and 0 at the center.
273*35238bceSAndroid Build Coastguard Worker                     // pattern is symmetric (x and y) => no discontinuity near boundary => no need to worry of results with LINEAR filtering near boundaries
274*35238bceSAndroid Build Coastguard Worker                     const uint8_t redComponent =
275*35238bceSAndroid Build Coastguard Worker                         (uint8_t)de::clamp(de::abs((float)x / (float)textureSize - 0.5f) * 255.0f +
276*35238bceSAndroid Build Coastguard Worker                                                de::abs((float)y / (float)textureSize - 0.5f) * 255.0f,
277*35238bceSAndroid Build Coastguard Worker                                            0.0f, 255.0f);
278*35238bceSAndroid Build Coastguard Worker 
279*35238bceSAndroid Build Coastguard Worker                     buffer[x * textureSize + y] = tcu::Vector<uint8_t, 4>(redComponent, 255, 255, 255);
280*35238bceSAndroid Build Coastguard Worker                 }
281*35238bceSAndroid Build Coastguard Worker 
282*35238bceSAndroid Build Coastguard Worker             gl.genTextures(1, &textureID);
283*35238bceSAndroid Build Coastguard Worker             gl.bindTexture(GL_TEXTURE_2D, textureID);
284*35238bceSAndroid Build Coastguard Worker             gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textureSize, textureSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
285*35238bceSAndroid Build Coastguard Worker                           buffer[0].getPtr());
286*35238bceSAndroid Build Coastguard Worker             gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
287*35238bceSAndroid Build Coastguard Worker             gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
288*35238bceSAndroid Build Coastguard Worker         }
289*35238bceSAndroid Build Coastguard Worker 
290*35238bceSAndroid Build Coastguard Worker         gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
291*35238bceSAndroid Build Coastguard Worker         gl.clear(GL_COLOR_BUFFER_BIT);
292*35238bceSAndroid Build Coastguard Worker         gl.viewport(0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
293*35238bceSAndroid Build Coastguard Worker         gl.useProgram(patternProgram.getProgram());
294*35238bceSAndroid Build Coastguard Worker 
295*35238bceSAndroid Build Coastguard Worker         if (useTexture)
296*35238bceSAndroid Build Coastguard Worker             gl.uniform1i(gl.getUniformLocation(patternProgram.getProgram(), "u_sampler"), 0);
297*35238bceSAndroid Build Coastguard Worker 
298*35238bceSAndroid Build Coastguard Worker         gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, &fullscreenQuad[0]);
299*35238bceSAndroid Build Coastguard Worker 
300*35238bceSAndroid Build Coastguard Worker         gl.enableVertexAttribArray(positionLoc);
301*35238bceSAndroid Build Coastguard Worker         gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
302*35238bceSAndroid Build Coastguard Worker         gl.disableVertexAttribArray(positionLoc);
303*35238bceSAndroid Build Coastguard Worker 
304*35238bceSAndroid Build Coastguard Worker         gl.useProgram(0);
305*35238bceSAndroid Build Coastguard Worker         gl.finish();
306*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "RenderCase::drawTestPattern");
307*35238bceSAndroid Build Coastguard Worker 
308*35238bceSAndroid Build Coastguard Worker         if (textureID)
309*35238bceSAndroid Build Coastguard Worker             gl.deleteTextures(1, &textureID);
310*35238bceSAndroid Build Coastguard Worker 
311*35238bceSAndroid Build Coastguard Worker         glu::readPixels(m_context.getRenderContext(), 0, 0, resultImage.getAccess());
312*35238bceSAndroid Build Coastguard Worker     }
313*35238bceSAndroid Build Coastguard Worker 
314*35238bceSAndroid Build Coastguard Worker     // verify pattern
315*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < TEST_CANVAS_SIZE; ++y)
316*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < TEST_CANVAS_SIZE; ++x)
317*35238bceSAndroid Build Coastguard Worker         {
318*35238bceSAndroid Build Coastguard Worker             const float texGradientPosX   = deFloatFrac((float)x * 2.0f / (float)TEST_CANVAS_SIZE);
319*35238bceSAndroid Build Coastguard Worker             const float texGradientPosY   = deFloatFrac((float)y * 2.0f / (float)TEST_CANVAS_SIZE);
320*35238bceSAndroid Build Coastguard Worker             const uint8_t texRedComponent = (uint8_t)de::clamp(
321*35238bceSAndroid Build Coastguard Worker                 de::abs(texGradientPosX - 0.5f) * 255.0f + de::abs(texGradientPosY - 0.5f) * 255.0f, 0.0f, 255.0f);
322*35238bceSAndroid Build Coastguard Worker 
323*35238bceSAndroid Build Coastguard Worker             const tcu::RGBA refColTexture = tcu::RGBA(texRedComponent, 255, 255, 255);
324*35238bceSAndroid Build Coastguard Worker             const tcu::RGBA refColGradient =
325*35238bceSAndroid Build Coastguard Worker                 tcu::RGBA((int)((float)x / (float)TEST_CANVAS_SIZE * 255.0f), 255, 255, 255);
326*35238bceSAndroid Build Coastguard Worker             const tcu::RGBA &refCol = (useTexture) ? (refColTexture) : (refColGradient);
327*35238bceSAndroid Build Coastguard Worker 
328*35238bceSAndroid Build Coastguard Worker             const int colorThreshold   = 10;
329*35238bceSAndroid Build Coastguard Worker             const tcu::RGBA col        = resultImage.getPixel(x, y);
330*35238bceSAndroid Build Coastguard Worker             const tcu::IVec4 colorDiff = tcu::abs(col.toIVec() - refCol.toIVec());
331*35238bceSAndroid Build Coastguard Worker 
332*35238bceSAndroid Build Coastguard Worker             if (colorDiff.x() > formatThreshold.getRed() + colorThreshold ||
333*35238bceSAndroid Build Coastguard Worker                 colorDiff.y() > formatThreshold.getGreen() + colorThreshold ||
334*35238bceSAndroid Build Coastguard Worker                 colorDiff.z() > formatThreshold.getBlue() + colorThreshold)
335*35238bceSAndroid Build Coastguard Worker             {
336*35238bceSAndroid Build Coastguard Worker                 errorMask.setPixel(x, y, tcu::RGBA::red());
337*35238bceSAndroid Build Coastguard Worker                 error = true;
338*35238bceSAndroid Build Coastguard Worker             }
339*35238bceSAndroid Build Coastguard Worker             else
340*35238bceSAndroid Build Coastguard Worker                 errorMask.setPixel(x, y, tcu::RGBA::green());
341*35238bceSAndroid Build Coastguard Worker         }
342*35238bceSAndroid Build Coastguard Worker 
343*35238bceSAndroid Build Coastguard Worker     // report error
344*35238bceSAndroid Build Coastguard Worker     if (error)
345*35238bceSAndroid Build Coastguard Worker     {
346*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Test pattern has missing/invalid pixels"
347*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
348*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::ImageSet("Results", "Result verification")
349*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::Image("Result", "Result", resultImage)
350*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::Image("Error mask", "Error mask", errorMask) << tcu::TestLog::EndImageSet;
351*35238bceSAndroid Build Coastguard Worker     }
352*35238bceSAndroid Build Coastguard Worker     else
353*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "No side-effects found." << tcu::TestLog::EndMessage;
354*35238bceSAndroid Build Coastguard Worker 
355*35238bceSAndroid Build Coastguard Worker     return !error;
356*35238bceSAndroid Build Coastguard Worker }
357*35238bceSAndroid Build Coastguard Worker 
358*35238bceSAndroid Build Coastguard Worker class FramebufferRenderCase : public RenderCase
359*35238bceSAndroid Build Coastguard Worker {
360*35238bceSAndroid Build Coastguard Worker public:
361*35238bceSAndroid Build Coastguard Worker     enum FrameBufferType
362*35238bceSAndroid Build Coastguard Worker     {
363*35238bceSAndroid Build Coastguard Worker         FBO_DEFAULT = 0,
364*35238bceSAndroid Build Coastguard Worker         FBO_RGBA,
365*35238bceSAndroid Build Coastguard Worker         FBO_RGBA4,
366*35238bceSAndroid Build Coastguard Worker         FBO_RGB5_A1,
367*35238bceSAndroid Build Coastguard Worker         FBO_RGB565,
368*35238bceSAndroid Build Coastguard Worker         FBO_RGBA_FLOAT16,
369*35238bceSAndroid Build Coastguard Worker 
370*35238bceSAndroid Build Coastguard Worker         FBO_LAST
371*35238bceSAndroid Build Coastguard Worker     };
372*35238bceSAndroid Build Coastguard Worker 
373*35238bceSAndroid Build Coastguard Worker     FramebufferRenderCase(Context &context, const char *name, const char *desc, FrameBufferType fboType);
374*35238bceSAndroid Build Coastguard Worker     virtual ~FramebufferRenderCase(void);
375*35238bceSAndroid Build Coastguard Worker 
376*35238bceSAndroid Build Coastguard Worker     virtual void init(void);
377*35238bceSAndroid Build Coastguard Worker     virtual void deinit(void);
378*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
379*35238bceSAndroid Build Coastguard Worker 
380*35238bceSAndroid Build Coastguard Worker     virtual void testFBO(void) = DE_NULL;
381*35238bceSAndroid Build Coastguard Worker 
382*35238bceSAndroid Build Coastguard Worker protected:
383*35238bceSAndroid Build Coastguard Worker     const FrameBufferType m_fboType;
384*35238bceSAndroid Build Coastguard Worker 
385*35238bceSAndroid Build Coastguard Worker private:
386*35238bceSAndroid Build Coastguard Worker     GLuint m_texID;
387*35238bceSAndroid Build Coastguard Worker     GLuint m_fboID;
388*35238bceSAndroid Build Coastguard Worker };
389*35238bceSAndroid Build Coastguard Worker 
FramebufferRenderCase(Context & context,const char * name,const char * desc,FrameBufferType fboType)390*35238bceSAndroid Build Coastguard Worker FramebufferRenderCase::FramebufferRenderCase(Context &context, const char *name, const char *desc,
391*35238bceSAndroid Build Coastguard Worker                                              FrameBufferType fboType)
392*35238bceSAndroid Build Coastguard Worker     : RenderCase(context, name, desc, (fboType == FBO_DEFAULT) ? (RENDERTARGETTYPE_SCREEN) : (RENDERTARGETTYPE_FBO))
393*35238bceSAndroid Build Coastguard Worker     , m_fboType(fboType)
394*35238bceSAndroid Build Coastguard Worker     , m_texID(0)
395*35238bceSAndroid Build Coastguard Worker     , m_fboID(0)
396*35238bceSAndroid Build Coastguard Worker {
397*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_fboType < FBO_LAST);
398*35238bceSAndroid Build Coastguard Worker }
399*35238bceSAndroid Build Coastguard Worker 
~FramebufferRenderCase(void)400*35238bceSAndroid Build Coastguard Worker FramebufferRenderCase::~FramebufferRenderCase(void)
401*35238bceSAndroid Build Coastguard Worker {
402*35238bceSAndroid Build Coastguard Worker     deinit();
403*35238bceSAndroid Build Coastguard Worker }
404*35238bceSAndroid Build Coastguard Worker 
init(void)405*35238bceSAndroid Build Coastguard Worker void FramebufferRenderCase::init(void)
406*35238bceSAndroid Build Coastguard Worker {
407*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
408*35238bceSAndroid Build Coastguard Worker 
409*35238bceSAndroid Build Coastguard Worker     // check requirements
410*35238bceSAndroid Build Coastguard Worker     if (m_fboType == FBO_RGBA_FLOAT16)
411*35238bceSAndroid Build Coastguard Worker     {
412*35238bceSAndroid Build Coastguard Worker         // half float texture is allowed (OES_texture_half_float) and it is color renderable (EXT_color_buffer_half_float)
413*35238bceSAndroid Build Coastguard Worker         if (!m_context.getContextInfo().isExtensionSupported("GL_OES_texture_half_float") ||
414*35238bceSAndroid Build Coastguard Worker             !m_context.getContextInfo().isExtensionSupported("GL_EXT_color_buffer_half_float"))
415*35238bceSAndroid Build Coastguard Worker             throw tcu::NotSupportedError("Color renderable half float texture required.");
416*35238bceSAndroid Build Coastguard Worker     }
417*35238bceSAndroid Build Coastguard Worker 
418*35238bceSAndroid Build Coastguard Worker     // gen shader
419*35238bceSAndroid Build Coastguard Worker     RenderCase::init();
420*35238bceSAndroid Build Coastguard Worker 
421*35238bceSAndroid Build Coastguard Worker     // create render target
422*35238bceSAndroid Build Coastguard Worker     if (m_fboType == FBO_DEFAULT)
423*35238bceSAndroid Build Coastguard Worker     {
424*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Using default framebuffer." << tcu::TestLog::EndMessage;
425*35238bceSAndroid Build Coastguard Worker     }
426*35238bceSAndroid Build Coastguard Worker     else
427*35238bceSAndroid Build Coastguard Worker     {
428*35238bceSAndroid Build Coastguard Worker         GLuint internalFormat = 0;
429*35238bceSAndroid Build Coastguard Worker         GLuint format         = 0;
430*35238bceSAndroid Build Coastguard Worker         GLuint type           = 0;
431*35238bceSAndroid Build Coastguard Worker 
432*35238bceSAndroid Build Coastguard Worker #if !defined(GL_HALF_FLOAT_OES)
433*35238bceSAndroid Build Coastguard Worker #define GL_HALF_FLOAT_OES 0x8D61
434*35238bceSAndroid Build Coastguard Worker #endif
435*35238bceSAndroid Build Coastguard Worker 
436*35238bceSAndroid Build Coastguard Worker         switch (m_fboType)
437*35238bceSAndroid Build Coastguard Worker         {
438*35238bceSAndroid Build Coastguard Worker         case FBO_RGBA:
439*35238bceSAndroid Build Coastguard Worker             internalFormat = GL_RGBA;
440*35238bceSAndroid Build Coastguard Worker             format         = GL_RGBA;
441*35238bceSAndroid Build Coastguard Worker             type           = GL_UNSIGNED_BYTE;
442*35238bceSAndroid Build Coastguard Worker             break;
443*35238bceSAndroid Build Coastguard Worker         case FBO_RGBA4:
444*35238bceSAndroid Build Coastguard Worker             internalFormat = GL_RGBA;
445*35238bceSAndroid Build Coastguard Worker             format         = GL_RGBA;
446*35238bceSAndroid Build Coastguard Worker             type           = GL_UNSIGNED_SHORT_4_4_4_4;
447*35238bceSAndroid Build Coastguard Worker             break;
448*35238bceSAndroid Build Coastguard Worker         case FBO_RGB5_A1:
449*35238bceSAndroid Build Coastguard Worker             internalFormat = GL_RGBA;
450*35238bceSAndroid Build Coastguard Worker             format         = GL_RGBA;
451*35238bceSAndroid Build Coastguard Worker             type           = GL_UNSIGNED_SHORT_5_5_5_1;
452*35238bceSAndroid Build Coastguard Worker             break;
453*35238bceSAndroid Build Coastguard Worker         case FBO_RGB565:
454*35238bceSAndroid Build Coastguard Worker             internalFormat = GL_RGB;
455*35238bceSAndroid Build Coastguard Worker             format         = GL_RGB;
456*35238bceSAndroid Build Coastguard Worker             type           = GL_UNSIGNED_SHORT_5_6_5;
457*35238bceSAndroid Build Coastguard Worker             break;
458*35238bceSAndroid Build Coastguard Worker         case FBO_RGBA_FLOAT16:
459*35238bceSAndroid Build Coastguard Worker             internalFormat = GL_RGBA;
460*35238bceSAndroid Build Coastguard Worker             format         = GL_RGBA;
461*35238bceSAndroid Build Coastguard Worker             type           = GL_HALF_FLOAT_OES;
462*35238bceSAndroid Build Coastguard Worker             break;
463*35238bceSAndroid Build Coastguard Worker 
464*35238bceSAndroid Build Coastguard Worker         default:
465*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
466*35238bceSAndroid Build Coastguard Worker             break;
467*35238bceSAndroid Build Coastguard Worker         }
468*35238bceSAndroid Build Coastguard Worker 
469*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message
470*35238bceSAndroid Build Coastguard Worker                            << "Creating fbo. Texture internalFormat = " << glu::getTextureFormatStr(internalFormat)
471*35238bceSAndroid Build Coastguard Worker                            << ", format = " << glu::getTextureFormatStr(format) << ", type = " << glu::getTypeStr(type)
472*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
473*35238bceSAndroid Build Coastguard Worker 
474*35238bceSAndroid Build Coastguard Worker         // gen texture
475*35238bceSAndroid Build Coastguard Worker         gl.genTextures(1, &m_texID);
476*35238bceSAndroid Build Coastguard Worker         gl.bindTexture(GL_TEXTURE_2D, m_texID);
477*35238bceSAndroid Build Coastguard Worker         gl.texImage2D(GL_TEXTURE_2D, 0, internalFormat, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE, 0, format, type, DE_NULL);
478*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "texture init");
479*35238bceSAndroid Build Coastguard Worker 
480*35238bceSAndroid Build Coastguard Worker         // gen fbo
481*35238bceSAndroid Build Coastguard Worker         gl.genFramebuffers(1, &m_fboID);
482*35238bceSAndroid Build Coastguard Worker         gl.bindFramebuffer(GL_FRAMEBUFFER, m_fboID);
483*35238bceSAndroid Build Coastguard Worker         gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texID, 0);
484*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "fbo init");
485*35238bceSAndroid Build Coastguard Worker 
486*35238bceSAndroid Build Coastguard Worker         if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
487*35238bceSAndroid Build Coastguard Worker             throw tcu::NotSupportedError("could not create fbo for testing.");
488*35238bceSAndroid Build Coastguard Worker     }
489*35238bceSAndroid Build Coastguard Worker }
490*35238bceSAndroid Build Coastguard Worker 
deinit(void)491*35238bceSAndroid Build Coastguard Worker void FramebufferRenderCase::deinit(void)
492*35238bceSAndroid Build Coastguard Worker {
493*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
494*35238bceSAndroid Build Coastguard Worker 
495*35238bceSAndroid Build Coastguard Worker     if (m_texID)
496*35238bceSAndroid Build Coastguard Worker     {
497*35238bceSAndroid Build Coastguard Worker         gl.deleteTextures(1, &m_texID);
498*35238bceSAndroid Build Coastguard Worker         m_texID = 0;
499*35238bceSAndroid Build Coastguard Worker     }
500*35238bceSAndroid Build Coastguard Worker 
501*35238bceSAndroid Build Coastguard Worker     if (m_fboID)
502*35238bceSAndroid Build Coastguard Worker     {
503*35238bceSAndroid Build Coastguard Worker         gl.deleteFramebuffers(1, &m_fboID);
504*35238bceSAndroid Build Coastguard Worker         m_fboID = 0;
505*35238bceSAndroid Build Coastguard Worker     }
506*35238bceSAndroid Build Coastguard Worker }
507*35238bceSAndroid Build Coastguard Worker 
iterate(void)508*35238bceSAndroid Build Coastguard Worker FramebufferRenderCase::IterateResult FramebufferRenderCase::iterate(void)
509*35238bceSAndroid Build Coastguard Worker {
510*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
511*35238bceSAndroid Build Coastguard Worker 
512*35238bceSAndroid Build Coastguard Worker     // bind fbo (or don't if we are using default)
513*35238bceSAndroid Build Coastguard Worker     if (m_fboID)
514*35238bceSAndroid Build Coastguard Worker         gl.bindFramebuffer(GL_FRAMEBUFFER, m_fboID);
515*35238bceSAndroid Build Coastguard Worker 
516*35238bceSAndroid Build Coastguard Worker     // do something with special floats
517*35238bceSAndroid Build Coastguard Worker     testFBO();
518*35238bceSAndroid Build Coastguard Worker 
519*35238bceSAndroid Build Coastguard Worker     return STOP;
520*35238bceSAndroid Build Coastguard Worker }
521*35238bceSAndroid Build Coastguard Worker 
522*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
523*35238bceSAndroid Build Coastguard Worker  * \brief Tests special floats as vertex attributes
524*35238bceSAndroid Build Coastguard Worker  *
525*35238bceSAndroid Build Coastguard Worker  * Tests that special floats transferred to the shader using vertex
526*35238bceSAndroid Build Coastguard Worker  * attributes do not change the results of normal floating point
527*35238bceSAndroid Build Coastguard Worker  * calculations. Special floats are put to 4-vector's x and y components and
528*35238bceSAndroid Build Coastguard Worker  * value 1.0 is put to z and w. The resulting fragment's green channel
529*35238bceSAndroid Build Coastguard Worker  * should be 1.0 everywhere.
530*35238bceSAndroid Build Coastguard Worker  *
531*35238bceSAndroid Build Coastguard Worker  * After the calculation test a test pattern is drawn to detect possible
532*35238bceSAndroid Build Coastguard Worker  * floating point operation anomalies.
533*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
534*35238bceSAndroid Build Coastguard Worker class VertexAttributeCase : public RenderCase
535*35238bceSAndroid Build Coastguard Worker {
536*35238bceSAndroid Build Coastguard Worker public:
537*35238bceSAndroid Build Coastguard Worker     enum Storage
538*35238bceSAndroid Build Coastguard Worker     {
539*35238bceSAndroid Build Coastguard Worker         STORAGE_BUFFER = 0,
540*35238bceSAndroid Build Coastguard Worker         STORAGE_CLIENT,
541*35238bceSAndroid Build Coastguard Worker 
542*35238bceSAndroid Build Coastguard Worker         STORAGE_LAST
543*35238bceSAndroid Build Coastguard Worker     };
544*35238bceSAndroid Build Coastguard Worker     enum ShaderType
545*35238bceSAndroid Build Coastguard Worker     {
546*35238bceSAndroid Build Coastguard Worker         TYPE_VERTEX = 0,
547*35238bceSAndroid Build Coastguard Worker         TYPE_FRAGMENT,
548*35238bceSAndroid Build Coastguard Worker 
549*35238bceSAndroid Build Coastguard Worker         TYPE_LAST
550*35238bceSAndroid Build Coastguard Worker     };
551*35238bceSAndroid Build Coastguard Worker 
552*35238bceSAndroid Build Coastguard Worker     VertexAttributeCase(Context &context, const char *name, const char *desc, Storage storage, ShaderType type);
553*35238bceSAndroid Build Coastguard Worker     ~VertexAttributeCase(void);
554*35238bceSAndroid Build Coastguard Worker 
555*35238bceSAndroid Build Coastguard Worker     void init(void);
556*35238bceSAndroid Build Coastguard Worker     void deinit(void);
557*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
558*35238bceSAndroid Build Coastguard Worker 
559*35238bceSAndroid Build Coastguard Worker private:
560*35238bceSAndroid Build Coastguard Worker     std::string genVertexSource(void) const;
561*35238bceSAndroid Build Coastguard Worker     std::string genFragmentSource(void) const;
562*35238bceSAndroid Build Coastguard Worker 
563*35238bceSAndroid Build Coastguard Worker     const Storage m_storage;
564*35238bceSAndroid Build Coastguard Worker     const ShaderType m_type;
565*35238bceSAndroid Build Coastguard Worker     GLuint m_positionVboID;
566*35238bceSAndroid Build Coastguard Worker     GLuint m_attribVboID;
567*35238bceSAndroid Build Coastguard Worker     GLuint m_elementVboID;
568*35238bceSAndroid Build Coastguard Worker };
569*35238bceSAndroid Build Coastguard Worker 
VertexAttributeCase(Context & context,const char * name,const char * desc,Storage storage,ShaderType type)570*35238bceSAndroid Build Coastguard Worker VertexAttributeCase::VertexAttributeCase(Context &context, const char *name, const char *desc, Storage storage,
571*35238bceSAndroid Build Coastguard Worker                                          ShaderType type)
572*35238bceSAndroid Build Coastguard Worker     : RenderCase(context, name, desc)
573*35238bceSAndroid Build Coastguard Worker     , m_storage(storage)
574*35238bceSAndroid Build Coastguard Worker     , m_type(type)
575*35238bceSAndroid Build Coastguard Worker     , m_positionVboID(0)
576*35238bceSAndroid Build Coastguard Worker     , m_attribVboID(0)
577*35238bceSAndroid Build Coastguard Worker     , m_elementVboID(0)
578*35238bceSAndroid Build Coastguard Worker {
579*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(storage < STORAGE_LAST);
580*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(type < TYPE_LAST);
581*35238bceSAndroid Build Coastguard Worker }
582*35238bceSAndroid Build Coastguard Worker 
~VertexAttributeCase(void)583*35238bceSAndroid Build Coastguard Worker VertexAttributeCase::~VertexAttributeCase(void)
584*35238bceSAndroid Build Coastguard Worker {
585*35238bceSAndroid Build Coastguard Worker     deinit();
586*35238bceSAndroid Build Coastguard Worker }
587*35238bceSAndroid Build Coastguard Worker 
init(void)588*35238bceSAndroid Build Coastguard Worker void VertexAttributeCase::init(void)
589*35238bceSAndroid Build Coastguard Worker {
590*35238bceSAndroid Build Coastguard Worker     RenderCase::init();
591*35238bceSAndroid Build Coastguard Worker 
592*35238bceSAndroid Build Coastguard Worker     // init gl resources
593*35238bceSAndroid Build Coastguard Worker     if (m_storage == STORAGE_BUFFER)
594*35238bceSAndroid Build Coastguard Worker     {
595*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
596*35238bceSAndroid Build Coastguard Worker 
597*35238bceSAndroid Build Coastguard Worker         gl.genBuffers(1, &m_positionVboID);
598*35238bceSAndroid Build Coastguard Worker         gl.genBuffers(1, &m_attribVboID);
599*35238bceSAndroid Build Coastguard Worker         gl.genBuffers(1, &m_elementVboID);
600*35238bceSAndroid Build Coastguard Worker     }
601*35238bceSAndroid Build Coastguard Worker }
602*35238bceSAndroid Build Coastguard Worker 
deinit(void)603*35238bceSAndroid Build Coastguard Worker void VertexAttributeCase::deinit(void)
604*35238bceSAndroid Build Coastguard Worker {
605*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
606*35238bceSAndroid Build Coastguard Worker 
607*35238bceSAndroid Build Coastguard Worker     RenderCase::deinit();
608*35238bceSAndroid Build Coastguard Worker 
609*35238bceSAndroid Build Coastguard Worker     if (m_attribVboID)
610*35238bceSAndroid Build Coastguard Worker     {
611*35238bceSAndroid Build Coastguard Worker         gl.deleteBuffers(1, &m_attribVboID);
612*35238bceSAndroid Build Coastguard Worker         m_attribVboID = 0;
613*35238bceSAndroid Build Coastguard Worker     }
614*35238bceSAndroid Build Coastguard Worker 
615*35238bceSAndroid Build Coastguard Worker     if (m_positionVboID)
616*35238bceSAndroid Build Coastguard Worker     {
617*35238bceSAndroid Build Coastguard Worker         gl.deleteBuffers(1, &m_positionVboID);
618*35238bceSAndroid Build Coastguard Worker         m_positionVboID = 0;
619*35238bceSAndroid Build Coastguard Worker     }
620*35238bceSAndroid Build Coastguard Worker 
621*35238bceSAndroid Build Coastguard Worker     if (m_elementVboID)
622*35238bceSAndroid Build Coastguard Worker     {
623*35238bceSAndroid Build Coastguard Worker         gl.deleteBuffers(1, &m_elementVboID);
624*35238bceSAndroid Build Coastguard Worker         m_elementVboID = 0;
625*35238bceSAndroid Build Coastguard Worker     }
626*35238bceSAndroid Build Coastguard Worker }
627*35238bceSAndroid Build Coastguard Worker 
iterate(void)628*35238bceSAndroid Build Coastguard Worker VertexAttributeCase::IterateResult VertexAttributeCase::iterate(void)
629*35238bceSAndroid Build Coastguard Worker {
630*35238bceSAndroid Build Coastguard Worker     // Create a [s_specialFloats] X [s_specialFloats] grid of vertices with each vertex having 2 [s_specialFloats] values
631*35238bceSAndroid Build Coastguard Worker     // and calculate some basic operations with the floating point values. If all goes well, nothing special should happen
632*35238bceSAndroid Build Coastguard Worker 
633*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::Vec4> gridVertices(DE_LENGTH_OF_ARRAY(s_specialFloats) * DE_LENGTH_OF_ARRAY(s_specialFloats));
634*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::UVec4> gridAttributes(DE_LENGTH_OF_ARRAY(s_specialFloats) * DE_LENGTH_OF_ARRAY(s_specialFloats));
635*35238bceSAndroid Build Coastguard Worker     std::vector<uint16_t> indices((DE_LENGTH_OF_ARRAY(s_specialFloats) - 1) *
636*35238bceSAndroid Build Coastguard Worker                                   (DE_LENGTH_OF_ARRAY(s_specialFloats) - 1) * 6);
637*35238bceSAndroid Build Coastguard Worker     tcu::Surface resultImage(TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
638*35238bceSAndroid Build Coastguard Worker 
639*35238bceSAndroid Build Coastguard Worker     // vertices
640*35238bceSAndroid Build Coastguard Worker     for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats); ++x)
641*35238bceSAndroid Build Coastguard Worker         for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats); ++y)
642*35238bceSAndroid Build Coastguard Worker         {
643*35238bceSAndroid Build Coastguard Worker             const uint32_t one = 0x3F800000;
644*35238bceSAndroid Build Coastguard Worker             const float posX   = (float)x / ((float)DE_LENGTH_OF_ARRAY(s_specialFloats) - 1.0f) * 2.0f -
645*35238bceSAndroid Build Coastguard Worker                                1.0f; // map from [0, len(s_specialFloats) - 1] to [-1, 1]
646*35238bceSAndroid Build Coastguard Worker             const float posY = (float)y / ((float)DE_LENGTH_OF_ARRAY(s_specialFloats) - 1.0f) * 2.0f - 1.0f;
647*35238bceSAndroid Build Coastguard Worker 
648*35238bceSAndroid Build Coastguard Worker             gridVertices[x * DE_LENGTH_OF_ARRAY(s_specialFloats) + y] = tcu::Vec4(posX, posY, 0.0f, 1.0f);
649*35238bceSAndroid Build Coastguard Worker             gridAttributes[x * DE_LENGTH_OF_ARRAY(s_specialFloats) + y] =
650*35238bceSAndroid Build Coastguard Worker                 tcu::UVec4(s_specialFloats[x], s_specialFloats[y], one, one);
651*35238bceSAndroid Build Coastguard Worker         }
652*35238bceSAndroid Build Coastguard Worker 
653*35238bceSAndroid Build Coastguard Worker     // tiles
654*35238bceSAndroid Build Coastguard Worker     for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats) - 1; ++x)
655*35238bceSAndroid Build Coastguard Worker         for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats) - 1; ++y)
656*35238bceSAndroid Build Coastguard Worker         {
657*35238bceSAndroid Build Coastguard Worker             const int baseNdx = (x * (DE_LENGTH_OF_ARRAY(s_specialFloats) - 1) + y) * 6;
658*35238bceSAndroid Build Coastguard Worker 
659*35238bceSAndroid Build Coastguard Worker             indices[baseNdx + 0] = (uint16_t)((x + 0) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y + 0));
660*35238bceSAndroid Build Coastguard Worker             indices[baseNdx + 1] = (uint16_t)((x + 1) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y + 1));
661*35238bceSAndroid Build Coastguard Worker             indices[baseNdx + 2] = (uint16_t)((x + 1) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y + 0));
662*35238bceSAndroid Build Coastguard Worker 
663*35238bceSAndroid Build Coastguard Worker             indices[baseNdx + 3] = (uint16_t)((x + 0) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y + 0));
664*35238bceSAndroid Build Coastguard Worker             indices[baseNdx + 4] = (uint16_t)((x + 1) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y + 1));
665*35238bceSAndroid Build Coastguard Worker             indices[baseNdx + 5] = (uint16_t)((x + 0) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y + 1));
666*35238bceSAndroid Build Coastguard Worker         }
667*35238bceSAndroid Build Coastguard Worker 
668*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message
669*35238bceSAndroid Build Coastguard Worker                        << "Drawing a grid with the shader. Setting a_attr for each vertex to (special, special, 1, 1)."
670*35238bceSAndroid Build Coastguard Worker                        << tcu::TestLog::EndMessage;
671*35238bceSAndroid Build Coastguard Worker 
672*35238bceSAndroid Build Coastguard Worker     // Draw grid
673*35238bceSAndroid Build Coastguard Worker     {
674*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
675*35238bceSAndroid Build Coastguard Worker         const GLint positionLoc  = gl.getAttribLocation(m_program->getProgram(), "a_pos");
676*35238bceSAndroid Build Coastguard Worker         const GLint attribLoc    = gl.getAttribLocation(m_program->getProgram(), "a_attr");
677*35238bceSAndroid Build Coastguard Worker 
678*35238bceSAndroid Build Coastguard Worker         if (m_storage == STORAGE_BUFFER)
679*35238bceSAndroid Build Coastguard Worker         {
680*35238bceSAndroid Build Coastguard Worker             gl.bindBuffer(GL_ARRAY_BUFFER, m_positionVboID);
681*35238bceSAndroid Build Coastguard Worker             gl.bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)(gridVertices.size() * sizeof(tcu::Vec4)), &gridVertices[0],
682*35238bceSAndroid Build Coastguard Worker                           GL_STATIC_DRAW);
683*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttributeCase::iterate");
684*35238bceSAndroid Build Coastguard Worker 
685*35238bceSAndroid Build Coastguard Worker             gl.bindBuffer(GL_ARRAY_BUFFER, m_attribVboID);
686*35238bceSAndroid Build Coastguard Worker             gl.bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)(gridAttributes.size() * sizeof(tcu::UVec4)),
687*35238bceSAndroid Build Coastguard Worker                           &gridAttributes[0], GL_STATIC_DRAW);
688*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttributeCase::iterate");
689*35238bceSAndroid Build Coastguard Worker 
690*35238bceSAndroid Build Coastguard Worker             gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementVboID);
691*35238bceSAndroid Build Coastguard Worker             gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (glw::GLsizeiptr)(indices.size() * sizeof(uint16_t)), &indices[0],
692*35238bceSAndroid Build Coastguard Worker                           GL_STATIC_DRAW);
693*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttributeCase::iterate");
694*35238bceSAndroid Build Coastguard Worker         }
695*35238bceSAndroid Build Coastguard Worker 
696*35238bceSAndroid Build Coastguard Worker         gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
697*35238bceSAndroid Build Coastguard Worker         gl.clear(GL_COLOR_BUFFER_BIT);
698*35238bceSAndroid Build Coastguard Worker         gl.viewport(0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
699*35238bceSAndroid Build Coastguard Worker         gl.useProgram(m_program->getProgram());
700*35238bceSAndroid Build Coastguard Worker 
701*35238bceSAndroid Build Coastguard Worker         if (m_storage == STORAGE_BUFFER)
702*35238bceSAndroid Build Coastguard Worker         {
703*35238bceSAndroid Build Coastguard Worker             gl.bindBuffer(GL_ARRAY_BUFFER, m_positionVboID);
704*35238bceSAndroid Build Coastguard Worker             gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
705*35238bceSAndroid Build Coastguard Worker 
706*35238bceSAndroid Build Coastguard Worker             gl.bindBuffer(GL_ARRAY_BUFFER, m_attribVboID);
707*35238bceSAndroid Build Coastguard Worker             gl.vertexAttribPointer(attribLoc, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
708*35238bceSAndroid Build Coastguard Worker 
709*35238bceSAndroid Build Coastguard Worker             gl.enableVertexAttribArray(positionLoc);
710*35238bceSAndroid Build Coastguard Worker             gl.enableVertexAttribArray(attribLoc);
711*35238bceSAndroid Build Coastguard Worker             gl.drawElements(GL_TRIANGLES, (glw::GLsizei)(indices.size()), GL_UNSIGNED_SHORT, DE_NULL);
712*35238bceSAndroid Build Coastguard Worker             gl.disableVertexAttribArray(positionLoc);
713*35238bceSAndroid Build Coastguard Worker             gl.disableVertexAttribArray(attribLoc);
714*35238bceSAndroid Build Coastguard Worker 
715*35238bceSAndroid Build Coastguard Worker             gl.bindBuffer(GL_ARRAY_BUFFER, 0);
716*35238bceSAndroid Build Coastguard Worker             gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
717*35238bceSAndroid Build Coastguard Worker         }
718*35238bceSAndroid Build Coastguard Worker         else if (m_storage == STORAGE_CLIENT)
719*35238bceSAndroid Build Coastguard Worker         {
720*35238bceSAndroid Build Coastguard Worker             gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, &gridVertices[0]);
721*35238bceSAndroid Build Coastguard Worker             gl.vertexAttribPointer(attribLoc, 4, GL_FLOAT, GL_FALSE, 0, &gridAttributes[0]);
722*35238bceSAndroid Build Coastguard Worker 
723*35238bceSAndroid Build Coastguard Worker             gl.enableVertexAttribArray(positionLoc);
724*35238bceSAndroid Build Coastguard Worker             gl.enableVertexAttribArray(attribLoc);
725*35238bceSAndroid Build Coastguard Worker             gl.drawElements(GL_TRIANGLES, (glw::GLsizei)(indices.size()), GL_UNSIGNED_SHORT, &indices[0]);
726*35238bceSAndroid Build Coastguard Worker             gl.disableVertexAttribArray(positionLoc);
727*35238bceSAndroid Build Coastguard Worker             gl.disableVertexAttribArray(attribLoc);
728*35238bceSAndroid Build Coastguard Worker         }
729*35238bceSAndroid Build Coastguard Worker         else
730*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
731*35238bceSAndroid Build Coastguard Worker 
732*35238bceSAndroid Build Coastguard Worker         gl.useProgram(0);
733*35238bceSAndroid Build Coastguard Worker         gl.finish();
734*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "VertexAttributeCase::iterate");
735*35238bceSAndroid Build Coastguard Worker 
736*35238bceSAndroid Build Coastguard Worker         glu::readPixels(m_context.getRenderContext(), 0, 0, resultImage.getAccess());
737*35238bceSAndroid Build Coastguard Worker     }
738*35238bceSAndroid Build Coastguard Worker 
739*35238bceSAndroid Build Coastguard Worker     // verify everywhere was drawn (all pixels have Green = 255)
740*35238bceSAndroid Build Coastguard Worker     if (!checkResultImage(resultImage))
741*35238bceSAndroid Build Coastguard Worker     {
742*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "missing or invalid fragments");
743*35238bceSAndroid Build Coastguard Worker         return STOP;
744*35238bceSAndroid Build Coastguard Worker     }
745*35238bceSAndroid Build Coastguard Worker 
746*35238bceSAndroid Build Coastguard Worker     // test drawing still works
747*35238bceSAndroid Build Coastguard Worker     if (!drawTestPattern(false))
748*35238bceSAndroid Build Coastguard Worker     {
749*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "test pattern failed");
750*35238bceSAndroid Build Coastguard Worker         return STOP;
751*35238bceSAndroid Build Coastguard Worker     }
752*35238bceSAndroid Build Coastguard Worker 
753*35238bceSAndroid Build Coastguard Worker     // all ok
754*35238bceSAndroid Build Coastguard Worker     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
755*35238bceSAndroid Build Coastguard Worker     return STOP;
756*35238bceSAndroid Build Coastguard Worker }
757*35238bceSAndroid Build Coastguard Worker 
genVertexSource(void) const758*35238bceSAndroid Build Coastguard Worker std::string VertexAttributeCase::genVertexSource(void) const
759*35238bceSAndroid Build Coastguard Worker {
760*35238bceSAndroid Build Coastguard Worker     if (m_type == TYPE_VERTEX)
761*35238bceSAndroid Build Coastguard Worker         return "attribute highp vec4 a_pos;\n"
762*35238bceSAndroid Build Coastguard Worker                "attribute highp vec4 a_attr;\n"
763*35238bceSAndroid Build Coastguard Worker                "varying mediump vec4 v_out;\n"
764*35238bceSAndroid Build Coastguard Worker                "void main ()\n"
765*35238bceSAndroid Build Coastguard Worker                "{\n"
766*35238bceSAndroid Build Coastguard Worker                "    highp vec2 a1 = a_attr.xz + a_attr.yw; // add\n"
767*35238bceSAndroid Build Coastguard Worker                "    highp vec2 a2 = a_attr.xz - a_attr.yw; // sub\n"
768*35238bceSAndroid Build Coastguard Worker                "    highp vec2 a3 = a_attr.xz * a_attr.yw; // mul\n"
769*35238bceSAndroid Build Coastguard Worker                "    highp vec2 a4 = a_attr.xz / a_attr.yw; // div\n"
770*35238bceSAndroid Build Coastguard Worker                "    highp vec2 a5 = a_attr.xz + a_attr.yw * a_attr.xz; // fma\n"
771*35238bceSAndroid Build Coastguard Worker                "\n"
772*35238bceSAndroid Build Coastguard Worker                "    highp float green = 1.0 - abs((a1.y + a2.y + a3.y + a4.y + a5.y) - 6.0);\n"
773*35238bceSAndroid Build Coastguard Worker                "    v_out = vec4(a1.x*a3.x + a2.x*a4.x, green, a5.x, 1.0);\n"
774*35238bceSAndroid Build Coastguard Worker                "    gl_Position = a_pos;\n"
775*35238bceSAndroid Build Coastguard Worker                "}\n";
776*35238bceSAndroid Build Coastguard Worker     else
777*35238bceSAndroid Build Coastguard Worker         return s_attrPassthroughVertexShaderSource;
778*35238bceSAndroid Build Coastguard Worker }
779*35238bceSAndroid Build Coastguard Worker 
genFragmentSource(void) const780*35238bceSAndroid Build Coastguard Worker std::string VertexAttributeCase::genFragmentSource(void) const
781*35238bceSAndroid Build Coastguard Worker {
782*35238bceSAndroid Build Coastguard Worker     if (m_type == TYPE_VERTEX)
783*35238bceSAndroid Build Coastguard Worker         return s_colorPassthroughFragmentShaderSource;
784*35238bceSAndroid Build Coastguard Worker     else
785*35238bceSAndroid Build Coastguard Worker         return "varying mediump vec4 v_attr;\n"
786*35238bceSAndroid Build Coastguard Worker                "void main ()\n"
787*35238bceSAndroid Build Coastguard Worker                "{\n"
788*35238bceSAndroid Build Coastguard Worker                "    mediump vec2 a1 = v_attr.xz + v_attr.yw; // add\n"
789*35238bceSAndroid Build Coastguard Worker                "    mediump vec2 a2 = v_attr.xz - v_attr.yw; // sub\n"
790*35238bceSAndroid Build Coastguard Worker                "    mediump vec2 a3 = v_attr.xz * v_attr.yw; // mul\n"
791*35238bceSAndroid Build Coastguard Worker                "    mediump vec2 a4 = v_attr.xz / v_attr.yw; // div\n"
792*35238bceSAndroid Build Coastguard Worker                "    mediump vec2 a5 = v_attr.xz + v_attr.yw * v_attr.xz; // fma\n"
793*35238bceSAndroid Build Coastguard Worker                "\n"
794*35238bceSAndroid Build Coastguard Worker                "    const mediump float epsilon = 0.1; // allow small differences. To results to be wrong they must be "
795*35238bceSAndroid Build Coastguard Worker                "more wrong than that.\n"
796*35238bceSAndroid Build Coastguard Worker                "    mediump float green = 1.0 + epsilon - abs((a1.y + a2.y + a3.y + a4.y + a5.y) - 6.0);\n"
797*35238bceSAndroid Build Coastguard Worker                "    gl_FragColor = vec4(a1.x*a3.x + a2.x*a4.x, green, a5.x, 1.0);\n"
798*35238bceSAndroid Build Coastguard Worker                "}\n";
799*35238bceSAndroid Build Coastguard Worker }
800*35238bceSAndroid Build Coastguard Worker 
801*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
802*35238bceSAndroid Build Coastguard Worker  * \brief Tests special floats as uniforms
803*35238bceSAndroid Build Coastguard Worker  *
804*35238bceSAndroid Build Coastguard Worker  * Tests that special floats transferred to the shader as uniforms do
805*35238bceSAndroid Build Coastguard Worker  * not change the results of normal floating point calculations. Special
806*35238bceSAndroid Build Coastguard Worker  * floats are put to 4-vector's x and y components and value 1.0 is put to
807*35238bceSAndroid Build Coastguard Worker  * z and w. The resulting fragment's green channel should be 1.0
808*35238bceSAndroid Build Coastguard Worker  * everywhere.
809*35238bceSAndroid Build Coastguard Worker  *
810*35238bceSAndroid Build Coastguard Worker  * After the calculation test a test pattern is drawn to detect possible
811*35238bceSAndroid Build Coastguard Worker  * floating point operation anomalies.
812*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
813*35238bceSAndroid Build Coastguard Worker class UniformCase : public RenderCase
814*35238bceSAndroid Build Coastguard Worker {
815*35238bceSAndroid Build Coastguard Worker public:
816*35238bceSAndroid Build Coastguard Worker     enum ShaderType
817*35238bceSAndroid Build Coastguard Worker     {
818*35238bceSAndroid Build Coastguard Worker         TYPE_VERTEX = 0,
819*35238bceSAndroid Build Coastguard Worker         TYPE_FRAGMENT,
820*35238bceSAndroid Build Coastguard Worker     };
821*35238bceSAndroid Build Coastguard Worker 
822*35238bceSAndroid Build Coastguard Worker     UniformCase(Context &context, const char *name, const char *desc, ShaderType type);
823*35238bceSAndroid Build Coastguard Worker     ~UniformCase(void);
824*35238bceSAndroid Build Coastguard Worker 
825*35238bceSAndroid Build Coastguard Worker     void init(void);
826*35238bceSAndroid Build Coastguard Worker     void deinit(void);
827*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
828*35238bceSAndroid Build Coastguard Worker 
829*35238bceSAndroid Build Coastguard Worker private:
830*35238bceSAndroid Build Coastguard Worker     std::string genVertexSource(void) const;
831*35238bceSAndroid Build Coastguard Worker     std::string genFragmentSource(void) const;
832*35238bceSAndroid Build Coastguard Worker 
833*35238bceSAndroid Build Coastguard Worker     const ShaderType m_type;
834*35238bceSAndroid Build Coastguard Worker };
835*35238bceSAndroid Build Coastguard Worker 
UniformCase(Context & context,const char * name,const char * desc,ShaderType type)836*35238bceSAndroid Build Coastguard Worker UniformCase::UniformCase(Context &context, const char *name, const char *desc, ShaderType type)
837*35238bceSAndroid Build Coastguard Worker     : RenderCase(context, name, desc)
838*35238bceSAndroid Build Coastguard Worker     , m_type(type)
839*35238bceSAndroid Build Coastguard Worker {
840*35238bceSAndroid Build Coastguard Worker }
841*35238bceSAndroid Build Coastguard Worker 
~UniformCase(void)842*35238bceSAndroid Build Coastguard Worker UniformCase::~UniformCase(void)
843*35238bceSAndroid Build Coastguard Worker {
844*35238bceSAndroid Build Coastguard Worker     deinit();
845*35238bceSAndroid Build Coastguard Worker }
846*35238bceSAndroid Build Coastguard Worker 
init(void)847*35238bceSAndroid Build Coastguard Worker void UniformCase::init(void)
848*35238bceSAndroid Build Coastguard Worker {
849*35238bceSAndroid Build Coastguard Worker     RenderCase::init();
850*35238bceSAndroid Build Coastguard Worker }
851*35238bceSAndroid Build Coastguard Worker 
deinit(void)852*35238bceSAndroid Build Coastguard Worker void UniformCase::deinit(void)
853*35238bceSAndroid Build Coastguard Worker {
854*35238bceSAndroid Build Coastguard Worker     RenderCase::deinit();
855*35238bceSAndroid Build Coastguard Worker }
856*35238bceSAndroid Build Coastguard Worker 
iterate(void)857*35238bceSAndroid Build Coastguard Worker UniformCase::IterateResult UniformCase::iterate(void)
858*35238bceSAndroid Build Coastguard Worker {
859*35238bceSAndroid Build Coastguard Worker     // Create a [s_specialFloats] X [s_specialFloats] grid of tile with each tile having 2 [s_specialFloats] values
860*35238bceSAndroid Build Coastguard Worker     // and calculate some basic operations with the floating point values. If all goes well, nothing special should happen
861*35238bceSAndroid Build Coastguard Worker 
862*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::Vec4> gridVertices((DE_LENGTH_OF_ARRAY(s_specialFloats) + 1) *
863*35238bceSAndroid Build Coastguard Worker                                         (DE_LENGTH_OF_ARRAY(s_specialFloats) + 1));
864*35238bceSAndroid Build Coastguard Worker     std::vector<uint16_t> indices(DE_LENGTH_OF_ARRAY(s_specialFloats) * DE_LENGTH_OF_ARRAY(s_specialFloats) * 6);
865*35238bceSAndroid Build Coastguard Worker     tcu::Surface resultImage(TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
866*35238bceSAndroid Build Coastguard Worker 
867*35238bceSAndroid Build Coastguard Worker     // vertices
868*35238bceSAndroid Build Coastguard Worker     for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats) + 1; ++x)
869*35238bceSAndroid Build Coastguard Worker         for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats) + 1; ++y)
870*35238bceSAndroid Build Coastguard Worker         {
871*35238bceSAndroid Build Coastguard Worker             const float posX = (float)x / (float)DE_LENGTH_OF_ARRAY(s_specialFloats) * 2.0f -
872*35238bceSAndroid Build Coastguard Worker                                1.0f; // map from [0, len(s_specialFloats) ] to [-1, 1]
873*35238bceSAndroid Build Coastguard Worker             const float posY = (float)y / (float)DE_LENGTH_OF_ARRAY(s_specialFloats) * 2.0f - 1.0f;
874*35238bceSAndroid Build Coastguard Worker 
875*35238bceSAndroid Build Coastguard Worker             gridVertices[x * (DE_LENGTH_OF_ARRAY(s_specialFloats) + 1) + y] = tcu::Vec4(posX, posY, 0.0f, 1.0f);
876*35238bceSAndroid Build Coastguard Worker         }
877*35238bceSAndroid Build Coastguard Worker 
878*35238bceSAndroid Build Coastguard Worker     // tiles
879*35238bceSAndroid Build Coastguard Worker     for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats); ++x)
880*35238bceSAndroid Build Coastguard Worker         for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats); ++y)
881*35238bceSAndroid Build Coastguard Worker         {
882*35238bceSAndroid Build Coastguard Worker             const int baseNdx = (x * (DE_LENGTH_OF_ARRAY(s_specialFloats)) + y) * 6;
883*35238bceSAndroid Build Coastguard Worker 
884*35238bceSAndroid Build Coastguard Worker             indices[baseNdx + 0] = (uint16_t)((x + 0) * (DE_LENGTH_OF_ARRAY(s_specialFloats) + 1) + (y + 0));
885*35238bceSAndroid Build Coastguard Worker             indices[baseNdx + 1] = (uint16_t)((x + 1) * (DE_LENGTH_OF_ARRAY(s_specialFloats) + 1) + (y + 1));
886*35238bceSAndroid Build Coastguard Worker             indices[baseNdx + 2] = (uint16_t)((x + 1) * (DE_LENGTH_OF_ARRAY(s_specialFloats) + 1) + (y + 0));
887*35238bceSAndroid Build Coastguard Worker 
888*35238bceSAndroid Build Coastguard Worker             indices[baseNdx + 3] = (uint16_t)((x + 0) * (DE_LENGTH_OF_ARRAY(s_specialFloats) + 1) + (y + 0));
889*35238bceSAndroid Build Coastguard Worker             indices[baseNdx + 4] = (uint16_t)((x + 1) * (DE_LENGTH_OF_ARRAY(s_specialFloats) + 1) + (y + 1));
890*35238bceSAndroid Build Coastguard Worker             indices[baseNdx + 5] = (uint16_t)((x + 0) * (DE_LENGTH_OF_ARRAY(s_specialFloats) + 1) + (y + 1));
891*35238bceSAndroid Build Coastguard Worker         }
892*35238bceSAndroid Build Coastguard Worker 
893*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog()
894*35238bceSAndroid Build Coastguard Worker         << tcu::TestLog::Message
895*35238bceSAndroid Build Coastguard Worker         << "Drawing a grid with the shader. Setting u_special for vertex each tile to (special, special, 1, 1)."
896*35238bceSAndroid Build Coastguard Worker         << tcu::TestLog::EndMessage;
897*35238bceSAndroid Build Coastguard Worker 
898*35238bceSAndroid Build Coastguard Worker     // Draw grid
899*35238bceSAndroid Build Coastguard Worker     {
900*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
901*35238bceSAndroid Build Coastguard Worker         const GLint positionLoc  = gl.getAttribLocation(m_program->getProgram(), "a_pos");
902*35238bceSAndroid Build Coastguard Worker         const GLint specialLoc   = gl.getUniformLocation(m_program->getProgram(), "u_special");
903*35238bceSAndroid Build Coastguard Worker 
904*35238bceSAndroid Build Coastguard Worker         gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
905*35238bceSAndroid Build Coastguard Worker         gl.clear(GL_COLOR_BUFFER_BIT);
906*35238bceSAndroid Build Coastguard Worker         gl.viewport(0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
907*35238bceSAndroid Build Coastguard Worker         gl.useProgram(m_program->getProgram());
908*35238bceSAndroid Build Coastguard Worker 
909*35238bceSAndroid Build Coastguard Worker         gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, &gridVertices[0]);
910*35238bceSAndroid Build Coastguard Worker         gl.enableVertexAttribArray(positionLoc);
911*35238bceSAndroid Build Coastguard Worker 
912*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats); ++x)
913*35238bceSAndroid Build Coastguard Worker             for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats); ++y)
914*35238bceSAndroid Build Coastguard Worker             {
915*35238bceSAndroid Build Coastguard Worker                 const uint32_t one            = 0x3F800000;
916*35238bceSAndroid Build Coastguard Worker                 const tcu::UVec4 uniformValue = tcu::UVec4(s_specialFloats[x], s_specialFloats[y], one, one);
917*35238bceSAndroid Build Coastguard Worker                 const int indexIndex          = (x * DE_LENGTH_OF_ARRAY(s_specialFloats) + y) * 6;
918*35238bceSAndroid Build Coastguard Worker 
919*35238bceSAndroid Build Coastguard Worker                 gl.uniform4fv(specialLoc, 1, (const float *)uniformValue.getPtr());
920*35238bceSAndroid Build Coastguard Worker                 gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, &indices[indexIndex]);
921*35238bceSAndroid Build Coastguard Worker             }
922*35238bceSAndroid Build Coastguard Worker 
923*35238bceSAndroid Build Coastguard Worker         gl.disableVertexAttribArray(positionLoc);
924*35238bceSAndroid Build Coastguard Worker 
925*35238bceSAndroid Build Coastguard Worker         gl.useProgram(0);
926*35238bceSAndroid Build Coastguard Worker         gl.finish();
927*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "UniformCase::iterate");
928*35238bceSAndroid Build Coastguard Worker 
929*35238bceSAndroid Build Coastguard Worker         glu::readPixels(m_context.getRenderContext(), 0, 0, resultImage.getAccess());
930*35238bceSAndroid Build Coastguard Worker     }
931*35238bceSAndroid Build Coastguard Worker 
932*35238bceSAndroid Build Coastguard Worker     // verify everywhere was drawn (all pixels have Green = 255)
933*35238bceSAndroid Build Coastguard Worker     if (!checkResultImage(resultImage))
934*35238bceSAndroid Build Coastguard Worker     {
935*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "missing or invalid fragments");
936*35238bceSAndroid Build Coastguard Worker         return STOP;
937*35238bceSAndroid Build Coastguard Worker     }
938*35238bceSAndroid Build Coastguard Worker 
939*35238bceSAndroid Build Coastguard Worker     // test drawing still works
940*35238bceSAndroid Build Coastguard Worker     if (!drawTestPattern(false))
941*35238bceSAndroid Build Coastguard Worker     {
942*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "test pattern failed");
943*35238bceSAndroid Build Coastguard Worker         return STOP;
944*35238bceSAndroid Build Coastguard Worker     }
945*35238bceSAndroid Build Coastguard Worker 
946*35238bceSAndroid Build Coastguard Worker     // all ok
947*35238bceSAndroid Build Coastguard Worker     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
948*35238bceSAndroid Build Coastguard Worker     return STOP;
949*35238bceSAndroid Build Coastguard Worker }
950*35238bceSAndroid Build Coastguard Worker 
genVertexSource(void) const951*35238bceSAndroid Build Coastguard Worker std::string UniformCase::genVertexSource(void) const
952*35238bceSAndroid Build Coastguard Worker {
953*35238bceSAndroid Build Coastguard Worker     if (m_type == TYPE_VERTEX)
954*35238bceSAndroid Build Coastguard Worker         return "attribute highp vec4 a_pos;\n"
955*35238bceSAndroid Build Coastguard Worker                "uniform highp vec4 u_special;\n"
956*35238bceSAndroid Build Coastguard Worker                "varying mediump vec4 v_out;\n"
957*35238bceSAndroid Build Coastguard Worker                "void main ()\n"
958*35238bceSAndroid Build Coastguard Worker                "{\n"
959*35238bceSAndroid Build Coastguard Worker                "    highp vec2 a1 = u_special.xz + u_special.yw; // add\n"
960*35238bceSAndroid Build Coastguard Worker                "    highp vec2 a2 = u_special.xz - u_special.yw; // sub\n"
961*35238bceSAndroid Build Coastguard Worker                "    highp vec2 a3 = u_special.xz * u_special.yw; // mul\n"
962*35238bceSAndroid Build Coastguard Worker                "    highp vec2 a4 = u_special.xz / u_special.yw; // div\n"
963*35238bceSAndroid Build Coastguard Worker                "    highp vec2 a5 = u_special.xz + u_special.yw * u_special.xz; // fma\n"
964*35238bceSAndroid Build Coastguard Worker                "\n"
965*35238bceSAndroid Build Coastguard Worker                "    highp float green = 1.0 - abs((a1.y + a2.y + a3.y + a4.y + a5.y) - 6.0);\n"
966*35238bceSAndroid Build Coastguard Worker                "    v_out = vec4(a1.x*a3.x + a2.x*a4.x, green, a5.x, 1.0);\n"
967*35238bceSAndroid Build Coastguard Worker                "    gl_Position = a_pos;\n"
968*35238bceSAndroid Build Coastguard Worker                "}\n";
969*35238bceSAndroid Build Coastguard Worker     else
970*35238bceSAndroid Build Coastguard Worker         return "attribute highp vec4 a_pos;\n"
971*35238bceSAndroid Build Coastguard Worker                "void main ()\n"
972*35238bceSAndroid Build Coastguard Worker                "{\n"
973*35238bceSAndroid Build Coastguard Worker                "    gl_Position = a_pos;\n"
974*35238bceSAndroid Build Coastguard Worker                "}\n";
975*35238bceSAndroid Build Coastguard Worker }
976*35238bceSAndroid Build Coastguard Worker 
genFragmentSource(void) const977*35238bceSAndroid Build Coastguard Worker std::string UniformCase::genFragmentSource(void) const
978*35238bceSAndroid Build Coastguard Worker {
979*35238bceSAndroid Build Coastguard Worker     if (m_type == TYPE_VERTEX)
980*35238bceSAndroid Build Coastguard Worker         return s_colorPassthroughFragmentShaderSource;
981*35238bceSAndroid Build Coastguard Worker     else
982*35238bceSAndroid Build Coastguard Worker         return "uniform mediump vec4 u_special;\n"
983*35238bceSAndroid Build Coastguard Worker                "void main ()\n"
984*35238bceSAndroid Build Coastguard Worker                "{\n"
985*35238bceSAndroid Build Coastguard Worker                "    mediump vec2 a1 = u_special.xz + u_special.yw; // add\n"
986*35238bceSAndroid Build Coastguard Worker                "    mediump vec2 a2 = u_special.xz - u_special.yw; // sub\n"
987*35238bceSAndroid Build Coastguard Worker                "    mediump vec2 a3 = u_special.xz * u_special.yw; // mul\n"
988*35238bceSAndroid Build Coastguard Worker                "    mediump vec2 a4 = u_special.xz / u_special.yw; // div\n"
989*35238bceSAndroid Build Coastguard Worker                "    mediump vec2 a5 = u_special.xz + u_special.yw * u_special.xz; // fma\n"
990*35238bceSAndroid Build Coastguard Worker                "    mediump vec2 a6 = mod(u_special.xz, u_special.yw);\n"
991*35238bceSAndroid Build Coastguard Worker                "    mediump vec2 a7 = mix(u_special.xz, u_special.yw, a6);\n"
992*35238bceSAndroid Build Coastguard Worker                "\n"
993*35238bceSAndroid Build Coastguard Worker                "    mediump float green = 1.0 - abs((a1.y + a2.y + a3.y + a4.y + a5.y + a6.y + a7.y) - 7.0);\n"
994*35238bceSAndroid Build Coastguard Worker                "    gl_FragColor = vec4(a1.x*a3.x, green, a5.x*a4.x + a2.x*a7.x, 1.0);\n"
995*35238bceSAndroid Build Coastguard Worker                "}\n";
996*35238bceSAndroid Build Coastguard Worker }
997*35238bceSAndroid Build Coastguard Worker 
998*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
999*35238bceSAndroid Build Coastguard Worker  * \brief Tests special floats as texture samping arguments
1000*35238bceSAndroid Build Coastguard Worker  *
1001*35238bceSAndroid Build Coastguard Worker  * Tests that special floats given as texture coordinates or LOD levels
1002*35238bceSAndroid Build Coastguard Worker  * to sampling functions do not return invalid values (values not in the
1003*35238bceSAndroid Build Coastguard Worker  * texture). Every texel's green component is 1.0.
1004*35238bceSAndroid Build Coastguard Worker  *
1005*35238bceSAndroid Build Coastguard Worker  * After the calculation test a test pattern is drawn to detect possible
1006*35238bceSAndroid Build Coastguard Worker  * texture sampling anomalies.
1007*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
1008*35238bceSAndroid Build Coastguard Worker class TextureSamplerCase : public RenderCase
1009*35238bceSAndroid Build Coastguard Worker {
1010*35238bceSAndroid Build Coastguard Worker public:
1011*35238bceSAndroid Build Coastguard Worker     enum ShaderType
1012*35238bceSAndroid Build Coastguard Worker     {
1013*35238bceSAndroid Build Coastguard Worker         TYPE_VERTEX = 0,
1014*35238bceSAndroid Build Coastguard Worker         TYPE_FRAGMENT,
1015*35238bceSAndroid Build Coastguard Worker 
1016*35238bceSAndroid Build Coastguard Worker         TYPE_LAST
1017*35238bceSAndroid Build Coastguard Worker     };
1018*35238bceSAndroid Build Coastguard Worker     enum TestType
1019*35238bceSAndroid Build Coastguard Worker     {
1020*35238bceSAndroid Build Coastguard Worker         TEST_TEX_COORD = 0,
1021*35238bceSAndroid Build Coastguard Worker         TEST_LOD,
1022*35238bceSAndroid Build Coastguard Worker         TEST_TEX_COORD_CUBE,
1023*35238bceSAndroid Build Coastguard Worker 
1024*35238bceSAndroid Build Coastguard Worker         TEST_LAST
1025*35238bceSAndroid Build Coastguard Worker     };
1026*35238bceSAndroid Build Coastguard Worker 
1027*35238bceSAndroid Build Coastguard Worker     TextureSamplerCase(Context &context, const char *name, const char *desc, ShaderType type, TestType testType);
1028*35238bceSAndroid Build Coastguard Worker     ~TextureSamplerCase(void);
1029*35238bceSAndroid Build Coastguard Worker 
1030*35238bceSAndroid Build Coastguard Worker     void init(void);
1031*35238bceSAndroid Build Coastguard Worker     void deinit(void);
1032*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
1033*35238bceSAndroid Build Coastguard Worker 
1034*35238bceSAndroid Build Coastguard Worker private:
1035*35238bceSAndroid Build Coastguard Worker     std::string genVertexSource(void) const;
1036*35238bceSAndroid Build Coastguard Worker     std::string genFragmentSource(void) const;
1037*35238bceSAndroid Build Coastguard Worker 
1038*35238bceSAndroid Build Coastguard Worker     const ShaderType m_type;
1039*35238bceSAndroid Build Coastguard Worker     const TestType m_testType;
1040*35238bceSAndroid Build Coastguard Worker     GLuint m_textureID;
1041*35238bceSAndroid Build Coastguard Worker };
1042*35238bceSAndroid Build Coastguard Worker 
TextureSamplerCase(Context & context,const char * name,const char * desc,ShaderType type,TestType testType)1043*35238bceSAndroid Build Coastguard Worker TextureSamplerCase::TextureSamplerCase(Context &context, const char *name, const char *desc, ShaderType type,
1044*35238bceSAndroid Build Coastguard Worker                                        TestType testType)
1045*35238bceSAndroid Build Coastguard Worker     : RenderCase(context, name, desc)
1046*35238bceSAndroid Build Coastguard Worker     , m_type(type)
1047*35238bceSAndroid Build Coastguard Worker     , m_testType(testType)
1048*35238bceSAndroid Build Coastguard Worker     , m_textureID(0)
1049*35238bceSAndroid Build Coastguard Worker {
1050*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(type < TYPE_LAST);
1051*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(testType < TEST_LAST);
1052*35238bceSAndroid Build Coastguard Worker }
1053*35238bceSAndroid Build Coastguard Worker 
~TextureSamplerCase(void)1054*35238bceSAndroid Build Coastguard Worker TextureSamplerCase::~TextureSamplerCase(void)
1055*35238bceSAndroid Build Coastguard Worker {
1056*35238bceSAndroid Build Coastguard Worker     deinit();
1057*35238bceSAndroid Build Coastguard Worker }
1058*35238bceSAndroid Build Coastguard Worker 
init(void)1059*35238bceSAndroid Build Coastguard Worker void TextureSamplerCase::init(void)
1060*35238bceSAndroid Build Coastguard Worker {
1061*35238bceSAndroid Build Coastguard Worker     // requirements
1062*35238bceSAndroid Build Coastguard Worker     {
1063*35238bceSAndroid Build Coastguard Worker         GLint maxTextureSize = 0;
1064*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext().getFunctions().getIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
1065*35238bceSAndroid Build Coastguard Worker         if (maxTextureSize < TEST_TEXTURE_SIZE)
1066*35238bceSAndroid Build Coastguard Worker             throw tcu::NotSupportedError(std::string("GL_MAX_TEXTURE_SIZE must be at least ") +
1067*35238bceSAndroid Build Coastguard Worker                                          de::toString(TEST_TEXTURE_SIZE));
1068*35238bceSAndroid Build Coastguard Worker     }
1069*35238bceSAndroid Build Coastguard Worker 
1070*35238bceSAndroid Build Coastguard Worker     // vertex shader supports textures?
1071*35238bceSAndroid Build Coastguard Worker     if (m_type == TYPE_VERTEX)
1072*35238bceSAndroid Build Coastguard Worker     {
1073*35238bceSAndroid Build Coastguard Worker         GLint maxVertexTexUnits = 0;
1074*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext().getFunctions().getIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxVertexTexUnits);
1075*35238bceSAndroid Build Coastguard Worker         if (maxVertexTexUnits < 1)
1076*35238bceSAndroid Build Coastguard Worker             throw tcu::NotSupportedError("GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS must be at least 1");
1077*35238bceSAndroid Build Coastguard Worker     }
1078*35238bceSAndroid Build Coastguard Worker 
1079*35238bceSAndroid Build Coastguard Worker     RenderCase::init();
1080*35238bceSAndroid Build Coastguard Worker 
1081*35238bceSAndroid Build Coastguard Worker     // gen texture
1082*35238bceSAndroid Build Coastguard Worker     {
1083*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1084*35238bceSAndroid Build Coastguard Worker         std::vector<uint8_t> texData(TEST_TEXTURE_SIZE * TEST_TEXTURE_SIZE * 4);
1085*35238bceSAndroid Build Coastguard Worker         de::Random rnd(12345);
1086*35238bceSAndroid Build Coastguard Worker 
1087*35238bceSAndroid Build Coastguard Worker         gl.genTextures(1, &m_textureID);
1088*35238bceSAndroid Build Coastguard Worker 
1089*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < TEST_TEXTURE_SIZE; ++x)
1090*35238bceSAndroid Build Coastguard Worker             for (int y = 0; y < TEST_TEXTURE_SIZE; ++y)
1091*35238bceSAndroid Build Coastguard Worker             {
1092*35238bceSAndroid Build Coastguard Worker                 // RGBA8, green and alpha channel are always 255 for verification
1093*35238bceSAndroid Build Coastguard Worker                 texData[(x * TEST_TEXTURE_SIZE + y) * 4 + 0] = rnd.getUint32() & 0xFF;
1094*35238bceSAndroid Build Coastguard Worker                 texData[(x * TEST_TEXTURE_SIZE + y) * 4 + 1] = 0xFF;
1095*35238bceSAndroid Build Coastguard Worker                 texData[(x * TEST_TEXTURE_SIZE + y) * 4 + 2] = rnd.getUint32() & 0xFF;
1096*35238bceSAndroid Build Coastguard Worker                 texData[(x * TEST_TEXTURE_SIZE + y) * 4 + 3] = 0xFF;
1097*35238bceSAndroid Build Coastguard Worker             }
1098*35238bceSAndroid Build Coastguard Worker 
1099*35238bceSAndroid Build Coastguard Worker         if (m_testType == TEST_TEX_COORD)
1100*35238bceSAndroid Build Coastguard Worker         {
1101*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Creating a 2D texture with a test pattern."
1102*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::EndMessage;
1103*35238bceSAndroid Build Coastguard Worker 
1104*35238bceSAndroid Build Coastguard Worker             gl.bindTexture(GL_TEXTURE_2D, m_textureID);
1105*35238bceSAndroid Build Coastguard Worker             gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1106*35238bceSAndroid Build Coastguard Worker                           &texData[0]);
1107*35238bceSAndroid Build Coastguard Worker             gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1108*35238bceSAndroid Build Coastguard Worker             gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1109*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "TextureSamplerCase::init");
1110*35238bceSAndroid Build Coastguard Worker         }
1111*35238bceSAndroid Build Coastguard Worker         else if (m_testType == TEST_LOD)
1112*35238bceSAndroid Build Coastguard Worker         {
1113*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Creating a mipmapped 2D texture with a test pattern."
1114*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::EndMessage;
1115*35238bceSAndroid Build Coastguard Worker 
1116*35238bceSAndroid Build Coastguard Worker             gl.bindTexture(GL_TEXTURE_2D, m_textureID);
1117*35238bceSAndroid Build Coastguard Worker 
1118*35238bceSAndroid Build Coastguard Worker             for (int level = 0; (TEST_TEXTURE_SIZE >> level); ++level)
1119*35238bceSAndroid Build Coastguard Worker                 gl.texImage2D(GL_TEXTURE_2D, level, GL_RGBA, TEST_TEXTURE_SIZE >> level, TEST_TEXTURE_SIZE >> level, 0,
1120*35238bceSAndroid Build Coastguard Worker                               GL_RGBA, GL_UNSIGNED_BYTE, &texData[0]);
1121*35238bceSAndroid Build Coastguard Worker 
1122*35238bceSAndroid Build Coastguard Worker             gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1123*35238bceSAndroid Build Coastguard Worker             gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1124*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "TextureSamplerCase::init");
1125*35238bceSAndroid Build Coastguard Worker         }
1126*35238bceSAndroid Build Coastguard Worker         else if (m_testType == TEST_TEX_COORD_CUBE)
1127*35238bceSAndroid Build Coastguard Worker         {
1128*35238bceSAndroid Build Coastguard Worker             DE_STATIC_ASSERT(TEST_TEXTURE_CUBE_SIZE <= TEST_TEXTURE_SIZE);
1129*35238bceSAndroid Build Coastguard Worker 
1130*35238bceSAndroid Build Coastguard Worker             static const GLenum faces[] = {
1131*35238bceSAndroid Build Coastguard Worker                 GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
1132*35238bceSAndroid Build Coastguard Worker                 GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
1133*35238bceSAndroid Build Coastguard Worker             };
1134*35238bceSAndroid Build Coastguard Worker 
1135*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Creating a cube map with a test pattern."
1136*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::EndMessage;
1137*35238bceSAndroid Build Coastguard Worker 
1138*35238bceSAndroid Build Coastguard Worker             gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_textureID);
1139*35238bceSAndroid Build Coastguard Worker 
1140*35238bceSAndroid Build Coastguard Worker             for (int faceNdx = 0; faceNdx < DE_LENGTH_OF_ARRAY(faces); ++faceNdx)
1141*35238bceSAndroid Build Coastguard Worker                 gl.texImage2D(faces[faceNdx], 0, GL_RGBA, TEST_TEXTURE_CUBE_SIZE, TEST_TEXTURE_CUBE_SIZE, 0, GL_RGBA,
1142*35238bceSAndroid Build Coastguard Worker                               GL_UNSIGNED_BYTE, &texData[0]);
1143*35238bceSAndroid Build Coastguard Worker 
1144*35238bceSAndroid Build Coastguard Worker             gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1145*35238bceSAndroid Build Coastguard Worker             gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1146*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "TextureSamplerCase::init");
1147*35238bceSAndroid Build Coastguard Worker         }
1148*35238bceSAndroid Build Coastguard Worker         else
1149*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
1150*35238bceSAndroid Build Coastguard Worker     }
1151*35238bceSAndroid Build Coastguard Worker }
1152*35238bceSAndroid Build Coastguard Worker 
deinit(void)1153*35238bceSAndroid Build Coastguard Worker void TextureSamplerCase::deinit(void)
1154*35238bceSAndroid Build Coastguard Worker {
1155*35238bceSAndroid Build Coastguard Worker     RenderCase::deinit();
1156*35238bceSAndroid Build Coastguard Worker 
1157*35238bceSAndroid Build Coastguard Worker     if (m_textureID)
1158*35238bceSAndroid Build Coastguard Worker     {
1159*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1160*35238bceSAndroid Build Coastguard Worker 
1161*35238bceSAndroid Build Coastguard Worker         gl.deleteTextures(1, &m_textureID);
1162*35238bceSAndroid Build Coastguard Worker         m_textureID = 0;
1163*35238bceSAndroid Build Coastguard Worker     }
1164*35238bceSAndroid Build Coastguard Worker }
1165*35238bceSAndroid Build Coastguard Worker 
iterate(void)1166*35238bceSAndroid Build Coastguard Worker TextureSamplerCase::IterateResult TextureSamplerCase::iterate(void)
1167*35238bceSAndroid Build Coastguard Worker {
1168*35238bceSAndroid Build Coastguard Worker     // Draw a grid and texture it with a texture and sample it using special special values. The result samples should all have the green channel at 255 as per the test image.
1169*35238bceSAndroid Build Coastguard Worker 
1170*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::Vec4> gridVertices(DE_LENGTH_OF_ARRAY(s_specialFloats) * DE_LENGTH_OF_ARRAY(s_specialFloats));
1171*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::UVec2> gridTexCoords(DE_LENGTH_OF_ARRAY(s_specialFloats) * DE_LENGTH_OF_ARRAY(s_specialFloats));
1172*35238bceSAndroid Build Coastguard Worker     std::vector<uint16_t> indices((DE_LENGTH_OF_ARRAY(s_specialFloats) - 1) *
1173*35238bceSAndroid Build Coastguard Worker                                   (DE_LENGTH_OF_ARRAY(s_specialFloats) - 1) * 6);
1174*35238bceSAndroid Build Coastguard Worker     tcu::Surface resultImage(TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
1175*35238bceSAndroid Build Coastguard Worker 
1176*35238bceSAndroid Build Coastguard Worker     // vertices
1177*35238bceSAndroid Build Coastguard Worker     for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats); ++x)
1178*35238bceSAndroid Build Coastguard Worker         for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats); ++y)
1179*35238bceSAndroid Build Coastguard Worker         {
1180*35238bceSAndroid Build Coastguard Worker             const float posX = (float)x / ((float)DE_LENGTH_OF_ARRAY(s_specialFloats) - 1.0f) * 2.0f -
1181*35238bceSAndroid Build Coastguard Worker                                1.0f; // map from [0, len(s_specialFloats) - 1] to [-1, 1]
1182*35238bceSAndroid Build Coastguard Worker             const float posY = (float)y / ((float)DE_LENGTH_OF_ARRAY(s_specialFloats) - 1.0f) * 2.0f - 1.0f;
1183*35238bceSAndroid Build Coastguard Worker 
1184*35238bceSAndroid Build Coastguard Worker             gridVertices[x * DE_LENGTH_OF_ARRAY(s_specialFloats) + y] = tcu::Vec4(posX, posY, 0.0f, 1.0f);
1185*35238bceSAndroid Build Coastguard Worker             gridTexCoords[x * DE_LENGTH_OF_ARRAY(s_specialFloats) + y] =
1186*35238bceSAndroid Build Coastguard Worker                 tcu::UVec2(s_specialFloats[x], s_specialFloats[y]);
1187*35238bceSAndroid Build Coastguard Worker         }
1188*35238bceSAndroid Build Coastguard Worker 
1189*35238bceSAndroid Build Coastguard Worker     // tiles
1190*35238bceSAndroid Build Coastguard Worker     for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats) - 1; ++x)
1191*35238bceSAndroid Build Coastguard Worker         for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats) - 1; ++y)
1192*35238bceSAndroid Build Coastguard Worker         {
1193*35238bceSAndroid Build Coastguard Worker             const int baseNdx = (x * (DE_LENGTH_OF_ARRAY(s_specialFloats) - 1) + y) * 6;
1194*35238bceSAndroid Build Coastguard Worker 
1195*35238bceSAndroid Build Coastguard Worker             indices[baseNdx + 0] = (uint16_t)((x + 0) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y + 0));
1196*35238bceSAndroid Build Coastguard Worker             indices[baseNdx + 1] = (uint16_t)((x + 1) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y + 1));
1197*35238bceSAndroid Build Coastguard Worker             indices[baseNdx + 2] = (uint16_t)((x + 1) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y + 0));
1198*35238bceSAndroid Build Coastguard Worker 
1199*35238bceSAndroid Build Coastguard Worker             indices[baseNdx + 3] = (uint16_t)((x + 0) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y + 0));
1200*35238bceSAndroid Build Coastguard Worker             indices[baseNdx + 4] = (uint16_t)((x + 1) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y + 1));
1201*35238bceSAndroid Build Coastguard Worker             indices[baseNdx + 5] = (uint16_t)((x + 0) * DE_LENGTH_OF_ARRAY(s_specialFloats) + (y + 1));
1202*35238bceSAndroid Build Coastguard Worker         }
1203*35238bceSAndroid Build Coastguard Worker 
1204*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog()
1205*35238bceSAndroid Build Coastguard Worker         << tcu::TestLog::Message
1206*35238bceSAndroid Build Coastguard Worker         << "Drawing a textured grid with the shader. Sampling from the texture using special floating point values."
1207*35238bceSAndroid Build Coastguard Worker         << tcu::TestLog::EndMessage;
1208*35238bceSAndroid Build Coastguard Worker 
1209*35238bceSAndroid Build Coastguard Worker     // Draw grid
1210*35238bceSAndroid Build Coastguard Worker     {
1211*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1212*35238bceSAndroid Build Coastguard Worker         const GLint positionLoc  = gl.getAttribLocation(m_program->getProgram(), "a_pos");
1213*35238bceSAndroid Build Coastguard Worker         const GLint texCoordLoc  = gl.getAttribLocation(m_program->getProgram(), "a_attr");
1214*35238bceSAndroid Build Coastguard Worker         const GLint samplerLoc   = gl.getUniformLocation(m_program->getProgram(), "u_sampler");
1215*35238bceSAndroid Build Coastguard Worker 
1216*35238bceSAndroid Build Coastguard Worker         gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
1217*35238bceSAndroid Build Coastguard Worker         gl.clear(GL_COLOR_BUFFER_BIT);
1218*35238bceSAndroid Build Coastguard Worker         gl.viewport(0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
1219*35238bceSAndroid Build Coastguard Worker         gl.useProgram(m_program->getProgram());
1220*35238bceSAndroid Build Coastguard Worker 
1221*35238bceSAndroid Build Coastguard Worker         gl.uniform1i(samplerLoc, 0);
1222*35238bceSAndroid Build Coastguard Worker         if (m_testType != TEST_TEX_COORD_CUBE)
1223*35238bceSAndroid Build Coastguard Worker             gl.bindTexture(GL_TEXTURE_2D, m_textureID);
1224*35238bceSAndroid Build Coastguard Worker         else
1225*35238bceSAndroid Build Coastguard Worker             gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_textureID);
1226*35238bceSAndroid Build Coastguard Worker 
1227*35238bceSAndroid Build Coastguard Worker         gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, &gridVertices[0]);
1228*35238bceSAndroid Build Coastguard Worker         gl.vertexAttribPointer(texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, &gridTexCoords[0]);
1229*35238bceSAndroid Build Coastguard Worker 
1230*35238bceSAndroid Build Coastguard Worker         gl.enableVertexAttribArray(positionLoc);
1231*35238bceSAndroid Build Coastguard Worker         gl.enableVertexAttribArray(texCoordLoc);
1232*35238bceSAndroid Build Coastguard Worker         gl.drawElements(GL_TRIANGLES, (glw::GLsizei)(indices.size()), GL_UNSIGNED_SHORT, &indices[0]);
1233*35238bceSAndroid Build Coastguard Worker         gl.disableVertexAttribArray(positionLoc);
1234*35238bceSAndroid Build Coastguard Worker         gl.disableVertexAttribArray(texCoordLoc);
1235*35238bceSAndroid Build Coastguard Worker 
1236*35238bceSAndroid Build Coastguard Worker         gl.useProgram(0);
1237*35238bceSAndroid Build Coastguard Worker         gl.finish();
1238*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "TextureSamplerCase::iterate");
1239*35238bceSAndroid Build Coastguard Worker 
1240*35238bceSAndroid Build Coastguard Worker         glu::readPixels(m_context.getRenderContext(), 0, 0, resultImage.getAccess());
1241*35238bceSAndroid Build Coastguard Worker     }
1242*35238bceSAndroid Build Coastguard Worker 
1243*35238bceSAndroid Build Coastguard Worker     // verify everywhere was drawn and samples were from the texture (all pixels have Green = 255)
1244*35238bceSAndroid Build Coastguard Worker     if (!checkResultImage(resultImage))
1245*35238bceSAndroid Build Coastguard Worker     {
1246*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "missing or invalid fragments");
1247*35238bceSAndroid Build Coastguard Worker         return STOP;
1248*35238bceSAndroid Build Coastguard Worker     }
1249*35238bceSAndroid Build Coastguard Worker 
1250*35238bceSAndroid Build Coastguard Worker     // test drawing and textures still works
1251*35238bceSAndroid Build Coastguard Worker     if (!drawTestPattern(true))
1252*35238bceSAndroid Build Coastguard Worker     {
1253*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "test pattern failed");
1254*35238bceSAndroid Build Coastguard Worker         return STOP;
1255*35238bceSAndroid Build Coastguard Worker     }
1256*35238bceSAndroid Build Coastguard Worker 
1257*35238bceSAndroid Build Coastguard Worker     // all ok
1258*35238bceSAndroid Build Coastguard Worker     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1259*35238bceSAndroid Build Coastguard Worker     return STOP;
1260*35238bceSAndroid Build Coastguard Worker }
1261*35238bceSAndroid Build Coastguard Worker 
genVertexSource(void) const1262*35238bceSAndroid Build Coastguard Worker std::string TextureSamplerCase::genVertexSource(void) const
1263*35238bceSAndroid Build Coastguard Worker {
1264*35238bceSAndroid Build Coastguard Worker     // vertex shader is passthrough, fragment does the calculations
1265*35238bceSAndroid Build Coastguard Worker     if (m_type == TYPE_FRAGMENT)
1266*35238bceSAndroid Build Coastguard Worker         return s_attrPassthroughVertexShaderSource;
1267*35238bceSAndroid Build Coastguard Worker 
1268*35238bceSAndroid Build Coastguard Worker     // vertex shader does the calculations
1269*35238bceSAndroid Build Coastguard Worker     std::ostringstream buf;
1270*35238bceSAndroid Build Coastguard Worker     buf << "attribute highp vec4 a_pos;\n"
1271*35238bceSAndroid Build Coastguard Worker            "attribute highp vec2 a_attr;\n";
1272*35238bceSAndroid Build Coastguard Worker 
1273*35238bceSAndroid Build Coastguard Worker     if (m_testType != TEST_TEX_COORD_CUBE)
1274*35238bceSAndroid Build Coastguard Worker         buf << "uniform highp sampler2D u_sampler;\n";
1275*35238bceSAndroid Build Coastguard Worker     else
1276*35238bceSAndroid Build Coastguard Worker         buf << "uniform highp samplerCube u_sampler;\n";
1277*35238bceSAndroid Build Coastguard Worker 
1278*35238bceSAndroid Build Coastguard Worker     buf << "varying mediump vec4 v_out;\n"
1279*35238bceSAndroid Build Coastguard Worker            "void main ()\n"
1280*35238bceSAndroid Build Coastguard Worker            "{\n";
1281*35238bceSAndroid Build Coastguard Worker 
1282*35238bceSAndroid Build Coastguard Worker     if (m_testType == TEST_TEX_COORD)
1283*35238bceSAndroid Build Coastguard Worker         buf << "    v_out = texture2DLod(u_sampler, a_attr, 0.0);\n";
1284*35238bceSAndroid Build Coastguard Worker     else if (m_testType == TEST_LOD)
1285*35238bceSAndroid Build Coastguard Worker         buf << "    v_out = texture2DLod(u_sampler, a_attr, a_attr.x);\n";
1286*35238bceSAndroid Build Coastguard Worker     else if (m_testType == TEST_TEX_COORD_CUBE)
1287*35238bceSAndroid Build Coastguard Worker         buf << "    v_out = textureCubeLod(u_sampler, vec3(a_attr, a_attr.x+a_attr.y), 0.0);\n";
1288*35238bceSAndroid Build Coastguard Worker     else
1289*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1290*35238bceSAndroid Build Coastguard Worker 
1291*35238bceSAndroid Build Coastguard Worker     buf << "\n"
1292*35238bceSAndroid Build Coastguard Worker            "    gl_Position = a_pos;\n"
1293*35238bceSAndroid Build Coastguard Worker            "}\n";
1294*35238bceSAndroid Build Coastguard Worker 
1295*35238bceSAndroid Build Coastguard Worker     return buf.str();
1296*35238bceSAndroid Build Coastguard Worker }
1297*35238bceSAndroid Build Coastguard Worker 
genFragmentSource(void) const1298*35238bceSAndroid Build Coastguard Worker std::string TextureSamplerCase::genFragmentSource(void) const
1299*35238bceSAndroid Build Coastguard Worker {
1300*35238bceSAndroid Build Coastguard Worker     // fragment shader is passthrough
1301*35238bceSAndroid Build Coastguard Worker     if (m_type == TYPE_VERTEX)
1302*35238bceSAndroid Build Coastguard Worker         return s_colorPassthroughFragmentShaderSource;
1303*35238bceSAndroid Build Coastguard Worker 
1304*35238bceSAndroid Build Coastguard Worker     // fragment shader does the calculations
1305*35238bceSAndroid Build Coastguard Worker     std::ostringstream buf;
1306*35238bceSAndroid Build Coastguard Worker     if (m_testType != TEST_TEX_COORD_CUBE)
1307*35238bceSAndroid Build Coastguard Worker         buf << "uniform mediump sampler2D u_sampler;\n";
1308*35238bceSAndroid Build Coastguard Worker     else
1309*35238bceSAndroid Build Coastguard Worker         buf << "uniform mediump samplerCube u_sampler;\n";
1310*35238bceSAndroid Build Coastguard Worker 
1311*35238bceSAndroid Build Coastguard Worker     buf << "varying mediump vec4 v_attr;\n"
1312*35238bceSAndroid Build Coastguard Worker            "void main ()\n"
1313*35238bceSAndroid Build Coastguard Worker            "{\n";
1314*35238bceSAndroid Build Coastguard Worker 
1315*35238bceSAndroid Build Coastguard Worker     if (m_testType == TEST_TEX_COORD)
1316*35238bceSAndroid Build Coastguard Worker         buf << "    gl_FragColor = texture2D(u_sampler, v_attr.xy);\n";
1317*35238bceSAndroid Build Coastguard Worker     else if (m_testType == TEST_LOD)
1318*35238bceSAndroid Build Coastguard Worker         buf << "    gl_FragColor = texture2D(u_sampler, v_attr.xy, v_attr.x);\n";
1319*35238bceSAndroid Build Coastguard Worker     else if (m_testType == TEST_TEX_COORD_CUBE)
1320*35238bceSAndroid Build Coastguard Worker         buf << "    gl_FragColor = textureCube(u_sampler, vec3(v_attr.xy, v_attr.x + v_attr.y));\n";
1321*35238bceSAndroid Build Coastguard Worker     else
1322*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1323*35238bceSAndroid Build Coastguard Worker 
1324*35238bceSAndroid Build Coastguard Worker     buf << "}\n";
1325*35238bceSAndroid Build Coastguard Worker 
1326*35238bceSAndroid Build Coastguard Worker     return buf.str();
1327*35238bceSAndroid Build Coastguard Worker }
1328*35238bceSAndroid Build Coastguard Worker 
1329*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
1330*35238bceSAndroid Build Coastguard Worker  * \brief Tests special floats as fragment shader outputs
1331*35238bceSAndroid Build Coastguard Worker  *
1332*35238bceSAndroid Build Coastguard Worker  * Tests that outputting special floats from a fragment shader does not change
1333*35238bceSAndroid Build Coastguard Worker  * the normal floating point values of outputted from a fragment shader. Special
1334*35238bceSAndroid Build Coastguard Worker  * floats are outputted in the green component, normal floating point values
1335*35238bceSAndroid Build Coastguard Worker  * in the red and blue component. Potential changes are tested by rendering
1336*35238bceSAndroid Build Coastguard Worker  * test pattern two times with different floating point values. The resulting
1337*35238bceSAndroid Build Coastguard Worker  * images' red and blue channels should be equal.
1338*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
1339*35238bceSAndroid Build Coastguard Worker class OutputCase : public FramebufferRenderCase
1340*35238bceSAndroid Build Coastguard Worker {
1341*35238bceSAndroid Build Coastguard Worker public:
1342*35238bceSAndroid Build Coastguard Worker     OutputCase(Context &context, const char *name, const char *desc, FramebufferRenderCase::FrameBufferType type);
1343*35238bceSAndroid Build Coastguard Worker     ~OutputCase(void);
1344*35238bceSAndroid Build Coastguard Worker 
1345*35238bceSAndroid Build Coastguard Worker     void testFBO(void);
1346*35238bceSAndroid Build Coastguard Worker 
1347*35238bceSAndroid Build Coastguard Worker private:
1348*35238bceSAndroid Build Coastguard Worker     std::string genVertexSource(void) const;
1349*35238bceSAndroid Build Coastguard Worker     std::string genFragmentSource(void) const;
1350*35238bceSAndroid Build Coastguard Worker };
1351*35238bceSAndroid Build Coastguard Worker 
OutputCase(Context & context,const char * name,const char * desc,FramebufferRenderCase::FrameBufferType type)1352*35238bceSAndroid Build Coastguard Worker OutputCase::OutputCase(Context &context, const char *name, const char *desc,
1353*35238bceSAndroid Build Coastguard Worker                        FramebufferRenderCase::FrameBufferType type)
1354*35238bceSAndroid Build Coastguard Worker     : FramebufferRenderCase(context, name, desc, type)
1355*35238bceSAndroid Build Coastguard Worker {
1356*35238bceSAndroid Build Coastguard Worker }
1357*35238bceSAndroid Build Coastguard Worker 
~OutputCase(void)1358*35238bceSAndroid Build Coastguard Worker OutputCase::~OutputCase(void)
1359*35238bceSAndroid Build Coastguard Worker {
1360*35238bceSAndroid Build Coastguard Worker     deinit();
1361*35238bceSAndroid Build Coastguard Worker }
1362*35238bceSAndroid Build Coastguard Worker 
testFBO(void)1363*35238bceSAndroid Build Coastguard Worker void OutputCase::testFBO(void)
1364*35238bceSAndroid Build Coastguard Worker {
1365*35238bceSAndroid Build Coastguard Worker     // Create a 1 X [s_specialFloats] grid of tiles (stripes).
1366*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::Vec4> gridVertices((DE_LENGTH_OF_ARRAY(s_specialFloats) + 1) * 2);
1367*35238bceSAndroid Build Coastguard Worker     std::vector<uint16_t> indices(DE_LENGTH_OF_ARRAY(s_specialFloats) * 6);
1368*35238bceSAndroid Build Coastguard Worker     tcu::TextureFormat textureFormat(tcu::TextureFormat::RGBA, (m_fboType == FBO_RGBA_FLOAT16) ?
1369*35238bceSAndroid Build Coastguard Worker                                                                    (tcu::TextureFormat::FLOAT) :
1370*35238bceSAndroid Build Coastguard Worker                                                                    (tcu::TextureFormat::UNORM_INT8));
1371*35238bceSAndroid Build Coastguard Worker     tcu::TextureLevel specialImage(textureFormat, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
1372*35238bceSAndroid Build Coastguard Worker     tcu::TextureLevel normalImage(textureFormat, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
1373*35238bceSAndroid Build Coastguard Worker 
1374*35238bceSAndroid Build Coastguard Worker     // vertices
1375*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats) + 1; ++y)
1376*35238bceSAndroid Build Coastguard Worker     {
1377*35238bceSAndroid Build Coastguard Worker         const float posY = (float)y / (float)DE_LENGTH_OF_ARRAY(s_specialFloats) * 2.0f -
1378*35238bceSAndroid Build Coastguard Worker                            1.0f; // map from [0, len(s_specialFloats) ] to [-1, 1]
1379*35238bceSAndroid Build Coastguard Worker 
1380*35238bceSAndroid Build Coastguard Worker         gridVertices[y * 2 + 0] = tcu::Vec4(-1.0, posY, 0.0f, 1.0f);
1381*35238bceSAndroid Build Coastguard Worker         gridVertices[y * 2 + 1] = tcu::Vec4(1.0, posY, 0.0f, 1.0f);
1382*35238bceSAndroid Build Coastguard Worker     }
1383*35238bceSAndroid Build Coastguard Worker 
1384*35238bceSAndroid Build Coastguard Worker     // tiles
1385*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats); ++y)
1386*35238bceSAndroid Build Coastguard Worker     {
1387*35238bceSAndroid Build Coastguard Worker         const int baseNdx = y * 6;
1388*35238bceSAndroid Build Coastguard Worker 
1389*35238bceSAndroid Build Coastguard Worker         indices[baseNdx + 0] = (uint16_t)((y + 0) * 2);
1390*35238bceSAndroid Build Coastguard Worker         indices[baseNdx + 1] = (uint16_t)((y + 1) * 2);
1391*35238bceSAndroid Build Coastguard Worker         indices[baseNdx + 2] = (uint16_t)((y + 1) * 2 + 1);
1392*35238bceSAndroid Build Coastguard Worker 
1393*35238bceSAndroid Build Coastguard Worker         indices[baseNdx + 3] = (uint16_t)((y + 0) * 2);
1394*35238bceSAndroid Build Coastguard Worker         indices[baseNdx + 4] = (uint16_t)((y + 1) * 2 + 1);
1395*35238bceSAndroid Build Coastguard Worker         indices[baseNdx + 5] = (uint16_t)((y + 0) * 2 + 1);
1396*35238bceSAndroid Build Coastguard Worker     }
1397*35238bceSAndroid Build Coastguard Worker 
1398*35238bceSAndroid Build Coastguard Worker     // Draw grids
1399*35238bceSAndroid Build Coastguard Worker     {
1400*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1401*35238bceSAndroid Build Coastguard Worker         const GLint positionLoc  = gl.getAttribLocation(m_program->getProgram(), "a_pos");
1402*35238bceSAndroid Build Coastguard Worker         const GLint specialLoc   = gl.getUniformLocation(m_program->getProgram(), "u_special");
1403*35238bceSAndroid Build Coastguard Worker 
1404*35238bceSAndroid Build Coastguard Worker         gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
1405*35238bceSAndroid Build Coastguard Worker         gl.viewport(0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
1406*35238bceSAndroid Build Coastguard Worker         gl.useProgram(m_program->getProgram());
1407*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "pre-draw");
1408*35238bceSAndroid Build Coastguard Worker 
1409*35238bceSAndroid Build Coastguard Worker         gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, &gridVertices[0]);
1410*35238bceSAndroid Build Coastguard Worker         gl.enableVertexAttribArray(positionLoc);
1411*35238bceSAndroid Build Coastguard Worker 
1412*35238bceSAndroid Build Coastguard Worker         // draw 2 passes. Special and normal.
1413*35238bceSAndroid Build Coastguard Worker         for (int passNdx = 0; passNdx < 2; ++passNdx)
1414*35238bceSAndroid Build Coastguard Worker         {
1415*35238bceSAndroid Build Coastguard Worker             const bool specialPass = (passNdx == 0);
1416*35238bceSAndroid Build Coastguard Worker 
1417*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Pass " << passNdx
1418*35238bceSAndroid Build Coastguard Worker                                << ": Drawing stripes with the shader. Setting u_special for each stripe to ("
1419*35238bceSAndroid Build Coastguard Worker                                << ((specialPass) ? ("special") : ("1.0")) << ")." << tcu::TestLog::EndMessage;
1420*35238bceSAndroid Build Coastguard Worker 
1421*35238bceSAndroid Build Coastguard Worker             // draw stripes
1422*35238bceSAndroid Build Coastguard Worker             gl.clear(GL_COLOR_BUFFER_BIT);
1423*35238bceSAndroid Build Coastguard Worker             for (int y = 0; y < DE_LENGTH_OF_ARRAY(s_specialFloats); ++y)
1424*35238bceSAndroid Build Coastguard Worker             {
1425*35238bceSAndroid Build Coastguard Worker                 const uint32_t one          = 0x3F800000;
1426*35238bceSAndroid Build Coastguard Worker                 const uint32_t special      = s_specialFloats[y];
1427*35238bceSAndroid Build Coastguard Worker                 const uint32_t uniformValue = (specialPass) ? (special) : (one);
1428*35238bceSAndroid Build Coastguard Worker                 const int indexIndex        = y * 6;
1429*35238bceSAndroid Build Coastguard Worker 
1430*35238bceSAndroid Build Coastguard Worker                 gl.uniform1fv(specialLoc, 1, (const float *)&uniformValue);
1431*35238bceSAndroid Build Coastguard Worker                 gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, &indices[indexIndex]);
1432*35238bceSAndroid Build Coastguard Worker             }
1433*35238bceSAndroid Build Coastguard Worker 
1434*35238bceSAndroid Build Coastguard Worker             gl.finish();
1435*35238bceSAndroid Build Coastguard Worker             glu::readPixels(m_context.getRenderContext(), 0, 0,
1436*35238bceSAndroid Build Coastguard Worker                             ((specialPass) ? (specialImage) : (normalImage)).getAccess());
1437*35238bceSAndroid Build Coastguard Worker         }
1438*35238bceSAndroid Build Coastguard Worker 
1439*35238bceSAndroid Build Coastguard Worker         gl.disableVertexAttribArray(positionLoc);
1440*35238bceSAndroid Build Coastguard Worker         gl.useProgram(0);
1441*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "OutputCase::iterate");
1442*35238bceSAndroid Build Coastguard Worker     }
1443*35238bceSAndroid Build Coastguard Worker 
1444*35238bceSAndroid Build Coastguard Worker     // Check results
1445*35238bceSAndroid Build Coastguard Worker     {
1446*35238bceSAndroid Build Coastguard Worker         tcu::Surface errorMask(TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
1447*35238bceSAndroid Build Coastguard Worker         const tcu::RGBA badPixelColor = tcu::RGBA::red();
1448*35238bceSAndroid Build Coastguard Worker         const tcu::RGBA okPixelColor  = tcu::RGBA::green();
1449*35238bceSAndroid Build Coastguard Worker         int badPixels                 = 0;
1450*35238bceSAndroid Build Coastguard Worker 
1451*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message
1452*35238bceSAndroid Build Coastguard Worker                            << "Checking passes have identical red and blue channels and the green channel is correct "
1453*35238bceSAndroid Build Coastguard Worker                               "in the constant pass."
1454*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
1455*35238bceSAndroid Build Coastguard Worker 
1456*35238bceSAndroid Build Coastguard Worker         for (int y = 0; y < specialImage.getHeight(); ++y)
1457*35238bceSAndroid Build Coastguard Worker             for (int x = 0; x < specialImage.getWidth(); ++x)
1458*35238bceSAndroid Build Coastguard Worker             {
1459*35238bceSAndroid Build Coastguard Worker                 const float greenThreshold = 0.1f;
1460*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec4 cNormal    = normalImage.getAccess().getPixel(x, y);
1461*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec4 cSpecial   = specialImage.getAccess().getPixel(x, y);
1462*35238bceSAndroid Build Coastguard Worker 
1463*35238bceSAndroid Build Coastguard Worker                 if (cNormal.x() != cSpecial.x() || cNormal.z() != cSpecial.z() || cNormal.y() < 1.0f - greenThreshold)
1464*35238bceSAndroid Build Coastguard Worker                 {
1465*35238bceSAndroid Build Coastguard Worker                     ++badPixels;
1466*35238bceSAndroid Build Coastguard Worker                     errorMask.setPixel(x, y, badPixelColor);
1467*35238bceSAndroid Build Coastguard Worker                 }
1468*35238bceSAndroid Build Coastguard Worker                 else
1469*35238bceSAndroid Build Coastguard Worker                     errorMask.setPixel(x, y, okPixelColor);
1470*35238bceSAndroid Build Coastguard Worker             }
1471*35238bceSAndroid Build Coastguard Worker 
1472*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Found " << badPixels << " invalid pixel(s)."
1473*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
1474*35238bceSAndroid Build Coastguard Worker 
1475*35238bceSAndroid Build Coastguard Worker         if (badPixels)
1476*35238bceSAndroid Build Coastguard Worker         {
1477*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::ImageSet("Results", "Result verification")
1478*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::Image("Image with special green channel",
1479*35238bceSAndroid Build Coastguard Worker                                                       "Image with special green channel", specialImage)
1480*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::Image("Image with constant green channel",
1481*35238bceSAndroid Build Coastguard Worker                                                       "Image with constant green channel", normalImage)
1482*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::Image("Error Mask", "Error Mask", errorMask)
1483*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::EndImageSet;
1484*35238bceSAndroid Build Coastguard Worker 
1485*35238bceSAndroid Build Coastguard Worker             // all ok?
1486*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
1487*35238bceSAndroid Build Coastguard Worker         }
1488*35238bceSAndroid Build Coastguard Worker         else
1489*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1490*35238bceSAndroid Build Coastguard Worker     }
1491*35238bceSAndroid Build Coastguard Worker }
1492*35238bceSAndroid Build Coastguard Worker 
genVertexSource(void) const1493*35238bceSAndroid Build Coastguard Worker std::string OutputCase::genVertexSource(void) const
1494*35238bceSAndroid Build Coastguard Worker {
1495*35238bceSAndroid Build Coastguard Worker     return "attribute highp vec4 a_pos;\n"
1496*35238bceSAndroid Build Coastguard Worker            "varying mediump vec2 v_pos;\n"
1497*35238bceSAndroid Build Coastguard Worker            "void main ()\n"
1498*35238bceSAndroid Build Coastguard Worker            "{\n"
1499*35238bceSAndroid Build Coastguard Worker            "    gl_Position = a_pos;\n"
1500*35238bceSAndroid Build Coastguard Worker            "    v_pos = a_pos.xy;\n"
1501*35238bceSAndroid Build Coastguard Worker            "}\n";
1502*35238bceSAndroid Build Coastguard Worker }
1503*35238bceSAndroid Build Coastguard Worker 
genFragmentSource(void) const1504*35238bceSAndroid Build Coastguard Worker std::string OutputCase::genFragmentSource(void) const
1505*35238bceSAndroid Build Coastguard Worker {
1506*35238bceSAndroid Build Coastguard Worker     return "uniform mediump float u_special;\n"
1507*35238bceSAndroid Build Coastguard Worker            "varying mediump vec2 v_pos;\n"
1508*35238bceSAndroid Build Coastguard Worker            "void main ()\n"
1509*35238bceSAndroid Build Coastguard Worker            "{\n"
1510*35238bceSAndroid Build Coastguard Worker            "    gl_FragColor = vec4((v_pos.x + 1.0) * 0.5, u_special, (v_pos.y + 1.0) * 0.5, 1.0);\n"
1511*35238bceSAndroid Build Coastguard Worker            "}\n";
1512*35238bceSAndroid Build Coastguard Worker }
1513*35238bceSAndroid Build Coastguard Worker 
1514*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
1515*35238bceSAndroid Build Coastguard Worker  * \brief Tests special floats in blending
1516*35238bceSAndroid Build Coastguard Worker  *
1517*35238bceSAndroid Build Coastguard Worker  * Tests special floats as alpha and color components with various blending
1518*35238bceSAndroid Build Coastguard Worker  * modes. Test draws a test pattern and then does various blend operations
1519*35238bceSAndroid Build Coastguard Worker  * with special float values. After the blending test another test pattern
1520*35238bceSAndroid Build Coastguard Worker  * is drawn to detect possible blending anomalies. Test patterns should be
1521*35238bceSAndroid Build Coastguard Worker  * identical.
1522*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
1523*35238bceSAndroid Build Coastguard Worker class BlendingCase : public FramebufferRenderCase
1524*35238bceSAndroid Build Coastguard Worker {
1525*35238bceSAndroid Build Coastguard Worker public:
1526*35238bceSAndroid Build Coastguard Worker     BlendingCase(Context &context, const char *name, const char *desc, FramebufferRenderCase::FrameBufferType type);
1527*35238bceSAndroid Build Coastguard Worker     ~BlendingCase(void);
1528*35238bceSAndroid Build Coastguard Worker 
1529*35238bceSAndroid Build Coastguard Worker     void testFBO(void);
1530*35238bceSAndroid Build Coastguard Worker 
1531*35238bceSAndroid Build Coastguard Worker private:
1532*35238bceSAndroid Build Coastguard Worker     void drawTestImage(tcu::PixelBufferAccess dst, GLuint uColorLoc, int maxVertexIndex);
1533*35238bceSAndroid Build Coastguard Worker 
1534*35238bceSAndroid Build Coastguard Worker     std::string genVertexSource(void) const;
1535*35238bceSAndroid Build Coastguard Worker     std::string genFragmentSource(void) const;
1536*35238bceSAndroid Build Coastguard Worker };
1537*35238bceSAndroid Build Coastguard Worker 
BlendingCase(Context & context,const char * name,const char * desc,FramebufferRenderCase::FrameBufferType type)1538*35238bceSAndroid Build Coastguard Worker BlendingCase::BlendingCase(Context &context, const char *name, const char *desc,
1539*35238bceSAndroid Build Coastguard Worker                            FramebufferRenderCase::FrameBufferType type)
1540*35238bceSAndroid Build Coastguard Worker     : FramebufferRenderCase(context, name, desc, type)
1541*35238bceSAndroid Build Coastguard Worker {
1542*35238bceSAndroid Build Coastguard Worker }
1543*35238bceSAndroid Build Coastguard Worker 
~BlendingCase(void)1544*35238bceSAndroid Build Coastguard Worker BlendingCase::~BlendingCase(void)
1545*35238bceSAndroid Build Coastguard Worker {
1546*35238bceSAndroid Build Coastguard Worker     deinit();
1547*35238bceSAndroid Build Coastguard Worker }
1548*35238bceSAndroid Build Coastguard Worker 
testFBO(void)1549*35238bceSAndroid Build Coastguard Worker void BlendingCase::testFBO(void)
1550*35238bceSAndroid Build Coastguard Worker {
1551*35238bceSAndroid Build Coastguard Worker     static const GLenum equations[] = {
1552*35238bceSAndroid Build Coastguard Worker         GL_FUNC_ADD,
1553*35238bceSAndroid Build Coastguard Worker         GL_FUNC_SUBTRACT,
1554*35238bceSAndroid Build Coastguard Worker         GL_FUNC_REVERSE_SUBTRACT,
1555*35238bceSAndroid Build Coastguard Worker     };
1556*35238bceSAndroid Build Coastguard Worker     static const GLenum functions[] = {
1557*35238bceSAndroid Build Coastguard Worker         GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
1558*35238bceSAndroid Build Coastguard Worker     };
1559*35238bceSAndroid Build Coastguard Worker 
1560*35238bceSAndroid Build Coastguard Worker     // Create a [BlendFuncs] X [s_specialFloats] grid of tiles. ( BlendFuncs = equations x functions )
1561*35238bceSAndroid Build Coastguard Worker 
1562*35238bceSAndroid Build Coastguard Worker     const int numBlendFuncs = DE_LENGTH_OF_ARRAY(equations) * DE_LENGTH_OF_ARRAY(functions);
1563*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::Vec4> gridVertices((numBlendFuncs + 1) * (DE_LENGTH_OF_ARRAY(s_specialFloats) + 1));
1564*35238bceSAndroid Build Coastguard Worker     std::vector<uint16_t> indices(numBlendFuncs * DE_LENGTH_OF_ARRAY(s_specialFloats) * 6);
1565*35238bceSAndroid Build Coastguard Worker     tcu::TextureFormat textureFormat(tcu::TextureFormat::RGBA, (m_fboType == FBO_RGBA_FLOAT16) ?
1566*35238bceSAndroid Build Coastguard Worker                                                                    (tcu::TextureFormat::FLOAT) :
1567*35238bceSAndroid Build Coastguard Worker                                                                    (tcu::TextureFormat::UNORM_INT8));
1568*35238bceSAndroid Build Coastguard Worker     tcu::TextureLevel beforeImage(textureFormat, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
1569*35238bceSAndroid Build Coastguard Worker     tcu::TextureLevel afterImage(textureFormat, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
1570*35238bceSAndroid Build Coastguard Worker 
1571*35238bceSAndroid Build Coastguard Worker     // vertices
1572*35238bceSAndroid Build Coastguard Worker     for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats) + 1; ++x)
1573*35238bceSAndroid Build Coastguard Worker         for (int y = 0; y < numBlendFuncs + 1; ++y)
1574*35238bceSAndroid Build Coastguard Worker         {
1575*35238bceSAndroid Build Coastguard Worker             const float posX = (float)x / (float)DE_LENGTH_OF_ARRAY(s_specialFloats) * 2.0f -
1576*35238bceSAndroid Build Coastguard Worker                                1.0f; // map from [0, len(s_specialFloats)] to [-1, 1]
1577*35238bceSAndroid Build Coastguard Worker             const float posY = (float)y / (float)numBlendFuncs * 2.0f - 1.0f;
1578*35238bceSAndroid Build Coastguard Worker 
1579*35238bceSAndroid Build Coastguard Worker             gridVertices[x * (numBlendFuncs + 1) + y] = tcu::Vec4(posX, posY, 0.0f, 1.0f);
1580*35238bceSAndroid Build Coastguard Worker         }
1581*35238bceSAndroid Build Coastguard Worker 
1582*35238bceSAndroid Build Coastguard Worker     // tiles
1583*35238bceSAndroid Build Coastguard Worker     for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats); ++x)
1584*35238bceSAndroid Build Coastguard Worker         for (int y = 0; y < numBlendFuncs; ++y)
1585*35238bceSAndroid Build Coastguard Worker         {
1586*35238bceSAndroid Build Coastguard Worker             const int baseNdx = (x * numBlendFuncs + y) * 6;
1587*35238bceSAndroid Build Coastguard Worker 
1588*35238bceSAndroid Build Coastguard Worker             indices[baseNdx + 0] = (uint16_t)((x + 0) * (numBlendFuncs + 1) + (y + 0));
1589*35238bceSAndroid Build Coastguard Worker             indices[baseNdx + 1] = (uint16_t)((x + 1) * (numBlendFuncs + 1) + (y + 1));
1590*35238bceSAndroid Build Coastguard Worker             indices[baseNdx + 2] = (uint16_t)((x + 1) * (numBlendFuncs + 1) + (y + 0));
1591*35238bceSAndroid Build Coastguard Worker 
1592*35238bceSAndroid Build Coastguard Worker             indices[baseNdx + 3] = (uint16_t)((x + 0) * (numBlendFuncs + 1) + (y + 0));
1593*35238bceSAndroid Build Coastguard Worker             indices[baseNdx + 4] = (uint16_t)((x + 1) * (numBlendFuncs + 1) + (y + 1));
1594*35238bceSAndroid Build Coastguard Worker             indices[baseNdx + 5] = (uint16_t)((x + 0) * (numBlendFuncs + 1) + (y + 1));
1595*35238bceSAndroid Build Coastguard Worker         }
1596*35238bceSAndroid Build Coastguard Worker 
1597*35238bceSAndroid Build Coastguard Worker     // Draw tiles
1598*35238bceSAndroid Build Coastguard Worker     {
1599*35238bceSAndroid Build Coastguard Worker         const int numPasses      = 5;
1600*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1601*35238bceSAndroid Build Coastguard Worker         const GLint positionLoc  = gl.getAttribLocation(m_program->getProgram(), "a_pos");
1602*35238bceSAndroid Build Coastguard Worker         const GLint specialLoc   = gl.getUniformLocation(m_program->getProgram(), "u_special");
1603*35238bceSAndroid Build Coastguard Worker 
1604*35238bceSAndroid Build Coastguard Worker         gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
1605*35238bceSAndroid Build Coastguard Worker         gl.clear(GL_COLOR_BUFFER_BIT);
1606*35238bceSAndroid Build Coastguard Worker         gl.viewport(0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
1607*35238bceSAndroid Build Coastguard Worker         gl.useProgram(m_program->getProgram());
1608*35238bceSAndroid Build Coastguard Worker         gl.enable(GL_BLEND);
1609*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "pre-draw");
1610*35238bceSAndroid Build Coastguard Worker 
1611*35238bceSAndroid Build Coastguard Worker         gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, &gridVertices[0]);
1612*35238bceSAndroid Build Coastguard Worker         gl.enableVertexAttribArray(positionLoc);
1613*35238bceSAndroid Build Coastguard Worker 
1614*35238bceSAndroid Build Coastguard Worker         // draw "before" image
1615*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Drawing pre-draw pattern." << tcu::TestLog::EndMessage;
1616*35238bceSAndroid Build Coastguard Worker         drawTestImage(beforeImage.getAccess(), specialLoc, (int)gridVertices.size() - 1);
1617*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "pre-draw pattern");
1618*35238bceSAndroid Build Coastguard Worker 
1619*35238bceSAndroid Build Coastguard Worker         // draw multiple passes with special floats
1620*35238bceSAndroid Build Coastguard Worker         gl.clear(GL_COLOR_BUFFER_BIT);
1621*35238bceSAndroid Build Coastguard Worker         for (int passNdx = 0; passNdx < numPasses; ++passNdx)
1622*35238bceSAndroid Build Coastguard Worker         {
1623*35238bceSAndroid Build Coastguard Worker             de::Random rnd(123 + 567 * passNdx);
1624*35238bceSAndroid Build Coastguard Worker 
1625*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Pass " << passNdx << ": Drawing tiles with the shader.\n"
1626*35238bceSAndroid Build Coastguard Worker                                << "\tVarying u_special for each tile.\n"
1627*35238bceSAndroid Build Coastguard Worker                                << "\tVarying blend function and blend equation for each tile.\n"
1628*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::EndMessage;
1629*35238bceSAndroid Build Coastguard Worker 
1630*35238bceSAndroid Build Coastguard Worker             // draw tiles
1631*35238bceSAndroid Build Coastguard Worker             for (int x = 0; x < DE_LENGTH_OF_ARRAY(s_specialFloats); ++x)
1632*35238bceSAndroid Build Coastguard Worker                 for (int y = 0; y < numBlendFuncs; ++y)
1633*35238bceSAndroid Build Coastguard Worker                 {
1634*35238bceSAndroid Build Coastguard Worker                     const GLenum blendEquation = equations[y % DE_LENGTH_OF_ARRAY(equations)];
1635*35238bceSAndroid Build Coastguard Worker                     const GLenum blendFunction = functions[y / DE_LENGTH_OF_ARRAY(equations)];
1636*35238bceSAndroid Build Coastguard Worker                     const GLenum blendFunctionDst =
1637*35238bceSAndroid Build Coastguard Worker                         rnd.choose<GLenum>(DE_ARRAY_BEGIN(functions), DE_ARRAY_END(functions));
1638*35238bceSAndroid Build Coastguard Worker                     const int indexIndex = (x * numBlendFuncs + y) * 6;
1639*35238bceSAndroid Build Coastguard Worker 
1640*35238bceSAndroid Build Coastguard Worker                     // "rnd.get"s are run in a deterministic order
1641*35238bceSAndroid Build Coastguard Worker                     const uint32_t componentR =
1642*35238bceSAndroid Build Coastguard Worker                         rnd.choose<uint32_t>(DE_ARRAY_BEGIN(s_specialFloats), DE_ARRAY_END(s_specialFloats));
1643*35238bceSAndroid Build Coastguard Worker                     const uint32_t componentG =
1644*35238bceSAndroid Build Coastguard Worker                         rnd.choose<uint32_t>(DE_ARRAY_BEGIN(s_specialFloats), DE_ARRAY_END(s_specialFloats));
1645*35238bceSAndroid Build Coastguard Worker                     const uint32_t componentB =
1646*35238bceSAndroid Build Coastguard Worker                         rnd.choose<uint32_t>(DE_ARRAY_BEGIN(s_specialFloats), DE_ARRAY_END(s_specialFloats));
1647*35238bceSAndroid Build Coastguard Worker                     const uint32_t componentA =
1648*35238bceSAndroid Build Coastguard Worker                         rnd.choose<uint32_t>(DE_ARRAY_BEGIN(s_specialFloats), DE_ARRAY_END(s_specialFloats));
1649*35238bceSAndroid Build Coastguard Worker                     const tcu::UVec4 uniformValue = tcu::UVec4(componentR, componentG, componentB, componentA);
1650*35238bceSAndroid Build Coastguard Worker 
1651*35238bceSAndroid Build Coastguard Worker                     gl.uniform4fv(specialLoc, 1, (const float *)uniformValue.getPtr());
1652*35238bceSAndroid Build Coastguard Worker                     gl.blendEquation(blendEquation);
1653*35238bceSAndroid Build Coastguard Worker                     gl.blendFunc(blendFunction, blendFunctionDst);
1654*35238bceSAndroid Build Coastguard Worker                     gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, &indices[indexIndex]);
1655*35238bceSAndroid Build Coastguard Worker                 }
1656*35238bceSAndroid Build Coastguard Worker         }
1657*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "special passes");
1658*35238bceSAndroid Build Coastguard Worker 
1659*35238bceSAndroid Build Coastguard Worker         // draw "after" image
1660*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Drawing post-draw pattern." << tcu::TestLog::EndMessage;
1661*35238bceSAndroid Build Coastguard Worker         drawTestImage(afterImage.getAccess(), specialLoc, (int)gridVertices.size() - 1);
1662*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "post-draw pattern");
1663*35238bceSAndroid Build Coastguard Worker 
1664*35238bceSAndroid Build Coastguard Worker         gl.disableVertexAttribArray(positionLoc);
1665*35238bceSAndroid Build Coastguard Worker         gl.useProgram(0);
1666*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "OutputCase::iterate");
1667*35238bceSAndroid Build Coastguard Worker     }
1668*35238bceSAndroid Build Coastguard Worker 
1669*35238bceSAndroid Build Coastguard Worker     // Check results
1670*35238bceSAndroid Build Coastguard Worker     {
1671*35238bceSAndroid Build Coastguard Worker         tcu::Surface errorMask(TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
1672*35238bceSAndroid Build Coastguard Worker         const tcu::RGBA badPixelColor = tcu::RGBA::red();
1673*35238bceSAndroid Build Coastguard Worker         const tcu::RGBA okPixelColor  = tcu::RGBA::green();
1674*35238bceSAndroid Build Coastguard Worker         int badPixels                 = 0;
1675*35238bceSAndroid Build Coastguard Worker 
1676*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Checking patterns are identical." << tcu::TestLog::EndMessage;
1677*35238bceSAndroid Build Coastguard Worker 
1678*35238bceSAndroid Build Coastguard Worker         for (int y = 0; y < beforeImage.getHeight(); ++y)
1679*35238bceSAndroid Build Coastguard Worker             for (int x = 0; x < beforeImage.getWidth(); ++x)
1680*35238bceSAndroid Build Coastguard Worker             {
1681*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec4 cBefore = beforeImage.getAccess().getPixel(x, y);
1682*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec4 cAfter  = afterImage.getAccess().getPixel(x, y);
1683*35238bceSAndroid Build Coastguard Worker 
1684*35238bceSAndroid Build Coastguard Worker                 if (cBefore != cAfter)
1685*35238bceSAndroid Build Coastguard Worker                 {
1686*35238bceSAndroid Build Coastguard Worker                     ++badPixels;
1687*35238bceSAndroid Build Coastguard Worker                     errorMask.setPixel(x, y, badPixelColor);
1688*35238bceSAndroid Build Coastguard Worker                 }
1689*35238bceSAndroid Build Coastguard Worker                 else
1690*35238bceSAndroid Build Coastguard Worker                     errorMask.setPixel(x, y, okPixelColor);
1691*35238bceSAndroid Build Coastguard Worker             }
1692*35238bceSAndroid Build Coastguard Worker 
1693*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Found " << badPixels << " invalid pixel(s)."
1694*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
1695*35238bceSAndroid Build Coastguard Worker 
1696*35238bceSAndroid Build Coastguard Worker         if (badPixels)
1697*35238bceSAndroid Build Coastguard Worker         {
1698*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::ImageSet("Results", "Result verification")
1699*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::Image("Pattern drawn before special float blending",
1700*35238bceSAndroid Build Coastguard Worker                                                       "Pattern drawn before special float blending", beforeImage)
1701*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::Image("Pattern drawn after special float blending",
1702*35238bceSAndroid Build Coastguard Worker                                                       "Pattern drawn after special float blending", afterImage)
1703*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::EndImageSet;
1704*35238bceSAndroid Build Coastguard Worker 
1705*35238bceSAndroid Build Coastguard Worker             // all ok?
1706*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
1707*35238bceSAndroid Build Coastguard Worker         }
1708*35238bceSAndroid Build Coastguard Worker         else
1709*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1710*35238bceSAndroid Build Coastguard Worker     }
1711*35238bceSAndroid Build Coastguard Worker }
1712*35238bceSAndroid Build Coastguard Worker 
drawTestImage(tcu::PixelBufferAccess dst,GLuint uColorLoc,int maxVertexIndex)1713*35238bceSAndroid Build Coastguard Worker void BlendingCase::drawTestImage(tcu::PixelBufferAccess dst, GLuint uColorLoc, int maxVertexIndex)
1714*35238bceSAndroid Build Coastguard Worker {
1715*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1716*35238bceSAndroid Build Coastguard Worker     de::Random rnd(123);
1717*35238bceSAndroid Build Coastguard Worker 
1718*35238bceSAndroid Build Coastguard Worker     gl.clear(GL_COLOR_BUFFER_BIT);
1719*35238bceSAndroid Build Coastguard Worker     gl.blendEquation(GL_FUNC_ADD);
1720*35238bceSAndroid Build Coastguard Worker     gl.blendFunc(GL_ONE, GL_ONE);
1721*35238bceSAndroid Build Coastguard Worker 
1722*35238bceSAndroid Build Coastguard Worker     for (int tri = 0; tri < 20; ++tri)
1723*35238bceSAndroid Build Coastguard Worker     {
1724*35238bceSAndroid Build Coastguard Worker         tcu::Vec4 color;
1725*35238bceSAndroid Build Coastguard Worker         color.x() = rnd.getFloat();
1726*35238bceSAndroid Build Coastguard Worker         color.y() = rnd.getFloat();
1727*35238bceSAndroid Build Coastguard Worker         color.z() = rnd.getFloat();
1728*35238bceSAndroid Build Coastguard Worker         color.w() = rnd.getFloat();
1729*35238bceSAndroid Build Coastguard Worker         gl.uniform4fv(uColorLoc, 1, color.getPtr());
1730*35238bceSAndroid Build Coastguard Worker 
1731*35238bceSAndroid Build Coastguard Worker         uint16_t indices[3];
1732*35238bceSAndroid Build Coastguard Worker         indices[0] = (uint16_t)rnd.getInt(0, maxVertexIndex);
1733*35238bceSAndroid Build Coastguard Worker         indices[1] = (uint16_t)rnd.getInt(0, maxVertexIndex);
1734*35238bceSAndroid Build Coastguard Worker         indices[2] = (uint16_t)rnd.getInt(0, maxVertexIndex);
1735*35238bceSAndroid Build Coastguard Worker 
1736*35238bceSAndroid Build Coastguard Worker         gl.drawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, indices);
1737*35238bceSAndroid Build Coastguard Worker     }
1738*35238bceSAndroid Build Coastguard Worker 
1739*35238bceSAndroid Build Coastguard Worker     gl.finish();
1740*35238bceSAndroid Build Coastguard Worker     glu::readPixels(m_context.getRenderContext(), 0, 0, dst);
1741*35238bceSAndroid Build Coastguard Worker }
1742*35238bceSAndroid Build Coastguard Worker 
genVertexSource(void) const1743*35238bceSAndroid Build Coastguard Worker std::string BlendingCase::genVertexSource(void) const
1744*35238bceSAndroid Build Coastguard Worker {
1745*35238bceSAndroid Build Coastguard Worker     return "attribute highp vec4 a_pos;\n"
1746*35238bceSAndroid Build Coastguard Worker            "void main ()\n"
1747*35238bceSAndroid Build Coastguard Worker            "{\n"
1748*35238bceSAndroid Build Coastguard Worker            "    gl_Position = a_pos;\n"
1749*35238bceSAndroid Build Coastguard Worker            "}\n";
1750*35238bceSAndroid Build Coastguard Worker }
1751*35238bceSAndroid Build Coastguard Worker 
genFragmentSource(void) const1752*35238bceSAndroid Build Coastguard Worker std::string BlendingCase::genFragmentSource(void) const
1753*35238bceSAndroid Build Coastguard Worker {
1754*35238bceSAndroid Build Coastguard Worker     return "uniform mediump vec4 u_special;\n"
1755*35238bceSAndroid Build Coastguard Worker            "void main ()\n"
1756*35238bceSAndroid Build Coastguard Worker            "{\n"
1757*35238bceSAndroid Build Coastguard Worker            "    gl_FragColor = u_special;\n"
1758*35238bceSAndroid Build Coastguard Worker            "}\n";
1759*35238bceSAndroid Build Coastguard Worker }
1760*35238bceSAndroid Build Coastguard Worker 
1761*35238bceSAndroid Build Coastguard Worker } // namespace
1762*35238bceSAndroid Build Coastguard Worker 
SpecialFloatTests(Context & context)1763*35238bceSAndroid Build Coastguard Worker SpecialFloatTests::SpecialFloatTests(Context &context) : TestCaseGroup(context, "special_float", "Special float tests")
1764*35238bceSAndroid Build Coastguard Worker {
1765*35238bceSAndroid Build Coastguard Worker }
1766*35238bceSAndroid Build Coastguard Worker 
~SpecialFloatTests(void)1767*35238bceSAndroid Build Coastguard Worker SpecialFloatTests::~SpecialFloatTests(void)
1768*35238bceSAndroid Build Coastguard Worker {
1769*35238bceSAndroid Build Coastguard Worker }
1770*35238bceSAndroid Build Coastguard Worker 
init(void)1771*35238bceSAndroid Build Coastguard Worker void SpecialFloatTests::init(void)
1772*35238bceSAndroid Build Coastguard Worker {
1773*35238bceSAndroid Build Coastguard Worker     tcu::TestCaseGroup *const vertexGroup =
1774*35238bceSAndroid Build Coastguard Worker         new tcu::TestCaseGroup(m_testCtx, "vertex", "Run vertex shader with special float values");
1775*35238bceSAndroid Build Coastguard Worker     tcu::TestCaseGroup *const fragmentGroup =
1776*35238bceSAndroid Build Coastguard Worker         new tcu::TestCaseGroup(m_testCtx, "fragment", "Run fragment shader with special float values");
1777*35238bceSAndroid Build Coastguard Worker     tcu::TestCaseGroup *const framebufferGroup =
1778*35238bceSAndroid Build Coastguard Worker         new tcu::TestCaseGroup(m_testCtx, "framebuffer", "Test framebuffers containing special float values");
1779*35238bceSAndroid Build Coastguard Worker 
1780*35238bceSAndroid Build Coastguard Worker     // .vertex
1781*35238bceSAndroid Build Coastguard Worker     {
1782*35238bceSAndroid Build Coastguard Worker         vertexGroup->addChild(
1783*35238bceSAndroid Build Coastguard Worker             new VertexAttributeCase(m_context, "attribute_buffer", "special attribute values in a buffer",
1784*35238bceSAndroid Build Coastguard Worker                                     VertexAttributeCase::STORAGE_BUFFER, VertexAttributeCase::TYPE_VERTEX));
1785*35238bceSAndroid Build Coastguard Worker         vertexGroup->addChild(
1786*35238bceSAndroid Build Coastguard Worker             new VertexAttributeCase(m_context, "attribute_client", "special attribute values in a client storage",
1787*35238bceSAndroid Build Coastguard Worker                                     VertexAttributeCase::STORAGE_CLIENT, VertexAttributeCase::TYPE_VERTEX));
1788*35238bceSAndroid Build Coastguard Worker         vertexGroup->addChild(
1789*35238bceSAndroid Build Coastguard Worker             new UniformCase(m_context, "uniform", "special uniform values", UniformCase::TYPE_VERTEX));
1790*35238bceSAndroid Build Coastguard Worker         vertexGroup->addChild(new TextureSamplerCase(m_context, "sampler_tex_coord", "special texture coords",
1791*35238bceSAndroid Build Coastguard Worker                                                      TextureSamplerCase::TYPE_VERTEX,
1792*35238bceSAndroid Build Coastguard Worker                                                      TextureSamplerCase::TEST_TEX_COORD));
1793*35238bceSAndroid Build Coastguard Worker         vertexGroup->addChild(
1794*35238bceSAndroid Build Coastguard Worker             new TextureSamplerCase(m_context, "sampler_tex_coord_cube", "special texture coords to cubemap",
1795*35238bceSAndroid Build Coastguard Worker                                    TextureSamplerCase::TYPE_VERTEX, TextureSamplerCase::TEST_TEX_COORD_CUBE));
1796*35238bceSAndroid Build Coastguard Worker         vertexGroup->addChild(new TextureSamplerCase(m_context, "sampler_lod", "special texture lod",
1797*35238bceSAndroid Build Coastguard Worker                                                      TextureSamplerCase::TYPE_VERTEX, TextureSamplerCase::TEST_LOD));
1798*35238bceSAndroid Build Coastguard Worker 
1799*35238bceSAndroid Build Coastguard Worker         addChild(vertexGroup);
1800*35238bceSAndroid Build Coastguard Worker     }
1801*35238bceSAndroid Build Coastguard Worker 
1802*35238bceSAndroid Build Coastguard Worker     // .fragment
1803*35238bceSAndroid Build Coastguard Worker     {
1804*35238bceSAndroid Build Coastguard Worker         fragmentGroup->addChild(
1805*35238bceSAndroid Build Coastguard Worker             new VertexAttributeCase(m_context, "attribute_buffer", "special attribute values in a buffer",
1806*35238bceSAndroid Build Coastguard Worker                                     VertexAttributeCase::STORAGE_BUFFER, VertexAttributeCase::TYPE_FRAGMENT));
1807*35238bceSAndroid Build Coastguard Worker         fragmentGroup->addChild(
1808*35238bceSAndroid Build Coastguard Worker             new VertexAttributeCase(m_context, "attribute_client", "special attribute values in a client storage",
1809*35238bceSAndroid Build Coastguard Worker                                     VertexAttributeCase::STORAGE_CLIENT, VertexAttributeCase::TYPE_FRAGMENT));
1810*35238bceSAndroid Build Coastguard Worker         fragmentGroup->addChild(
1811*35238bceSAndroid Build Coastguard Worker             new UniformCase(m_context, "uniform", "special uniform values", UniformCase::TYPE_FRAGMENT));
1812*35238bceSAndroid Build Coastguard Worker         fragmentGroup->addChild(new TextureSamplerCase(m_context, "sampler_tex_coord", "special texture coords",
1813*35238bceSAndroid Build Coastguard Worker                                                        TextureSamplerCase::TYPE_FRAGMENT,
1814*35238bceSAndroid Build Coastguard Worker                                                        TextureSamplerCase::TEST_TEX_COORD));
1815*35238bceSAndroid Build Coastguard Worker         fragmentGroup->addChild(
1816*35238bceSAndroid Build Coastguard Worker             new TextureSamplerCase(m_context, "sampler_tex_coord_cube", "special texture coords to cubemap",
1817*35238bceSAndroid Build Coastguard Worker                                    TextureSamplerCase::TYPE_FRAGMENT, TextureSamplerCase::TEST_TEX_COORD_CUBE));
1818*35238bceSAndroid Build Coastguard Worker         fragmentGroup->addChild(new TextureSamplerCase(m_context, "sampler_lod", "special texture lod",
1819*35238bceSAndroid Build Coastguard Worker                                                        TextureSamplerCase::TYPE_FRAGMENT,
1820*35238bceSAndroid Build Coastguard Worker                                                        TextureSamplerCase::TEST_LOD));
1821*35238bceSAndroid Build Coastguard Worker 
1822*35238bceSAndroid Build Coastguard Worker         addChild(fragmentGroup);
1823*35238bceSAndroid Build Coastguard Worker     }
1824*35238bceSAndroid Build Coastguard Worker 
1825*35238bceSAndroid Build Coastguard Worker     // .framebuffer
1826*35238bceSAndroid Build Coastguard Worker     {
1827*35238bceSAndroid Build Coastguard Worker         framebufferGroup->addChild(new OutputCase(m_context, "write_default",
1828*35238bceSAndroid Build Coastguard Worker                                                   "write special floating point values to default framebuffer",
1829*35238bceSAndroid Build Coastguard Worker                                                   FramebufferRenderCase::FBO_DEFAULT));
1830*35238bceSAndroid Build Coastguard Worker         framebufferGroup->addChild(new OutputCase(m_context, "write_rgba",
1831*35238bceSAndroid Build Coastguard Worker                                                   "write special floating point values to RGBA framebuffer",
1832*35238bceSAndroid Build Coastguard Worker                                                   FramebufferRenderCase::FBO_RGBA));
1833*35238bceSAndroid Build Coastguard Worker         framebufferGroup->addChild(new OutputCase(m_context, "write_rgba4",
1834*35238bceSAndroid Build Coastguard Worker                                                   "write special floating point values to RGBA4 framebuffer",
1835*35238bceSAndroid Build Coastguard Worker                                                   FramebufferRenderCase::FBO_RGBA4));
1836*35238bceSAndroid Build Coastguard Worker         framebufferGroup->addChild(new OutputCase(m_context, "write_rgb5_a1",
1837*35238bceSAndroid Build Coastguard Worker                                                   "write special floating point values to RGB5_A1 framebuffer",
1838*35238bceSAndroid Build Coastguard Worker                                                   FramebufferRenderCase::FBO_RGB5_A1));
1839*35238bceSAndroid Build Coastguard Worker         framebufferGroup->addChild(new OutputCase(m_context, "write_rgb565",
1840*35238bceSAndroid Build Coastguard Worker                                                   "write special floating point values to RGB565 framebuffer",
1841*35238bceSAndroid Build Coastguard Worker                                                   FramebufferRenderCase::FBO_RGB565));
1842*35238bceSAndroid Build Coastguard Worker         framebufferGroup->addChild(new OutputCase(m_context, "write_float16",
1843*35238bceSAndroid Build Coastguard Worker                                                   "write special floating point values to float16 framebuffer",
1844*35238bceSAndroid Build Coastguard Worker                                                   FramebufferRenderCase::FBO_RGBA_FLOAT16));
1845*35238bceSAndroid Build Coastguard Worker 
1846*35238bceSAndroid Build Coastguard Worker         framebufferGroup->addChild(new BlendingCase(m_context, "blend_default",
1847*35238bceSAndroid Build Coastguard Worker                                                     "blend special floating point values in a default framebuffer",
1848*35238bceSAndroid Build Coastguard Worker                                                     FramebufferRenderCase::FBO_DEFAULT));
1849*35238bceSAndroid Build Coastguard Worker         framebufferGroup->addChild(new BlendingCase(m_context, "blend_rgba",
1850*35238bceSAndroid Build Coastguard Worker                                                     "blend special floating point values in a RGBA framebuffer",
1851*35238bceSAndroid Build Coastguard Worker                                                     FramebufferRenderCase::FBO_RGBA));
1852*35238bceSAndroid Build Coastguard Worker         framebufferGroup->addChild(new BlendingCase(m_context, "blend_float16",
1853*35238bceSAndroid Build Coastguard Worker                                                     "blend special floating point values in a float16 framebuffer",
1854*35238bceSAndroid Build Coastguard Worker                                                     FramebufferRenderCase::FBO_RGBA_FLOAT16));
1855*35238bceSAndroid Build Coastguard Worker 
1856*35238bceSAndroid Build Coastguard Worker         addChild(framebufferGroup);
1857*35238bceSAndroid Build Coastguard Worker     }
1858*35238bceSAndroid Build Coastguard Worker }
1859*35238bceSAndroid Build Coastguard Worker 
1860*35238bceSAndroid Build Coastguard Worker } // namespace Stress
1861*35238bceSAndroid Build Coastguard Worker } // namespace gles2
1862*35238bceSAndroid Build Coastguard Worker } // namespace deqp
1863