Merge vk-gl-cts/vulkan-cts-1.0.1 into vk-gl-cts/vulkan-cts-1.0.2
[platform/upstream/VK-GL-CTS.git] / modules / gles3 / functional / es3fDefaultVertexAttributeTests.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.0 Module
3  * -------------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Default vertex attribute test
22  *//*--------------------------------------------------------------------*/
23
24 #include "es3fDefaultVertexAttributeTests.hpp"
25 #include "tcuVector.hpp"
26 #include "tcuRenderTarget.hpp"
27 #include "tcuSurface.hpp"
28 #include "tcuTextureUtil.hpp"
29 #include "gluRenderContext.hpp"
30 #include "gluCallLogWrapper.hpp"
31 #include "gluShaderProgram.hpp"
32 #include "gluObjectWrapper.hpp"
33 #include "gluPixelTransfer.hpp"
34 #include "glwEnums.hpp"
35 #include "glwFunctions.hpp"
36 #include "deMath.h"
37 #include "deStringUtil.hpp"
38 #include "deString.h"
39
40 #include <limits>
41
42 namespace deqp
43 {
44 namespace gles3
45 {
46 namespace Functional
47 {
48 namespace
49 {
50
51 static const int s_valueRange = 10;
52
53 static const char* const s_passThroughFragmentShaderSource =    "#version 300 es\n"
54                                                                                                                                 "layout(location = 0) out mediump vec4 fragColor;\n"
55                                                                                                                                 "in mediump vec4 v_color;\n"
56                                                                                                                                 "void main (void)\n"
57                                                                                                                                 "{\n"
58                                                                                                                                 "       fragColor = v_color;\n"
59                                                                                                                                 "}\n";
60
61 template <typename T1, int S1, typename T2, int S2>
62 tcu::Vector<T1, S1> convertToTypeVec (const tcu::Vector<T2, S2>& v)
63 {
64         tcu::Vector<T1, S1> retVal;
65
66         for (int ndx = 0; ndx < S1; ++ndx)
67                 retVal[ndx] = T1(0);
68
69         if (S1 == 4)
70                 retVal[3] = T1(1);
71
72         for (int ndx = 0; ndx < de::min(S1, S2); ++ndx)
73                 retVal[ndx] = T1(v[ndx]);
74
75         return retVal;
76 }
77
78 class FloatLoader
79 {
80 public:
81         virtual                         ~FloatLoader    (void) {};
82
83         // returns the value loaded
84         virtual tcu::Vec4       load                    (glu::CallLogWrapper& gl, int index, const tcu::Vec4& v) const = 0;
85 };
86
87 #define GEN_DIRECT_FLOAT_LOADER(TYPE, COMPS, TYPECODE, CASENAME, VALUES)                                \
88         class LoaderVertexAttrib##COMPS##TYPECODE : public FloatLoader                                          \
89         {                                                                                                                                                                       \
90         public:                                                                                                                                                         \
91                 enum                                                                                                                                                    \
92                 {                                                                                                                                                               \
93                         NORMALIZING = 0,                                                                                                                        \
94                 };                                                                                                                                                              \
95                 enum                                                                                                                                                    \
96                 {                                                                                                                                                               \
97                         COMPONENTS = (COMPS)                                                                                                            \
98                 };                                                                                                                                                              \
99                 typedef TYPE Type;                                                                                                                              \
100                                                                                                                                                                                 \
101                 tcu::Vec4 load (glu::CallLogWrapper& gl, int index, const tcu::Vec4& v) const   \
102                 {                                                                                                                                                               \
103                         tcu::Vector<TYPE, COMPONENTS> value;                                                                            \
104                         value = convertToTypeVec<Type, COMPONENTS>(v);                                                          \
105                                                                                                                                                                                 \
106                         gl.glVertexAttrib ##COMPS ##TYPECODE VALUES;                                                            \
107                         return convertToTypeVec<float, 4>(value);                                                                       \
108                 }                                                                                                                                                               \
109                                                                                                                                                                                 \
110                 static const char* getCaseName (void)                                                                                   \
111                 {                                                                                                                                                               \
112                         return CASENAME;                                                                                                                        \
113                 }                                                                                                                                                               \
114                                                                                                                                                                                 \
115                 static const char* getName (void)                                                                                               \
116                 {                                                                                                                                                               \
117                         return "VertexAttrib" #COMPS #TYPECODE;                                                                         \
118                 }                                                                                                                                                               \
119         }
120
121 #define GEN_INDIRECT_FLOAT_LOADER(TYPE, COMPS, TYPECODE, CASENAME)                                              \
122         class LoaderVertexAttrib##COMPS##TYPECODE : public FloatLoader                                          \
123         {                                                                                                                                                                       \
124         public:                                                                                                                                                         \
125                 enum                                                                                                                                                    \
126                 {                                                                                                                                                               \
127                         NORMALIZING = 0,                                                                                                                        \
128                 };                                                                                                                                                              \
129                 enum                                                                                                                                                    \
130                 {                                                                                                                                                               \
131                         COMPONENTS = (COMPS)                                                                                                            \
132                 };                                                                                                                                                              \
133                 typedef TYPE Type;                                                                                                                              \
134                                                                                                                                                                                 \
135                 tcu::Vec4 load (glu::CallLogWrapper& gl, int index, const tcu::Vec4& v) const   \
136                 {                                                                                                                                                               \
137                         tcu::Vector<TYPE, COMPONENTS> value;                                                                            \
138                         value = convertToTypeVec<Type, COMPONENTS>(v);                                                          \
139                                                                                                                                                                                 \
140                         gl.glVertexAttrib ##COMPS ##TYPECODE (index, value.getPtr());                           \
141                         return convertToTypeVec<float, 4>(value);                                                                       \
142                 }                                                                                                                                                               \
143                                                                                                                                                                                 \
144                 static const char* getCaseName (void)                                                                                   \
145                 {                                                                                                                                                               \
146                         return CASENAME;                                                                                                                        \
147                 }                                                                                                                                                               \
148                                                                                                                                                                                 \
149                 static const char* getName (void)                                                                                               \
150                 {                                                                                                                                                               \
151                         return "VertexAttrib" #COMPS #TYPECODE;                                                                         \
152                 }                                                                                                                                                               \
153         }
154
155 #define GEN_DIRECT_INTEGER_LOADER(TYPE, COMPS, TYPECODE, CASENAME, VALUES)                              \
156         class LoaderVertexAttribI##COMPS##TYPECODE : public FloatLoader                                         \
157         {                                                                                                                                                                       \
158         public:                                                                                                                                                         \
159                 enum                                                                                                                                                    \
160                 {                                                                                                                                                               \
161                         NORMALIZING = 0,                                                                                                                        \
162                 };                                                                                                                                                              \
163                 enum                                                                                                                                                    \
164                 {                                                                                                                                                               \
165                         COMPONENTS = (COMPS)                                                                                                            \
166                 };                                                                                                                                                              \
167                 typedef TYPE Type;                                                                                                                              \
168                                                                                                                                                                                 \
169                 tcu::Vec4 load (glu::CallLogWrapper& gl, int index, const tcu::Vec4& v) const   \
170                 {                                                                                                                                                               \
171                         tcu::Vector<TYPE, COMPONENTS> value;                                                                            \
172                         value = convertToTypeVec<Type, COMPONENTS>(v);                                                          \
173                                                                                                                                                                                 \
174                         gl.glVertexAttribI ##COMPS ##TYPECODE VALUES;                                                           \
175                         return convertToTypeVec<float, 4>(value);                                                                       \
176                 }                                                                                                                                                               \
177                                                                                                                                                                                 \
178                 static const char* getCaseName (void)                                                                                   \
179                 {                                                                                                                                                               \
180                         return CASENAME;                                                                                                                        \
181                 }                                                                                                                                                               \
182                                                                                                                                                                                 \
183                 static const char* getName (void)                                                                                               \
184                 {                                                                                                                                                               \
185                         return "VertexAttrib" #COMPS #TYPECODE;                                                                         \
186                 }                                                                                                                                                               \
187         }
188
189 #define GEN_INDIRECT_INTEGER_LOADER(TYPE, COMPS, TYPECODE, CASENAME)                                    \
190         class LoaderVertexAttribI##COMPS##TYPECODE : public FloatLoader                                         \
191         {                                                                                                                                                                       \
192         public:                                                                                                                                                         \
193                 enum                                                                                                                                                    \
194                 {                                                                                                                                                               \
195                         NORMALIZING = 0,                                                                                                                        \
196                 };                                                                                                                                                              \
197                 enum                                                                                                                                                    \
198                 {                                                                                                                                                               \
199                         COMPONENTS = (COMPS)                                                                                                            \
200                 };                                                                                                                                                              \
201                 typedef TYPE Type;                                                                                                                              \
202                                                                                                                                                                                 \
203                 tcu::Vec4 load (glu::CallLogWrapper& gl, int index, const tcu::Vec4& v) const   \
204                 {                                                                                                                                                               \
205                         tcu::Vector<TYPE, COMPONENTS> value;                                                                            \
206                         value = convertToTypeVec<Type, COMPONENTS>(v);                                                          \
207                                                                                                                                                                                 \
208                         gl.glVertexAttribI ##COMPS ##TYPECODE (index, value.getPtr());                          \
209                         return convertToTypeVec<float, 4>(value);                                                                       \
210                 }                                                                                                                                                               \
211                                                                                                                                                                                 \
212                 static const char* getCaseName (void)                                                                                   \
213                 {                                                                                                                                                               \
214                         return CASENAME;                                                                                                                        \
215                 }                                                                                                                                                               \
216                                                                                                                                                                                 \
217                 static const char* getName (void)                                                                                               \
218                 {                                                                                                                                                               \
219                         return "VertexAttrib" #COMPS #TYPECODE;                                                                         \
220                 }                                                                                                                                                               \
221         }
222
223 GEN_DIRECT_FLOAT_LOADER(float, 1, f, "vertex_attrib_1f", (index, value.x()));
224 GEN_DIRECT_FLOAT_LOADER(float, 2, f, "vertex_attrib_2f", (index, value.x(), value.y()));
225 GEN_DIRECT_FLOAT_LOADER(float, 3, f, "vertex_attrib_3f", (index, value.x(), value.y(), value.z()));
226 GEN_DIRECT_FLOAT_LOADER(float, 4, f, "vertex_attrib_4f", (index, value.x(), value.y(), value.z(), value.w()));
227
228 GEN_INDIRECT_FLOAT_LOADER(float, 1, fv, "vertex_attrib_1fv");
229 GEN_INDIRECT_FLOAT_LOADER(float, 2, fv, "vertex_attrib_2fv");
230 GEN_INDIRECT_FLOAT_LOADER(float, 3, fv, "vertex_attrib_3fv");
231 GEN_INDIRECT_FLOAT_LOADER(float, 4, fv, "vertex_attrib_4fv");
232
233 GEN_DIRECT_INTEGER_LOADER(deInt32, 4, i, "vertex_attribi_4i", (index, value.x(), value.y(), value.z(), value.w()));
234 GEN_INDIRECT_INTEGER_LOADER(deInt32, 4, iv, "vertex_attribi_4iv");
235
236 GEN_DIRECT_INTEGER_LOADER(deUint32, 4, ui, "vertex_attribi_4ui", (index, value.x(), value.y(), value.z(), value.w()));
237 GEN_INDIRECT_INTEGER_LOADER(deUint32, 4, uiv, "vertex_attribi_4uiv");
238
239 class AttributeCase : public TestCase
240 {
241                                                                         AttributeCase                   (Context& ctx, const char* name, const char* desc, const char* funcName, bool normalizing, bool useNegative, glu::DataType dataType);
242 public:
243         template<typename LoaderType>
244         static AttributeCase*                   create                                  (Context& ctx, glu::DataType dataType);
245                                                                         ~AttributeCase                  (void);
246
247 private:
248         void                                                    init                                    (void);
249         void                                                    deinit                                  (void);
250         IterateResult                                   iterate                                 (void);
251
252         glu::DataType                                   getTargetType                   (void) const;
253         std::string                                             genVertexSource                 (void) const;
254         bool                                                    renderWithValue                 (const tcu::Vec4& v);
255         tcu::Vec4                                               computeColor                    (const tcu::Vec4& value);
256         bool                                                    verifyUnicoloredBuffer  (const tcu::Surface& scene, const tcu::Vec4& refValue);
257
258         const bool                                              m_normalizing;
259         const bool                                              m_useNegativeValues;
260         const char* const                               m_funcName;
261         const glu::DataType                             m_dataType;
262         const FloatLoader*                              m_loader;
263         glu::ShaderProgram*                             m_program;
264         deUint32                                                m_bufID;
265         bool                                                    m_allIterationsPassed;
266         int                                                             m_iteration;
267
268         enum
269         {
270                 RENDER_SIZE = 32
271         };
272 };
273
274 AttributeCase::AttributeCase (Context& ctx, const char* name, const char* desc, const char* funcName, bool normalizing, bool useNegative, glu::DataType dataType)
275         : TestCase                              (ctx, name, desc)
276         , m_normalizing                 (normalizing)
277         , m_useNegativeValues   (useNegative)
278         , m_funcName                    (funcName)
279         , m_dataType                    (dataType)
280         , m_loader                              (DE_NULL)
281         , m_program                             (DE_NULL)
282         , m_bufID                               (0)
283         , m_allIterationsPassed (true)
284         , m_iteration                   (0)
285 {
286 }
287
288 template<typename LoaderType>
289 AttributeCase* AttributeCase::create (Context& ctx, glu::DataType dataType)
290 {
291         AttributeCase* retVal = new AttributeCase(ctx,
292                                                                                           LoaderType::getCaseName(),
293                                                                                           (std::string("Test ") + LoaderType::getName()).c_str(),
294                                                                                           LoaderType::getName(),
295                                                                                           LoaderType::NORMALIZING != 0,
296                                                                                           std::numeric_limits<typename LoaderType::Type>::is_signed,
297                                                                                           dataType);
298         retVal->m_loader = new LoaderType();
299         return retVal;
300 }
301
302 AttributeCase::~AttributeCase (void)
303 {
304         deinit();
305 }
306
307 void AttributeCase::init (void)
308 {
309         if (m_context.getRenderTarget().getWidth() < RENDER_SIZE || m_context.getRenderTarget().getHeight() < RENDER_SIZE)
310                 throw tcu::NotSupportedError("Render target must be at least " + de::toString<int>(RENDER_SIZE) + "x" + de::toString<int>(RENDER_SIZE));
311
312         // log test info
313
314         {
315                 const float                     maxRange                = (m_normalizing) ? (1.0f) : (s_valueRange);
316                 const float                     minRange                = (m_useNegativeValues) ? (-maxRange) : (0.0f);
317
318                 m_testCtx.getLog()
319                         << tcu::TestLog::Message
320                         << "Loading attribute values using " << m_funcName << "\n"
321                         << "Attribute type: " << glu::getDataTypeName(m_dataType) << "\n"
322                         << "Attribute value range: [" << minRange << ", " << maxRange << "]"
323                         << tcu::TestLog::EndMessage;
324         }
325
326         // gen shader and base quad
327
328         m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(genVertexSource()) << glu::FragmentSource(s_passThroughFragmentShaderSource));
329         m_testCtx.getLog() << *m_program;
330         if (!m_program->isOk())
331                 throw tcu::TestError("could not build program");
332
333         {
334                 const tcu::Vec4 fullscreenQuad[] =
335                 {
336                         tcu::Vec4( 1.0f,  1.0f, 0.0f, 1.0f),
337                         tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f),
338                         tcu::Vec4(-1.0f,  1.0f, 0.0f, 1.0f),
339                         tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
340                 };
341
342                 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
343
344                 gl.genBuffers(1, &m_bufID);
345                 gl.bindBuffer(GL_ARRAY_BUFFER, m_bufID);
346                 gl.bufferData(GL_ARRAY_BUFFER, sizeof(fullscreenQuad), fullscreenQuad, GL_STATIC_DRAW);
347                 GLU_EXPECT_NO_ERROR(gl.getError(), "fill buffer");
348         }
349 }
350
351 void AttributeCase::deinit (void)
352 {
353         delete m_loader;
354         m_loader = DE_NULL;
355
356         delete m_program;
357         m_program = DE_NULL;
358
359         if (m_bufID)
360         {
361                 m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_bufID);
362                 m_bufID = 0;
363         }
364 }
365
366 AttributeCase::IterateResult AttributeCase::iterate (void)
367 {
368         static const tcu::Vec4 testValues[] =
369         {
370                 tcu::Vec4(0.0f, 0.5f, 0.2f, 1.0f),
371                 tcu::Vec4(0.1f, 0.7f, 1.0f, 0.6f),
372                 tcu::Vec4(0.4f, 0.2f, 0.0f, 0.5f),
373                 tcu::Vec4(0.5f, 0.0f, 0.9f, 0.1f),
374                 tcu::Vec4(0.6f, 0.2f, 0.2f, 0.9f),
375                 tcu::Vec4(0.9f, 1.0f, 0.0f, 0.0f),
376                 tcu::Vec4(1.0f, 0.5f, 0.3f, 0.8f),
377         };
378
379         const tcu::ScopedLogSection section(m_testCtx.getLog(), "Iteration", "Iteration " + de::toString(m_iteration+1) + "/" + de::toString(DE_LENGTH_OF_ARRAY(testValues)));
380
381         // Test normalizing transfers with whole range, non-normalizing with up to s_valueRange
382         const tcu::Vec4 testValue = ((m_useNegativeValues) ? (testValues[m_iteration] * 2.0f - tcu::Vec4(1.0f)) : (testValues[m_iteration])) * ((m_normalizing) ? (1.0f) : ((float)s_valueRange));
383
384         if (!renderWithValue(testValue))
385                 m_allIterationsPassed = false;
386
387         // continue
388
389         if (++m_iteration < DE_LENGTH_OF_ARRAY(testValues))
390                 return CONTINUE;
391
392         if (m_allIterationsPassed)
393                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
394         else
395                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got unexpected values");
396
397         return STOP;
398 }
399
400 std::string AttributeCase::genVertexSource (void) const
401 {
402         const int                       vectorSize      = (glu::isDataTypeMatrix(m_dataType)) ? (glu::getDataTypeMatrixNumRows(m_dataType)) : (glu::isDataTypeVector(m_dataType)) ? (glu::getDataTypeScalarSize(m_dataType)) : (-1);
403         const char* const       vectorType      = glu::getDataTypeName((glu::isDataTypeMatrix(m_dataType)) ? (glu::getDataTypeVector(glu::TYPE_FLOAT, vectorSize)) : (glu::isDataTypeVector(m_dataType)) ? (glu::getDataTypeVector(glu::TYPE_FLOAT, vectorSize)) : (glu::TYPE_FLOAT));
404         const int                       components      = (glu::isDataTypeMatrix(m_dataType)) ? (glu::getDataTypeMatrixNumRows(m_dataType)) : (glu::getDataTypeScalarSize(m_dataType));
405         std::ostringstream      buf;
406
407         buf <<  "#version 300 es\n"
408                         "in highp vec4 a_position;\n"
409                         "in highp " << glu::getDataTypeName(m_dataType) << " a_value;\n"
410                         "out highp vec4 v_color;\n"
411                         "void main (void)\n"
412                         "{\n"
413                         "       gl_Position = a_position;\n"
414                         "\n";
415
416         if (m_normalizing)
417                 buf << "        highp " << vectorType << " normalizedValue = " << ((glu::getDataTypeScalarType(m_dataType) == glu::TYPE_FLOAT) ? ("") : (vectorType)) << "(a_value" << ((glu::isDataTypeMatrix(m_dataType)) ? ("[1]") : ("")) << ");\n";
418         else
419                 buf << "        highp " << vectorType << " normalizedValue = " << ((glu::getDataTypeScalarType(m_dataType) == glu::TYPE_FLOAT) ? ("") : (vectorType)) << "(a_value" << ((glu::isDataTypeMatrix(m_dataType)) ? ("[1]") : ("")) << ") / float(" << s_valueRange << ");\n";
420
421         if (m_useNegativeValues)
422                 buf << "        highp " << vectorType << " positiveNormalizedValue = (normalizedValue + " << vectorType << "(1.0)) / 2.0;\n";
423         else
424                 buf << "        highp " << vectorType << " positiveNormalizedValue = normalizedValue;\n";
425
426         if (components == 1)
427                 buf << "        v_color = vec4(positiveNormalizedValue, 0.0, 0.0, 1.0);\n";
428         else if (components == 2)
429                 buf << "        v_color = vec4(positiveNormalizedValue.xy, 0.0, 1.0);\n";
430         else if (components == 3)
431                 buf << "        v_color = vec4(positiveNormalizedValue.xyz, 1.0);\n";
432         else if (components == 4)
433                 buf << "        v_color = vec4((positiveNormalizedValue.xy + positiveNormalizedValue.zz) / 2.0, positiveNormalizedValue.w, 1.0);\n";
434         else
435                 DE_ASSERT(DE_FALSE);
436
437         buf << "}\n";
438
439         return buf.str();
440 }
441
442 bool AttributeCase::renderWithValue (const tcu::Vec4& v)
443 {
444         glu::CallLogWrapper     gl                              (m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
445
446         gl.enableLogging(true);
447
448         const int                       positionIndex   = gl.glGetAttribLocation(m_program->getProgram(), "a_position");
449         const int                       valueIndex              = gl.glGetAttribLocation(m_program->getProgram(), "a_value");
450         tcu::Surface            dest                    (RENDER_SIZE, RENDER_SIZE);
451         tcu::Vec4                       loadedValue;
452
453         gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
454         gl.glClear(GL_COLOR_BUFFER_BIT);
455         gl.glViewport(0, 0, RENDER_SIZE, RENDER_SIZE);
456         GLU_EXPECT_NO_ERROR(gl.glGetError(), "setup");
457
458         gl.glBindBuffer(GL_ARRAY_BUFFER, m_bufID);
459         gl.glVertexAttribPointer(positionIndex, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
460         gl.glEnableVertexAttribArray(positionIndex);
461         GLU_EXPECT_NO_ERROR(gl.glGetError(), "position va");
462
463         // transfer test value. Load to the second column in the matrix case
464         loadedValue = m_loader->load(gl, (glu::isDataTypeMatrix(m_dataType)) ? (valueIndex + 1) : (valueIndex), v);
465         GLU_EXPECT_NO_ERROR(gl.glGetError(), "default va");
466
467         gl.glUseProgram(m_program->getProgram());
468         gl.glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
469         gl.glUseProgram(0);
470         GLU_EXPECT_NO_ERROR(gl.glGetError(), "draw");
471
472         glu::readPixels(m_context.getRenderContext(), 0, 0, dest.getAccess());
473
474         // check whole result is colored correctly
475         return verifyUnicoloredBuffer(dest, computeColor(loadedValue));
476 }
477
478 tcu::Vec4 AttributeCase::computeColor (const tcu::Vec4& value)
479 {
480         const tcu::Vec4 normalizedValue                 = value / ((m_normalizing) ? (1.0f) : ((float)s_valueRange));
481         const tcu::Vec4 positiveNormalizedValue = ((m_useNegativeValues) ? ((normalizedValue + tcu::Vec4(1.0f)) / 2.0f) : (normalizedValue));
482         const int               components                              = (glu::isDataTypeMatrix(m_dataType)) ? (glu::getDataTypeMatrixNumRows(m_dataType)) : (glu::getDataTypeScalarSize(m_dataType));
483
484         if (components == 1)
485                 return tcu::Vec4(positiveNormalizedValue.x(), 0.0f, 0.0f, 1.0f);
486         else if (components == 2)
487                 return tcu::Vec4(positiveNormalizedValue.x(), positiveNormalizedValue.y(), 0.0f, 1.0f);
488         else if (components == 3)
489                 return tcu::Vec4(positiveNormalizedValue.x(), positiveNormalizedValue.y(), positiveNormalizedValue.z(), 1.0f);
490         else if (components == 4)
491                 return tcu::Vec4((positiveNormalizedValue.x() + positiveNormalizedValue.z()) / 2.0f, (positiveNormalizedValue.y() + positiveNormalizedValue.z()) / 2.0f, positiveNormalizedValue.w(), 1.0f);
492         else
493                 DE_ASSERT(DE_FALSE);
494
495         return tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
496 }
497
498 bool AttributeCase::verifyUnicoloredBuffer (const tcu::Surface& scene, const tcu::Vec4& refValue)
499 {
500         tcu::Surface    errorMask               (RENDER_SIZE, RENDER_SIZE);
501         const tcu::RGBA refColor                (refValue);
502         const int               resultThreshold = 2;
503         const tcu::RGBA colorThreshold  = m_context.getRenderTarget().getPixelFormat().getColorThreshold() * resultThreshold;
504         bool                    error                   = false;
505
506         tcu::RGBA               exampleColor;
507         tcu::IVec2              examplePos;
508
509         tcu::clear(errorMask.getAccess(), tcu::RGBA::green().toIVec());
510
511         m_testCtx.getLog() << tcu::TestLog::Message << "Verifying rendered image. Expecting color " << refColor << ", threshold " << colorThreshold << tcu::TestLog::EndMessage;
512
513         for (int y = 0; y < RENDER_SIZE; ++y)
514         for (int x = 0; x < RENDER_SIZE; ++x)
515         {
516                 const tcu::RGBA color = scene.getPixel(x, y);
517
518                 if (de::abs(color.getRed()   - refColor.getRed())   > colorThreshold.getRed()   ||
519                         de::abs(color.getGreen() - refColor.getGreen()) > colorThreshold.getGreen() ||
520                         de::abs(color.getBlue()  - refColor.getBlue())  > colorThreshold.getBlue())
521                 {
522                         // first error
523                         if (!error)
524                         {
525                                 exampleColor = color;
526                                 examplePos = tcu::IVec2(x, y);
527                         }
528
529                         error = true;
530                         errorMask.setPixel(x, y, tcu::RGBA::red());
531                 }
532         }
533
534         if (!error)
535                 m_testCtx.getLog() << tcu::TestLog::Message << "Rendered image is valid." << tcu::TestLog::EndMessage;
536         else
537         {
538                 m_testCtx.getLog()      << tcu::TestLog::Message
539                                                         << "Found invalid pixel(s).\n"
540                                                         << "Pixel at (" << examplePos.x() << ", " << examplePos.y() << ") color: " << exampleColor
541                                                         << tcu::TestLog::EndMessage
542                                                         << tcu::TestLog::ImageSet("Result", "Render result")
543                                                         << tcu::TestLog::Image("Result", "Result", scene)
544                                                         << tcu::TestLog::Image("ErrorMask", "Error Mask", errorMask)
545                                                         << tcu::TestLog::EndImageSet;
546         }
547
548         return !error;
549 }
550
551 } // anonymous
552
553 DefaultVertexAttributeTests::DefaultVertexAttributeTests (Context& context)
554         : TestCaseGroup(context, "default_vertex_attrib", "Test default vertex attributes")
555 {
556 }
557
558 DefaultVertexAttributeTests::~DefaultVertexAttributeTests (void)
559 {
560 }
561
562 void DefaultVertexAttributeTests::init (void)
563 {
564         struct Target
565         {
566                 const char*             name;
567                 glu::DataType   dataType;
568                 bool                    reducedTestSets;        // !< use reduced coverage
569         };
570
571         static const Target floatTargets[] =
572         {
573                 { "float",      glu::TYPE_FLOAT,                false   },
574                 { "vec2",       glu::TYPE_FLOAT_VEC2,   true    },
575                 { "vec3",       glu::TYPE_FLOAT_VEC3,   true    },
576                 { "vec4",       glu::TYPE_FLOAT_VEC4,   false   },
577                 { "mat2",       glu::TYPE_FLOAT_MAT2,   true    },
578                 { "mat2x3",     glu::TYPE_FLOAT_MAT2X3, true    },
579                 { "mat2x4",     glu::TYPE_FLOAT_MAT2X4, true    },
580                 { "mat3",       glu::TYPE_FLOAT_MAT3,   true    },
581                 { "mat3x2",     glu::TYPE_FLOAT_MAT3X2, true    },
582                 { "mat3x4",     glu::TYPE_FLOAT_MAT3X4, true    },
583                 { "mat4",       glu::TYPE_FLOAT_MAT4,   false   },
584                 { "mat4x2",     glu::TYPE_FLOAT_MAT4X2, true    },
585                 { "mat4x3",     glu::TYPE_FLOAT_MAT4X3, true    },
586         };
587
588         static const Target intTargets[] =
589         {
590                 { "int",        glu::TYPE_INT,                  false   },
591                 { "ivec2",      glu::TYPE_INT_VEC2,             true    },
592                 { "ivec3",      glu::TYPE_INT_VEC3,             true    },
593                 { "ivec4",      glu::TYPE_INT_VEC4,             false   },
594         };
595
596         static const Target uintTargets[] =
597         {
598                 { "uint",       glu::TYPE_UINT,                 false   },
599                 { "uvec2",      glu::TYPE_UINT_VEC2,    true    },
600                 { "uvec3",      glu::TYPE_UINT_VEC3,    true    },
601                 { "uvec4",      glu::TYPE_UINT_VEC4,    false   },
602         };
603
604         // float targets
605
606         for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(floatTargets); ++targetNdx)
607         {
608                 tcu::TestCaseGroup* const       group   = new tcu::TestCaseGroup(m_testCtx, floatTargets[targetNdx].name, (std::string("test with ") + floatTargets[targetNdx].name).c_str());
609                 const bool                                      fullSet = !floatTargets[targetNdx].reducedTestSets;
610
611 #define ADD_CASE(X) group->addChild(AttributeCase::create<X>(m_context, floatTargets[targetNdx].dataType))
612 #define ADD_REDUCED_CASE(X)     if (fullSet) ADD_CASE(X)
613
614                 ADD_CASE                (LoaderVertexAttrib1f);
615                 ADD_REDUCED_CASE(LoaderVertexAttrib2f);
616                 ADD_REDUCED_CASE(LoaderVertexAttrib3f);
617                 ADD_CASE                (LoaderVertexAttrib4f);
618
619                 ADD_CASE                (LoaderVertexAttrib1fv);
620                 ADD_REDUCED_CASE(LoaderVertexAttrib2fv);
621                 ADD_REDUCED_CASE(LoaderVertexAttrib3fv);
622                 ADD_CASE                (LoaderVertexAttrib4fv);
623
624 #undef ADD_CASE
625 #undef ADD_REDUCED_CASE
626
627                 addChild(group);
628         }
629
630         // int targets
631
632         for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(intTargets); ++targetNdx)
633         {
634                 tcu::TestCaseGroup* const       group   = new tcu::TestCaseGroup(m_testCtx, intTargets[targetNdx].name, (std::string("test with ") + intTargets[targetNdx].name).c_str());
635
636 #define ADD_CASE(X) group->addChild(AttributeCase::create<X>(m_context, intTargets[targetNdx].dataType))
637
638                 ADD_CASE                (LoaderVertexAttribI4i);
639                 ADD_CASE                (LoaderVertexAttribI4iv);
640
641 #undef ADD_CASE
642
643                 addChild(group);
644         }
645
646         // uint targets
647
648         for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(uintTargets); ++targetNdx)
649         {
650                 tcu::TestCaseGroup* const       group   = new tcu::TestCaseGroup(m_testCtx, uintTargets[targetNdx].name, (std::string("test with ") + uintTargets[targetNdx].name).c_str());
651
652 #define ADD_CASE(X) group->addChild(AttributeCase::create<X>(m_context, uintTargets[targetNdx].dataType))
653
654                 ADD_CASE                (LoaderVertexAttribI4ui);
655                 ADD_CASE                (LoaderVertexAttribI4uiv);
656
657 #undef ADD_CASE
658
659                 addChild(group);
660         }
661 }
662
663 } // Functional
664 } // gles3
665 } // deqp