xref: /aosp_15_r20/external/deqp/modules/glshared/glsDrawTest.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program OpenGL (ES) 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 Draw tests
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "glsDrawTest.hpp"
25*35238bceSAndroid Build Coastguard Worker 
26*35238bceSAndroid Build Coastguard Worker #include "deRandom.h"
27*35238bceSAndroid Build Coastguard Worker #include "deRandom.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "deMath.h"
29*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "deFloat16.h"
31*35238bceSAndroid Build Coastguard Worker #include "deUniquePtr.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "deArrayUtil.hpp"
33*35238bceSAndroid Build Coastguard Worker 
34*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "tcuPixelFormat.hpp"
36*35238bceSAndroid Build Coastguard Worker #include "tcuRGBA.hpp"
37*35238bceSAndroid Build Coastguard Worker #include "tcuSurface.hpp"
38*35238bceSAndroid Build Coastguard Worker #include "tcuVector.hpp"
39*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
40*35238bceSAndroid Build Coastguard Worker #include "tcuRenderTarget.hpp"
41*35238bceSAndroid Build Coastguard Worker #include "tcuStringTemplate.hpp"
42*35238bceSAndroid Build Coastguard Worker #include "tcuImageCompare.hpp"
43*35238bceSAndroid Build Coastguard Worker #include "tcuFloat.hpp"
44*35238bceSAndroid Build Coastguard Worker #include "tcuTextureUtil.hpp"
45*35238bceSAndroid Build Coastguard Worker 
46*35238bceSAndroid Build Coastguard Worker #include "gluContextInfo.hpp"
47*35238bceSAndroid Build Coastguard Worker #include "gluPixelTransfer.hpp"
48*35238bceSAndroid Build Coastguard Worker #include "gluCallLogWrapper.hpp"
49*35238bceSAndroid Build Coastguard Worker 
50*35238bceSAndroid Build Coastguard Worker #include "sglrContext.hpp"
51*35238bceSAndroid Build Coastguard Worker #include "sglrReferenceContext.hpp"
52*35238bceSAndroid Build Coastguard Worker #include "sglrGLContext.hpp"
53*35238bceSAndroid Build Coastguard Worker 
54*35238bceSAndroid Build Coastguard Worker #include "rrGenericVector.hpp"
55*35238bceSAndroid Build Coastguard Worker 
56*35238bceSAndroid Build Coastguard Worker #include <cstring>
57*35238bceSAndroid Build Coastguard Worker #include <cmath>
58*35238bceSAndroid Build Coastguard Worker #include <vector>
59*35238bceSAndroid Build Coastguard Worker #include <sstream>
60*35238bceSAndroid Build Coastguard Worker #include <limits>
61*35238bceSAndroid Build Coastguard Worker #include <cstdint>
62*35238bceSAndroid Build Coastguard Worker 
63*35238bceSAndroid Build Coastguard Worker #include "glwDefs.hpp"
64*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
65*35238bceSAndroid Build Coastguard Worker 
66*35238bceSAndroid Build Coastguard Worker namespace deqp
67*35238bceSAndroid Build Coastguard Worker {
68*35238bceSAndroid Build Coastguard Worker namespace gls
69*35238bceSAndroid Build Coastguard Worker {
70*35238bceSAndroid Build Coastguard Worker namespace
71*35238bceSAndroid Build Coastguard Worker {
72*35238bceSAndroid Build Coastguard Worker 
73*35238bceSAndroid Build Coastguard Worker using tcu::TestLog;
74*35238bceSAndroid Build Coastguard Worker using namespace glw; // GL types
75*35238bceSAndroid Build Coastguard Worker 
76*35238bceSAndroid Build Coastguard Worker const int MAX_RENDER_TARGET_SIZE = 512;
77*35238bceSAndroid Build Coastguard Worker 
78*35238bceSAndroid Build Coastguard Worker // Utils
79*35238bceSAndroid Build Coastguard Worker 
targetToGL(DrawTestSpec::Target target)80*35238bceSAndroid Build Coastguard Worker static GLenum targetToGL(DrawTestSpec::Target target)
81*35238bceSAndroid Build Coastguard Worker {
82*35238bceSAndroid Build Coastguard Worker     static const GLenum targets[] = {
83*35238bceSAndroid Build Coastguard Worker         GL_ELEMENT_ARRAY_BUFFER, // TARGET_ELEMENT_ARRAY = 0,
84*35238bceSAndroid Build Coastguard Worker         GL_ARRAY_BUFFER          // TARGET_ARRAY,
85*35238bceSAndroid Build Coastguard Worker     };
86*35238bceSAndroid Build Coastguard Worker 
87*35238bceSAndroid Build Coastguard Worker     return de::getSizedArrayElement<DrawTestSpec::TARGET_LAST>(targets, (int)target);
88*35238bceSAndroid Build Coastguard Worker }
89*35238bceSAndroid Build Coastguard Worker 
usageToGL(DrawTestSpec::Usage usage)90*35238bceSAndroid Build Coastguard Worker static GLenum usageToGL(DrawTestSpec::Usage usage)
91*35238bceSAndroid Build Coastguard Worker {
92*35238bceSAndroid Build Coastguard Worker     static const GLenum usages[] = {
93*35238bceSAndroid Build Coastguard Worker         GL_DYNAMIC_DRAW, // USAGE_DYNAMIC_DRAW = 0,
94*35238bceSAndroid Build Coastguard Worker         GL_STATIC_DRAW,  // USAGE_STATIC_DRAW,
95*35238bceSAndroid Build Coastguard Worker         GL_STREAM_DRAW,  // USAGE_STREAM_DRAW,
96*35238bceSAndroid Build Coastguard Worker 
97*35238bceSAndroid Build Coastguard Worker         GL_STREAM_READ, // USAGE_STREAM_READ,
98*35238bceSAndroid Build Coastguard Worker         GL_STREAM_COPY, // USAGE_STREAM_COPY,
99*35238bceSAndroid Build Coastguard Worker 
100*35238bceSAndroid Build Coastguard Worker         GL_STATIC_READ, // USAGE_STATIC_READ,
101*35238bceSAndroid Build Coastguard Worker         GL_STATIC_COPY, // USAGE_STATIC_COPY,
102*35238bceSAndroid Build Coastguard Worker 
103*35238bceSAndroid Build Coastguard Worker         GL_DYNAMIC_READ, // USAGE_DYNAMIC_READ,
104*35238bceSAndroid Build Coastguard Worker         GL_DYNAMIC_COPY  // USAGE_DYNAMIC_COPY,
105*35238bceSAndroid Build Coastguard Worker     };
106*35238bceSAndroid Build Coastguard Worker 
107*35238bceSAndroid Build Coastguard Worker     return de::getSizedArrayElement<DrawTestSpec::USAGE_LAST>(usages, (int)usage);
108*35238bceSAndroid Build Coastguard Worker }
109*35238bceSAndroid Build Coastguard Worker 
inputTypeToGL(DrawTestSpec::InputType type)110*35238bceSAndroid Build Coastguard Worker static GLenum inputTypeToGL(DrawTestSpec::InputType type)
111*35238bceSAndroid Build Coastguard Worker {
112*35238bceSAndroid Build Coastguard Worker     static const GLenum types[] = {
113*35238bceSAndroid Build Coastguard Worker         GL_FLOAT,          // INPUTTYPE_FLOAT = 0,
114*35238bceSAndroid Build Coastguard Worker         GL_FIXED,          // INPUTTYPE_FIXED,
115*35238bceSAndroid Build Coastguard Worker         GL_DOUBLE,         // INPUTTYPE_DOUBLE
116*35238bceSAndroid Build Coastguard Worker         GL_BYTE,           // INPUTTYPE_BYTE,
117*35238bceSAndroid Build Coastguard Worker         GL_SHORT,          // INPUTTYPE_SHORT,
118*35238bceSAndroid Build Coastguard Worker         GL_UNSIGNED_BYTE,  // INPUTTYPE_UNSIGNED_BYTE,
119*35238bceSAndroid Build Coastguard Worker         GL_UNSIGNED_SHORT, // INPUTTYPE_UNSIGNED_SHORT,
120*35238bceSAndroid Build Coastguard Worker 
121*35238bceSAndroid Build Coastguard Worker         GL_INT,                         // INPUTTYPE_INT,
122*35238bceSAndroid Build Coastguard Worker         GL_UNSIGNED_INT,                // INPUTTYPE_UNSIGNED_INT,
123*35238bceSAndroid Build Coastguard Worker         GL_HALF_FLOAT,                  // INPUTTYPE_HALF,
124*35238bceSAndroid Build Coastguard Worker         GL_UNSIGNED_INT_2_10_10_10_REV, // INPUTTYPE_UNSIGNED_INT_2_10_10_10,
125*35238bceSAndroid Build Coastguard Worker         GL_INT_2_10_10_10_REV           // INPUTTYPE_INT_2_10_10_10,
126*35238bceSAndroid Build Coastguard Worker     };
127*35238bceSAndroid Build Coastguard Worker 
128*35238bceSAndroid Build Coastguard Worker     return de::getSizedArrayElement<DrawTestSpec::INPUTTYPE_LAST>(types, (int)type);
129*35238bceSAndroid Build Coastguard Worker }
130*35238bceSAndroid Build Coastguard Worker 
outputTypeToGLType(DrawTestSpec::OutputType type)131*35238bceSAndroid Build Coastguard Worker static std::string outputTypeToGLType(DrawTestSpec::OutputType type)
132*35238bceSAndroid Build Coastguard Worker {
133*35238bceSAndroid Build Coastguard Worker     static const char *types[] = {
134*35238bceSAndroid Build Coastguard Worker         "float", // OUTPUTTYPE_FLOAT = 0,
135*35238bceSAndroid Build Coastguard Worker         "vec2",  // OUTPUTTYPE_VEC2,
136*35238bceSAndroid Build Coastguard Worker         "vec3",  // OUTPUTTYPE_VEC3,
137*35238bceSAndroid Build Coastguard Worker         "vec4",  // OUTPUTTYPE_VEC4,
138*35238bceSAndroid Build Coastguard Worker 
139*35238bceSAndroid Build Coastguard Worker         "int",  // OUTPUTTYPE_INT,
140*35238bceSAndroid Build Coastguard Worker         "uint", // OUTPUTTYPE_UINT,
141*35238bceSAndroid Build Coastguard Worker 
142*35238bceSAndroid Build Coastguard Worker         "ivec2", // OUTPUTTYPE_IVEC2,
143*35238bceSAndroid Build Coastguard Worker         "ivec3", // OUTPUTTYPE_IVEC3,
144*35238bceSAndroid Build Coastguard Worker         "ivec4", // OUTPUTTYPE_IVEC4,
145*35238bceSAndroid Build Coastguard Worker 
146*35238bceSAndroid Build Coastguard Worker         "uvec2", // OUTPUTTYPE_UVEC2,
147*35238bceSAndroid Build Coastguard Worker         "uvec3", // OUTPUTTYPE_UVEC3,
148*35238bceSAndroid Build Coastguard Worker         "uvec4", // OUTPUTTYPE_UVEC4,
149*35238bceSAndroid Build Coastguard Worker     };
150*35238bceSAndroid Build Coastguard Worker 
151*35238bceSAndroid Build Coastguard Worker     return de::getSizedArrayElement<DrawTestSpec::OUTPUTTYPE_LAST>(types, (int)type);
152*35238bceSAndroid Build Coastguard Worker }
153*35238bceSAndroid Build Coastguard Worker 
primitiveToGL(DrawTestSpec::Primitive primitive)154*35238bceSAndroid Build Coastguard Worker static GLenum primitiveToGL(DrawTestSpec::Primitive primitive)
155*35238bceSAndroid Build Coastguard Worker {
156*35238bceSAndroid Build Coastguard Worker     static const GLenum primitives[] = {
157*35238bceSAndroid Build Coastguard Worker         GL_POINTS,                   // PRIMITIVE_POINTS = 0,
158*35238bceSAndroid Build Coastguard Worker         GL_TRIANGLES,                // PRIMITIVE_TRIANGLES,
159*35238bceSAndroid Build Coastguard Worker         GL_TRIANGLE_FAN,             // PRIMITIVE_TRIANGLE_FAN,
160*35238bceSAndroid Build Coastguard Worker         GL_TRIANGLE_STRIP,           // PRIMITIVE_TRIANGLE_STRIP,
161*35238bceSAndroid Build Coastguard Worker         GL_LINES,                    // PRIMITIVE_LINES
162*35238bceSAndroid Build Coastguard Worker         GL_LINE_STRIP,               // PRIMITIVE_LINE_STRIP
163*35238bceSAndroid Build Coastguard Worker         GL_LINE_LOOP,                // PRIMITIVE_LINE_LOOP
164*35238bceSAndroid Build Coastguard Worker         GL_LINES_ADJACENCY,          // PRIMITIVE_LINES_ADJACENCY
165*35238bceSAndroid Build Coastguard Worker         GL_LINE_STRIP_ADJACENCY,     // PRIMITIVE_LINE_STRIP_ADJACENCY
166*35238bceSAndroid Build Coastguard Worker         GL_TRIANGLES_ADJACENCY,      // PRIMITIVE_TRIANGLES_ADJACENCY
167*35238bceSAndroid Build Coastguard Worker         GL_TRIANGLE_STRIP_ADJACENCY, // PRIMITIVE_TRIANGLE_STRIP_ADJACENCY
168*35238bceSAndroid Build Coastguard Worker     };
169*35238bceSAndroid Build Coastguard Worker 
170*35238bceSAndroid Build Coastguard Worker     return de::getSizedArrayElement<DrawTestSpec::PRIMITIVE_LAST>(primitives, (int)primitive);
171*35238bceSAndroid Build Coastguard Worker }
172*35238bceSAndroid Build Coastguard Worker 
indexTypeToGL(DrawTestSpec::IndexType indexType)173*35238bceSAndroid Build Coastguard Worker static uint32_t indexTypeToGL(DrawTestSpec::IndexType indexType)
174*35238bceSAndroid Build Coastguard Worker {
175*35238bceSAndroid Build Coastguard Worker     static const GLenum indexTypes[] = {
176*35238bceSAndroid Build Coastguard Worker         GL_UNSIGNED_BYTE,  // INDEXTYPE_BYTE = 0,
177*35238bceSAndroid Build Coastguard Worker         GL_UNSIGNED_SHORT, // INDEXTYPE_SHORT,
178*35238bceSAndroid Build Coastguard Worker         GL_UNSIGNED_INT,   // INDEXTYPE_INT,
179*35238bceSAndroid Build Coastguard Worker     };
180*35238bceSAndroid Build Coastguard Worker 
181*35238bceSAndroid Build Coastguard Worker     return de::getSizedArrayElement<DrawTestSpec::INDEXTYPE_LAST>(indexTypes, (int)indexType);
182*35238bceSAndroid Build Coastguard Worker }
183*35238bceSAndroid Build Coastguard Worker 
inputTypeIsFloatType(DrawTestSpec::InputType type)184*35238bceSAndroid Build Coastguard Worker static bool inputTypeIsFloatType(DrawTestSpec::InputType type)
185*35238bceSAndroid Build Coastguard Worker {
186*35238bceSAndroid Build Coastguard Worker     if (type == DrawTestSpec::INPUTTYPE_FLOAT)
187*35238bceSAndroid Build Coastguard Worker         return true;
188*35238bceSAndroid Build Coastguard Worker     if (type == DrawTestSpec::INPUTTYPE_FIXED)
189*35238bceSAndroid Build Coastguard Worker         return true;
190*35238bceSAndroid Build Coastguard Worker     if (type == DrawTestSpec::INPUTTYPE_HALF)
191*35238bceSAndroid Build Coastguard Worker         return true;
192*35238bceSAndroid Build Coastguard Worker     if (type == DrawTestSpec::INPUTTYPE_DOUBLE)
193*35238bceSAndroid Build Coastguard Worker         return true;
194*35238bceSAndroid Build Coastguard Worker     return false;
195*35238bceSAndroid Build Coastguard Worker }
196*35238bceSAndroid Build Coastguard Worker 
outputTypeIsFloatType(DrawTestSpec::OutputType type)197*35238bceSAndroid Build Coastguard Worker static bool outputTypeIsFloatType(DrawTestSpec::OutputType type)
198*35238bceSAndroid Build Coastguard Worker {
199*35238bceSAndroid Build Coastguard Worker     if (type == DrawTestSpec::OUTPUTTYPE_FLOAT || type == DrawTestSpec::OUTPUTTYPE_VEC2 ||
200*35238bceSAndroid Build Coastguard Worker         type == DrawTestSpec::OUTPUTTYPE_VEC3 || type == DrawTestSpec::OUTPUTTYPE_VEC4)
201*35238bceSAndroid Build Coastguard Worker         return true;
202*35238bceSAndroid Build Coastguard Worker 
203*35238bceSAndroid Build Coastguard Worker     return false;
204*35238bceSAndroid Build Coastguard Worker }
205*35238bceSAndroid Build Coastguard Worker 
outputTypeIsIntType(DrawTestSpec::OutputType type)206*35238bceSAndroid Build Coastguard Worker static bool outputTypeIsIntType(DrawTestSpec::OutputType type)
207*35238bceSAndroid Build Coastguard Worker {
208*35238bceSAndroid Build Coastguard Worker     if (type == DrawTestSpec::OUTPUTTYPE_INT || type == DrawTestSpec::OUTPUTTYPE_IVEC2 ||
209*35238bceSAndroid Build Coastguard Worker         type == DrawTestSpec::OUTPUTTYPE_IVEC3 || type == DrawTestSpec::OUTPUTTYPE_IVEC4)
210*35238bceSAndroid Build Coastguard Worker         return true;
211*35238bceSAndroid Build Coastguard Worker 
212*35238bceSAndroid Build Coastguard Worker     return false;
213*35238bceSAndroid Build Coastguard Worker }
214*35238bceSAndroid Build Coastguard Worker 
outputTypeIsUintType(DrawTestSpec::OutputType type)215*35238bceSAndroid Build Coastguard Worker static bool outputTypeIsUintType(DrawTestSpec::OutputType type)
216*35238bceSAndroid Build Coastguard Worker {
217*35238bceSAndroid Build Coastguard Worker     if (type == DrawTestSpec::OUTPUTTYPE_UINT || type == DrawTestSpec::OUTPUTTYPE_UVEC2 ||
218*35238bceSAndroid Build Coastguard Worker         type == DrawTestSpec::OUTPUTTYPE_UVEC3 || type == DrawTestSpec::OUTPUTTYPE_UVEC4)
219*35238bceSAndroid Build Coastguard Worker         return true;
220*35238bceSAndroid Build Coastguard Worker 
221*35238bceSAndroid Build Coastguard Worker     return false;
222*35238bceSAndroid Build Coastguard Worker }
223*35238bceSAndroid Build Coastguard Worker 
getElementCount(DrawTestSpec::Primitive primitive,size_t primitiveCount)224*35238bceSAndroid Build Coastguard Worker static size_t getElementCount(DrawTestSpec::Primitive primitive, size_t primitiveCount)
225*35238bceSAndroid Build Coastguard Worker {
226*35238bceSAndroid Build Coastguard Worker     switch (primitive)
227*35238bceSAndroid Build Coastguard Worker     {
228*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_POINTS:
229*35238bceSAndroid Build Coastguard Worker         return primitiveCount;
230*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_TRIANGLES:
231*35238bceSAndroid Build Coastguard Worker         return primitiveCount * 3;
232*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_TRIANGLE_FAN:
233*35238bceSAndroid Build Coastguard Worker         return primitiveCount + 2;
234*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP:
235*35238bceSAndroid Build Coastguard Worker         return primitiveCount + 2;
236*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_LINES:
237*35238bceSAndroid Build Coastguard Worker         return primitiveCount * 2;
238*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_LINE_STRIP:
239*35238bceSAndroid Build Coastguard Worker         return primitiveCount + 1;
240*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_LINE_LOOP:
241*35238bceSAndroid Build Coastguard Worker         return (primitiveCount == 1) ? (2) : (primitiveCount);
242*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_LINES_ADJACENCY:
243*35238bceSAndroid Build Coastguard Worker         return primitiveCount * 4;
244*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_LINE_STRIP_ADJACENCY:
245*35238bceSAndroid Build Coastguard Worker         return primitiveCount + 3;
246*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_TRIANGLES_ADJACENCY:
247*35238bceSAndroid Build Coastguard Worker         return primitiveCount * 6;
248*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP_ADJACENCY:
249*35238bceSAndroid Build Coastguard Worker         return primitiveCount * 2 + 4;
250*35238bceSAndroid Build Coastguard Worker     default:
251*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
252*35238bceSAndroid Build Coastguard Worker         return 0;
253*35238bceSAndroid Build Coastguard Worker     }
254*35238bceSAndroid Build Coastguard Worker }
255*35238bceSAndroid Build Coastguard Worker 
256*35238bceSAndroid Build Coastguard Worker struct MethodInfo
257*35238bceSAndroid Build Coastguard Worker {
258*35238bceSAndroid Build Coastguard Worker     bool indexed;
259*35238bceSAndroid Build Coastguard Worker     bool instanced;
260*35238bceSAndroid Build Coastguard Worker     bool ranged;
261*35238bceSAndroid Build Coastguard Worker     bool first;
262*35238bceSAndroid Build Coastguard Worker     bool baseVertex;
263*35238bceSAndroid Build Coastguard Worker     bool indirect;
264*35238bceSAndroid Build Coastguard Worker };
265*35238bceSAndroid Build Coastguard Worker 
getMethodInfo(gls::DrawTestSpec::DrawMethod method)266*35238bceSAndroid Build Coastguard Worker static MethodInfo getMethodInfo(gls::DrawTestSpec::DrawMethod method)
267*35238bceSAndroid Build Coastguard Worker {
268*35238bceSAndroid Build Coastguard Worker     static const MethodInfo infos[] = {
269*35238bceSAndroid Build Coastguard Worker         //    indexed        instanced    ranged        first        baseVertex    indirect
270*35238bceSAndroid Build Coastguard Worker         {false, false, false, true, false, false}, //!< DRAWMETHOD_DRAWARRAYS,
271*35238bceSAndroid Build Coastguard Worker         {false, true, false, true, false, false},  //!< DRAWMETHOD_DRAWARRAYS_INSTANCED,
272*35238bceSAndroid Build Coastguard Worker         {false, true, false, true, false, true},   //!< DRAWMETHOD_DRAWARRAYS_INDIRECT,
273*35238bceSAndroid Build Coastguard Worker         {true, false, false, false, false, false}, //!< DRAWMETHOD_DRAWELEMENTS,
274*35238bceSAndroid Build Coastguard Worker         {true, false, true, false, false, false},  //!< DRAWMETHOD_DRAWELEMENTS_RANGED,
275*35238bceSAndroid Build Coastguard Worker         {true, true, false, false, false, false},  //!< DRAWMETHOD_DRAWELEMENTS_INSTANCED,
276*35238bceSAndroid Build Coastguard Worker         {true, true, false, false, true, true},    //!< DRAWMETHOD_DRAWELEMENTS_INDIRECT,
277*35238bceSAndroid Build Coastguard Worker         {true, false, false, false, true, false},  //!< DRAWMETHOD_DRAWELEMENTS_BASEVERTEX,
278*35238bceSAndroid Build Coastguard Worker         {true, true, false, false, true, false},   //!< DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX,
279*35238bceSAndroid Build Coastguard Worker         {true, false, true, false, true, false},   //!< DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX,
280*35238bceSAndroid Build Coastguard Worker     };
281*35238bceSAndroid Build Coastguard Worker 
282*35238bceSAndroid Build Coastguard Worker     return de::getSizedArrayElement<DrawTestSpec::DRAWMETHOD_LAST>(infos, (int)method);
283*35238bceSAndroid Build Coastguard Worker }
284*35238bceSAndroid Build Coastguard Worker 
285*35238bceSAndroid Build Coastguard Worker template <class T>
alignmentSafeAssignment(char * dst,T val)286*35238bceSAndroid Build Coastguard Worker inline static void alignmentSafeAssignment(char *dst, T val)
287*35238bceSAndroid Build Coastguard Worker {
288*35238bceSAndroid Build Coastguard Worker     std::memcpy(dst, &val, sizeof(T));
289*35238bceSAndroid Build Coastguard Worker }
290*35238bceSAndroid Build Coastguard Worker 
checkSpecsShaderCompatible(const DrawTestSpec & a,const DrawTestSpec & b)291*35238bceSAndroid Build Coastguard Worker static bool checkSpecsShaderCompatible(const DrawTestSpec &a, const DrawTestSpec &b)
292*35238bceSAndroid Build Coastguard Worker {
293*35238bceSAndroid Build Coastguard Worker     // Only the attributes matter
294*35238bceSAndroid Build Coastguard Worker     if (a.attribs.size() != b.attribs.size())
295*35238bceSAndroid Build Coastguard Worker         return false;
296*35238bceSAndroid Build Coastguard Worker 
297*35238bceSAndroid Build Coastguard Worker     for (size_t ndx = 0; ndx < a.attribs.size(); ++ndx)
298*35238bceSAndroid Build Coastguard Worker     {
299*35238bceSAndroid Build Coastguard Worker         // Only the output type (== shader input type) matters and the usage in the shader.
300*35238bceSAndroid Build Coastguard Worker 
301*35238bceSAndroid Build Coastguard Worker         if (a.attribs[ndx].additionalPositionAttribute != b.attribs[ndx].additionalPositionAttribute)
302*35238bceSAndroid Build Coastguard Worker             return false;
303*35238bceSAndroid Build Coastguard Worker 
304*35238bceSAndroid Build Coastguard Worker         // component counts need not to match
305*35238bceSAndroid Build Coastguard Worker         if (outputTypeIsFloatType(a.attribs[ndx].outputType) && outputTypeIsFloatType(b.attribs[ndx].outputType))
306*35238bceSAndroid Build Coastguard Worker             continue;
307*35238bceSAndroid Build Coastguard Worker         if (outputTypeIsIntType(a.attribs[ndx].outputType) && outputTypeIsIntType(b.attribs[ndx].outputType))
308*35238bceSAndroid Build Coastguard Worker             continue;
309*35238bceSAndroid Build Coastguard Worker         if (outputTypeIsUintType(a.attribs[ndx].outputType) && outputTypeIsUintType(b.attribs[ndx].outputType))
310*35238bceSAndroid Build Coastguard Worker             continue;
311*35238bceSAndroid Build Coastguard Worker 
312*35238bceSAndroid Build Coastguard Worker         return false;
313*35238bceSAndroid Build Coastguard Worker     }
314*35238bceSAndroid Build Coastguard Worker 
315*35238bceSAndroid Build Coastguard Worker     return true;
316*35238bceSAndroid Build Coastguard Worker }
317*35238bceSAndroid Build Coastguard Worker 
318*35238bceSAndroid Build Coastguard Worker // generate random vectors in a way that does not depend on argument evaluation order
319*35238bceSAndroid Build Coastguard Worker 
generateRandomVec4(de::Random & random)320*35238bceSAndroid Build Coastguard Worker tcu::Vec4 generateRandomVec4(de::Random &random)
321*35238bceSAndroid Build Coastguard Worker {
322*35238bceSAndroid Build Coastguard Worker     tcu::Vec4 retVal;
323*35238bceSAndroid Build Coastguard Worker 
324*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < 4; ++i)
325*35238bceSAndroid Build Coastguard Worker         retVal[i] = random.getFloat();
326*35238bceSAndroid Build Coastguard Worker 
327*35238bceSAndroid Build Coastguard Worker     return retVal;
328*35238bceSAndroid Build Coastguard Worker }
329*35238bceSAndroid Build Coastguard Worker 
generateRandomIVec4(de::Random & random)330*35238bceSAndroid Build Coastguard Worker tcu::IVec4 generateRandomIVec4(de::Random &random)
331*35238bceSAndroid Build Coastguard Worker {
332*35238bceSAndroid Build Coastguard Worker     tcu::IVec4 retVal;
333*35238bceSAndroid Build Coastguard Worker 
334*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < 4; ++i)
335*35238bceSAndroid Build Coastguard Worker         retVal[i] = random.getUint32();
336*35238bceSAndroid Build Coastguard Worker 
337*35238bceSAndroid Build Coastguard Worker     return retVal;
338*35238bceSAndroid Build Coastguard Worker }
339*35238bceSAndroid Build Coastguard Worker 
generateRandomUVec4(de::Random & random)340*35238bceSAndroid Build Coastguard Worker tcu::UVec4 generateRandomUVec4(de::Random &random)
341*35238bceSAndroid Build Coastguard Worker {
342*35238bceSAndroid Build Coastguard Worker     tcu::UVec4 retVal;
343*35238bceSAndroid Build Coastguard Worker 
344*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < 4; ++i)
345*35238bceSAndroid Build Coastguard Worker         retVal[i] = random.getUint32();
346*35238bceSAndroid Build Coastguard Worker 
347*35238bceSAndroid Build Coastguard Worker     return retVal;
348*35238bceSAndroid Build Coastguard Worker }
349*35238bceSAndroid Build Coastguard Worker 
350*35238bceSAndroid Build Coastguard Worker // IterationLogSectionEmitter
351*35238bceSAndroid Build Coastguard Worker 
352*35238bceSAndroid Build Coastguard Worker class IterationLogSectionEmitter
353*35238bceSAndroid Build Coastguard Worker {
354*35238bceSAndroid Build Coastguard Worker public:
355*35238bceSAndroid Build Coastguard Worker     IterationLogSectionEmitter(tcu::TestLog &log, size_t testIteration, size_t testIterations,
356*35238bceSAndroid Build Coastguard Worker                                const std::string &description, bool enabled);
357*35238bceSAndroid Build Coastguard Worker     ~IterationLogSectionEmitter(void);
358*35238bceSAndroid Build Coastguard Worker 
359*35238bceSAndroid Build Coastguard Worker private:
360*35238bceSAndroid Build Coastguard Worker     IterationLogSectionEmitter(const IterationLogSectionEmitter &);            // delete
361*35238bceSAndroid Build Coastguard Worker     IterationLogSectionEmitter &operator=(const IterationLogSectionEmitter &); // delete
362*35238bceSAndroid Build Coastguard Worker 
363*35238bceSAndroid Build Coastguard Worker     tcu::TestLog &m_log;
364*35238bceSAndroid Build Coastguard Worker     bool m_enabled;
365*35238bceSAndroid Build Coastguard Worker };
366*35238bceSAndroid Build Coastguard Worker 
IterationLogSectionEmitter(tcu::TestLog & log,size_t testIteration,size_t testIterations,const std::string & description,bool enabled)367*35238bceSAndroid Build Coastguard Worker IterationLogSectionEmitter::IterationLogSectionEmitter(tcu::TestLog &log, size_t testIteration, size_t testIterations,
368*35238bceSAndroid Build Coastguard Worker                                                        const std::string &description, bool enabled)
369*35238bceSAndroid Build Coastguard Worker     : m_log(log)
370*35238bceSAndroid Build Coastguard Worker     , m_enabled(enabled)
371*35238bceSAndroid Build Coastguard Worker {
372*35238bceSAndroid Build Coastguard Worker     if (m_enabled)
373*35238bceSAndroid Build Coastguard Worker     {
374*35238bceSAndroid Build Coastguard Worker         std::ostringstream buf;
375*35238bceSAndroid Build Coastguard Worker         buf << "Iteration " << (testIteration + 1) << "/" << testIterations;
376*35238bceSAndroid Build Coastguard Worker 
377*35238bceSAndroid Build Coastguard Worker         if (!description.empty())
378*35238bceSAndroid Build Coastguard Worker             buf << " - " << description;
379*35238bceSAndroid Build Coastguard Worker 
380*35238bceSAndroid Build Coastguard Worker         m_log << tcu::TestLog::Section(buf.str(), buf.str());
381*35238bceSAndroid Build Coastguard Worker     }
382*35238bceSAndroid Build Coastguard Worker }
383*35238bceSAndroid Build Coastguard Worker 
~IterationLogSectionEmitter(void)384*35238bceSAndroid Build Coastguard Worker IterationLogSectionEmitter::~IterationLogSectionEmitter(void)
385*35238bceSAndroid Build Coastguard Worker {
386*35238bceSAndroid Build Coastguard Worker     if (m_enabled)
387*35238bceSAndroid Build Coastguard Worker         m_log << tcu::TestLog::EndSection;
388*35238bceSAndroid Build Coastguard Worker }
389*35238bceSAndroid Build Coastguard Worker 
390*35238bceSAndroid Build Coastguard Worker // GLValue
391*35238bceSAndroid Build Coastguard Worker 
392*35238bceSAndroid Build Coastguard Worker class GLValue
393*35238bceSAndroid Build Coastguard Worker {
394*35238bceSAndroid Build Coastguard Worker public:
395*35238bceSAndroid Build Coastguard Worker     template <class Type>
396*35238bceSAndroid Build Coastguard Worker     class WrappedType
397*35238bceSAndroid Build Coastguard Worker     {
398*35238bceSAndroid Build Coastguard Worker     public:
create(Type value)399*35238bceSAndroid Build Coastguard Worker         static WrappedType<Type> create(Type value)
400*35238bceSAndroid Build Coastguard Worker         {
401*35238bceSAndroid Build Coastguard Worker             WrappedType<Type> v;
402*35238bceSAndroid Build Coastguard Worker             v.m_value = value;
403*35238bceSAndroid Build Coastguard Worker             return v;
404*35238bceSAndroid Build Coastguard Worker         }
getValue(void) const405*35238bceSAndroid Build Coastguard Worker         inline Type getValue(void) const
406*35238bceSAndroid Build Coastguard Worker         {
407*35238bceSAndroid Build Coastguard Worker             return m_value;
408*35238bceSAndroid Build Coastguard Worker         }
409*35238bceSAndroid Build Coastguard Worker 
operator +(const WrappedType<Type> & other) const410*35238bceSAndroid Build Coastguard Worker         inline WrappedType<Type> operator+(const WrappedType<Type> &other) const
411*35238bceSAndroid Build Coastguard Worker         {
412*35238bceSAndroid Build Coastguard Worker             return WrappedType<Type>::create((Type)(m_value + other.getValue()));
413*35238bceSAndroid Build Coastguard Worker         }
operator *(const WrappedType<Type> & other) const414*35238bceSAndroid Build Coastguard Worker         inline WrappedType<Type> operator*(const WrappedType<Type> &other) const
415*35238bceSAndroid Build Coastguard Worker         {
416*35238bceSAndroid Build Coastguard Worker             return WrappedType<Type>::create((Type)(m_value * other.getValue()));
417*35238bceSAndroid Build Coastguard Worker         }
operator /(const WrappedType<Type> & other) const418*35238bceSAndroid Build Coastguard Worker         inline WrappedType<Type> operator/(const WrappedType<Type> &other) const
419*35238bceSAndroid Build Coastguard Worker         {
420*35238bceSAndroid Build Coastguard Worker             return WrappedType<Type>::create((Type)(m_value / other.getValue()));
421*35238bceSAndroid Build Coastguard Worker         }
operator -(const WrappedType<Type> & other) const422*35238bceSAndroid Build Coastguard Worker         inline WrappedType<Type> operator-(const WrappedType<Type> &other) const
423*35238bceSAndroid Build Coastguard Worker         {
424*35238bceSAndroid Build Coastguard Worker             return WrappedType<Type>::create((Type)(m_value - other.getValue()));
425*35238bceSAndroid Build Coastguard Worker         }
426*35238bceSAndroid Build Coastguard Worker 
operator +=(const WrappedType<Type> & other)427*35238bceSAndroid Build Coastguard Worker         inline WrappedType<Type> &operator+=(const WrappedType<Type> &other)
428*35238bceSAndroid Build Coastguard Worker         {
429*35238bceSAndroid Build Coastguard Worker             m_value += other.getValue();
430*35238bceSAndroid Build Coastguard Worker             return *this;
431*35238bceSAndroid Build Coastguard Worker         }
operator *=(const WrappedType<Type> & other)432*35238bceSAndroid Build Coastguard Worker         inline WrappedType<Type> &operator*=(const WrappedType<Type> &other)
433*35238bceSAndroid Build Coastguard Worker         {
434*35238bceSAndroid Build Coastguard Worker             m_value *= other.getValue();
435*35238bceSAndroid Build Coastguard Worker             return *this;
436*35238bceSAndroid Build Coastguard Worker         }
operator /=(const WrappedType<Type> & other)437*35238bceSAndroid Build Coastguard Worker         inline WrappedType<Type> &operator/=(const WrappedType<Type> &other)
438*35238bceSAndroid Build Coastguard Worker         {
439*35238bceSAndroid Build Coastguard Worker             m_value /= other.getValue();
440*35238bceSAndroid Build Coastguard Worker             return *this;
441*35238bceSAndroid Build Coastguard Worker         }
operator -=(const WrappedType<Type> & other)442*35238bceSAndroid Build Coastguard Worker         inline WrappedType<Type> &operator-=(const WrappedType<Type> &other)
443*35238bceSAndroid Build Coastguard Worker         {
444*35238bceSAndroid Build Coastguard Worker             m_value -= other.getValue();
445*35238bceSAndroid Build Coastguard Worker             return *this;
446*35238bceSAndroid Build Coastguard Worker         }
447*35238bceSAndroid Build Coastguard Worker 
operator ==(const WrappedType<Type> & other) const448*35238bceSAndroid Build Coastguard Worker         inline bool operator==(const WrappedType<Type> &other) const
449*35238bceSAndroid Build Coastguard Worker         {
450*35238bceSAndroid Build Coastguard Worker             return m_value == other.m_value;
451*35238bceSAndroid Build Coastguard Worker         }
operator !=(const WrappedType<Type> & other) const452*35238bceSAndroid Build Coastguard Worker         inline bool operator!=(const WrappedType<Type> &other) const
453*35238bceSAndroid Build Coastguard Worker         {
454*35238bceSAndroid Build Coastguard Worker             return m_value != other.m_value;
455*35238bceSAndroid Build Coastguard Worker         }
operator <(const WrappedType<Type> & other) const456*35238bceSAndroid Build Coastguard Worker         inline bool operator<(const WrappedType<Type> &other) const
457*35238bceSAndroid Build Coastguard Worker         {
458*35238bceSAndroid Build Coastguard Worker             return m_value < other.m_value;
459*35238bceSAndroid Build Coastguard Worker         }
operator >(const WrappedType<Type> & other) const460*35238bceSAndroid Build Coastguard Worker         inline bool operator>(const WrappedType<Type> &other) const
461*35238bceSAndroid Build Coastguard Worker         {
462*35238bceSAndroid Build Coastguard Worker             return m_value > other.m_value;
463*35238bceSAndroid Build Coastguard Worker         }
operator <=(const WrappedType<Type> & other) const464*35238bceSAndroid Build Coastguard Worker         inline bool operator<=(const WrappedType<Type> &other) const
465*35238bceSAndroid Build Coastguard Worker         {
466*35238bceSAndroid Build Coastguard Worker             return m_value <= other.m_value;
467*35238bceSAndroid Build Coastguard Worker         }
operator >=(const WrappedType<Type> & other) const468*35238bceSAndroid Build Coastguard Worker         inline bool operator>=(const WrappedType<Type> &other) const
469*35238bceSAndroid Build Coastguard Worker         {
470*35238bceSAndroid Build Coastguard Worker             return m_value >= other.m_value;
471*35238bceSAndroid Build Coastguard Worker         }
472*35238bceSAndroid Build Coastguard Worker 
operator Type(void) const473*35238bceSAndroid Build Coastguard Worker         inline operator Type(void) const
474*35238bceSAndroid Build Coastguard Worker         {
475*35238bceSAndroid Build Coastguard Worker             return m_value;
476*35238bceSAndroid Build Coastguard Worker         }
477*35238bceSAndroid Build Coastguard Worker         template <class T>
to(void) const478*35238bceSAndroid Build Coastguard Worker         inline T to(void) const
479*35238bceSAndroid Build Coastguard Worker         {
480*35238bceSAndroid Build Coastguard Worker             return (T)m_value;
481*35238bceSAndroid Build Coastguard Worker         }
482*35238bceSAndroid Build Coastguard Worker 
483*35238bceSAndroid Build Coastguard Worker     private:
484*35238bceSAndroid Build Coastguard Worker         Type m_value;
485*35238bceSAndroid Build Coastguard Worker     };
486*35238bceSAndroid Build Coastguard Worker 
487*35238bceSAndroid Build Coastguard Worker     typedef WrappedType<int16_t> Short;
488*35238bceSAndroid Build Coastguard Worker     typedef WrappedType<uint16_t> Ushort;
489*35238bceSAndroid Build Coastguard Worker 
490*35238bceSAndroid Build Coastguard Worker     typedef WrappedType<int8_t> Byte;
491*35238bceSAndroid Build Coastguard Worker     typedef WrappedType<uint8_t> Ubyte;
492*35238bceSAndroid Build Coastguard Worker 
493*35238bceSAndroid Build Coastguard Worker     typedef WrappedType<float> Float;
494*35238bceSAndroid Build Coastguard Worker     typedef WrappedType<double> Double;
495*35238bceSAndroid Build Coastguard Worker 
496*35238bceSAndroid Build Coastguard Worker     typedef WrappedType<uint32_t> Uint;
497*35238bceSAndroid Build Coastguard Worker 
498*35238bceSAndroid Build Coastguard Worker     // All operations are calculated using 64bit values to avoid signed integer overflow which is undefined.
499*35238bceSAndroid Build Coastguard Worker     class Int
500*35238bceSAndroid Build Coastguard Worker     {
501*35238bceSAndroid Build Coastguard Worker     public:
create(int32_t value)502*35238bceSAndroid Build Coastguard Worker         static Int create(int32_t value)
503*35238bceSAndroid Build Coastguard Worker         {
504*35238bceSAndroid Build Coastguard Worker             Int v;
505*35238bceSAndroid Build Coastguard Worker             v.m_value = value;
506*35238bceSAndroid Build Coastguard Worker             return v;
507*35238bceSAndroid Build Coastguard Worker         }
getValue(void) const508*35238bceSAndroid Build Coastguard Worker         inline int32_t getValue(void) const
509*35238bceSAndroid Build Coastguard Worker         {
510*35238bceSAndroid Build Coastguard Worker             return m_value;
511*35238bceSAndroid Build Coastguard Worker         }
512*35238bceSAndroid Build Coastguard Worker 
operator +(const Int & other) const513*35238bceSAndroid Build Coastguard Worker         inline Int operator+(const Int &other) const
514*35238bceSAndroid Build Coastguard Worker         {
515*35238bceSAndroid Build Coastguard Worker             return Int::create((int32_t)((int64_t)m_value + (int64_t)other.getValue()));
516*35238bceSAndroid Build Coastguard Worker         }
operator *(const Int & other) const517*35238bceSAndroid Build Coastguard Worker         inline Int operator*(const Int &other) const
518*35238bceSAndroid Build Coastguard Worker         {
519*35238bceSAndroid Build Coastguard Worker             return Int::create((int32_t)((int64_t)m_value * (int64_t)other.getValue()));
520*35238bceSAndroid Build Coastguard Worker         }
operator /(const Int & other) const521*35238bceSAndroid Build Coastguard Worker         inline Int operator/(const Int &other) const
522*35238bceSAndroid Build Coastguard Worker         {
523*35238bceSAndroid Build Coastguard Worker             return Int::create((int32_t)((int64_t)m_value / (int64_t)other.getValue()));
524*35238bceSAndroid Build Coastguard Worker         }
operator -(const Int & other) const525*35238bceSAndroid Build Coastguard Worker         inline Int operator-(const Int &other) const
526*35238bceSAndroid Build Coastguard Worker         {
527*35238bceSAndroid Build Coastguard Worker             return Int::create((int32_t)((int64_t)m_value - (int64_t)other.getValue()));
528*35238bceSAndroid Build Coastguard Worker         }
529*35238bceSAndroid Build Coastguard Worker 
operator +=(const Int & other)530*35238bceSAndroid Build Coastguard Worker         inline Int &operator+=(const Int &other)
531*35238bceSAndroid Build Coastguard Worker         {
532*35238bceSAndroid Build Coastguard Worker             m_value = (int32_t)((int64_t)m_value + (int64_t)other.getValue());
533*35238bceSAndroid Build Coastguard Worker             return *this;
534*35238bceSAndroid Build Coastguard Worker         }
operator *=(const Int & other)535*35238bceSAndroid Build Coastguard Worker         inline Int &operator*=(const Int &other)
536*35238bceSAndroid Build Coastguard Worker         {
537*35238bceSAndroid Build Coastguard Worker             m_value = (int32_t)((int64_t)m_value * (int64_t)other.getValue());
538*35238bceSAndroid Build Coastguard Worker             return *this;
539*35238bceSAndroid Build Coastguard Worker         }
operator /=(const Int & other)540*35238bceSAndroid Build Coastguard Worker         inline Int &operator/=(const Int &other)
541*35238bceSAndroid Build Coastguard Worker         {
542*35238bceSAndroid Build Coastguard Worker             m_value = (int32_t)((int64_t)m_value / (int64_t)other.getValue());
543*35238bceSAndroid Build Coastguard Worker             return *this;
544*35238bceSAndroid Build Coastguard Worker         }
operator -=(const Int & other)545*35238bceSAndroid Build Coastguard Worker         inline Int &operator-=(const Int &other)
546*35238bceSAndroid Build Coastguard Worker         {
547*35238bceSAndroid Build Coastguard Worker             m_value = (int32_t)((int64_t)m_value - (int64_t)other.getValue());
548*35238bceSAndroid Build Coastguard Worker             return *this;
549*35238bceSAndroid Build Coastguard Worker         }
550*35238bceSAndroid Build Coastguard Worker 
operator ==(const Int & other) const551*35238bceSAndroid Build Coastguard Worker         inline bool operator==(const Int &other) const
552*35238bceSAndroid Build Coastguard Worker         {
553*35238bceSAndroid Build Coastguard Worker             return m_value == other.m_value;
554*35238bceSAndroid Build Coastguard Worker         }
operator !=(const Int & other) const555*35238bceSAndroid Build Coastguard Worker         inline bool operator!=(const Int &other) const
556*35238bceSAndroid Build Coastguard Worker         {
557*35238bceSAndroid Build Coastguard Worker             return m_value != other.m_value;
558*35238bceSAndroid Build Coastguard Worker         }
operator <(const Int & other) const559*35238bceSAndroid Build Coastguard Worker         inline bool operator<(const Int &other) const
560*35238bceSAndroid Build Coastguard Worker         {
561*35238bceSAndroid Build Coastguard Worker             return m_value < other.m_value;
562*35238bceSAndroid Build Coastguard Worker         }
operator >(const Int & other) const563*35238bceSAndroid Build Coastguard Worker         inline bool operator>(const Int &other) const
564*35238bceSAndroid Build Coastguard Worker         {
565*35238bceSAndroid Build Coastguard Worker             return m_value > other.m_value;
566*35238bceSAndroid Build Coastguard Worker         }
operator <=(const Int & other) const567*35238bceSAndroid Build Coastguard Worker         inline bool operator<=(const Int &other) const
568*35238bceSAndroid Build Coastguard Worker         {
569*35238bceSAndroid Build Coastguard Worker             return m_value <= other.m_value;
570*35238bceSAndroid Build Coastguard Worker         }
operator >=(const Int & other) const571*35238bceSAndroid Build Coastguard Worker         inline bool operator>=(const Int &other) const
572*35238bceSAndroid Build Coastguard Worker         {
573*35238bceSAndroid Build Coastguard Worker             return m_value >= other.m_value;
574*35238bceSAndroid Build Coastguard Worker         }
575*35238bceSAndroid Build Coastguard Worker 
operator int32_t(void) const576*35238bceSAndroid Build Coastguard Worker         inline operator int32_t(void) const
577*35238bceSAndroid Build Coastguard Worker         {
578*35238bceSAndroid Build Coastguard Worker             return m_value;
579*35238bceSAndroid Build Coastguard Worker         }
580*35238bceSAndroid Build Coastguard Worker         template <class T>
to(void) const581*35238bceSAndroid Build Coastguard Worker         inline T to(void) const
582*35238bceSAndroid Build Coastguard Worker         {
583*35238bceSAndroid Build Coastguard Worker             return (T)m_value;
584*35238bceSAndroid Build Coastguard Worker         }
585*35238bceSAndroid Build Coastguard Worker 
586*35238bceSAndroid Build Coastguard Worker     private:
587*35238bceSAndroid Build Coastguard Worker         int32_t m_value;
588*35238bceSAndroid Build Coastguard Worker     };
589*35238bceSAndroid Build Coastguard Worker 
590*35238bceSAndroid Build Coastguard Worker     class Half
591*35238bceSAndroid Build Coastguard Worker     {
592*35238bceSAndroid Build Coastguard Worker     public:
create(float value)593*35238bceSAndroid Build Coastguard Worker         static Half create(float value)
594*35238bceSAndroid Build Coastguard Worker         {
595*35238bceSAndroid Build Coastguard Worker             Half h;
596*35238bceSAndroid Build Coastguard Worker             h.m_value = floatToHalf(value);
597*35238bceSAndroid Build Coastguard Worker             return h;
598*35238bceSAndroid Build Coastguard Worker         }
getValue(void) const599*35238bceSAndroid Build Coastguard Worker         inline deFloat16 getValue(void) const
600*35238bceSAndroid Build Coastguard Worker         {
601*35238bceSAndroid Build Coastguard Worker             return m_value;
602*35238bceSAndroid Build Coastguard Worker         }
603*35238bceSAndroid Build Coastguard Worker 
operator +(const Half & other) const604*35238bceSAndroid Build Coastguard Worker         inline Half operator+(const Half &other) const
605*35238bceSAndroid Build Coastguard Worker         {
606*35238bceSAndroid Build Coastguard Worker             return create(halfToFloat(m_value) + halfToFloat(other.getValue()));
607*35238bceSAndroid Build Coastguard Worker         }
operator *(const Half & other) const608*35238bceSAndroid Build Coastguard Worker         inline Half operator*(const Half &other) const
609*35238bceSAndroid Build Coastguard Worker         {
610*35238bceSAndroid Build Coastguard Worker             return create(halfToFloat(m_value) * halfToFloat(other.getValue()));
611*35238bceSAndroid Build Coastguard Worker         }
operator /(const Half & other) const612*35238bceSAndroid Build Coastguard Worker         inline Half operator/(const Half &other) const
613*35238bceSAndroid Build Coastguard Worker         {
614*35238bceSAndroid Build Coastguard Worker             return create(halfToFloat(m_value) / halfToFloat(other.getValue()));
615*35238bceSAndroid Build Coastguard Worker         }
operator -(const Half & other) const616*35238bceSAndroid Build Coastguard Worker         inline Half operator-(const Half &other) const
617*35238bceSAndroid Build Coastguard Worker         {
618*35238bceSAndroid Build Coastguard Worker             return create(halfToFloat(m_value) - halfToFloat(other.getValue()));
619*35238bceSAndroid Build Coastguard Worker         }
620*35238bceSAndroid Build Coastguard Worker 
operator +=(const Half & other)621*35238bceSAndroid Build Coastguard Worker         inline Half &operator+=(const Half &other)
622*35238bceSAndroid Build Coastguard Worker         {
623*35238bceSAndroid Build Coastguard Worker             m_value = floatToHalf(halfToFloat(other.getValue()) + halfToFloat(m_value));
624*35238bceSAndroid Build Coastguard Worker             return *this;
625*35238bceSAndroid Build Coastguard Worker         }
operator *=(const Half & other)626*35238bceSAndroid Build Coastguard Worker         inline Half &operator*=(const Half &other)
627*35238bceSAndroid Build Coastguard Worker         {
628*35238bceSAndroid Build Coastguard Worker             m_value = floatToHalf(halfToFloat(other.getValue()) * halfToFloat(m_value));
629*35238bceSAndroid Build Coastguard Worker             return *this;
630*35238bceSAndroid Build Coastguard Worker         }
operator /=(const Half & other)631*35238bceSAndroid Build Coastguard Worker         inline Half &operator/=(const Half &other)
632*35238bceSAndroid Build Coastguard Worker         {
633*35238bceSAndroid Build Coastguard Worker             m_value = floatToHalf(halfToFloat(other.getValue()) / halfToFloat(m_value));
634*35238bceSAndroid Build Coastguard Worker             return *this;
635*35238bceSAndroid Build Coastguard Worker         }
operator -=(const Half & other)636*35238bceSAndroid Build Coastguard Worker         inline Half &operator-=(const Half &other)
637*35238bceSAndroid Build Coastguard Worker         {
638*35238bceSAndroid Build Coastguard Worker             m_value = floatToHalf(halfToFloat(other.getValue()) - halfToFloat(m_value));
639*35238bceSAndroid Build Coastguard Worker             return *this;
640*35238bceSAndroid Build Coastguard Worker         }
641*35238bceSAndroid Build Coastguard Worker 
operator ==(const Half & other) const642*35238bceSAndroid Build Coastguard Worker         inline bool operator==(const Half &other) const
643*35238bceSAndroid Build Coastguard Worker         {
644*35238bceSAndroid Build Coastguard Worker             return m_value == other.m_value;
645*35238bceSAndroid Build Coastguard Worker         }
operator !=(const Half & other) const646*35238bceSAndroid Build Coastguard Worker         inline bool operator!=(const Half &other) const
647*35238bceSAndroid Build Coastguard Worker         {
648*35238bceSAndroid Build Coastguard Worker             return m_value != other.m_value;
649*35238bceSAndroid Build Coastguard Worker         }
operator <(const Half & other) const650*35238bceSAndroid Build Coastguard Worker         inline bool operator<(const Half &other) const
651*35238bceSAndroid Build Coastguard Worker         {
652*35238bceSAndroid Build Coastguard Worker             return halfToFloat(m_value) < halfToFloat(other.m_value);
653*35238bceSAndroid Build Coastguard Worker         }
operator >(const Half & other) const654*35238bceSAndroid Build Coastguard Worker         inline bool operator>(const Half &other) const
655*35238bceSAndroid Build Coastguard Worker         {
656*35238bceSAndroid Build Coastguard Worker             return halfToFloat(m_value) > halfToFloat(other.m_value);
657*35238bceSAndroid Build Coastguard Worker         }
operator <=(const Half & other) const658*35238bceSAndroid Build Coastguard Worker         inline bool operator<=(const Half &other) const
659*35238bceSAndroid Build Coastguard Worker         {
660*35238bceSAndroid Build Coastguard Worker             return halfToFloat(m_value) <= halfToFloat(other.m_value);
661*35238bceSAndroid Build Coastguard Worker         }
operator >=(const Half & other) const662*35238bceSAndroid Build Coastguard Worker         inline bool operator>=(const Half &other) const
663*35238bceSAndroid Build Coastguard Worker         {
664*35238bceSAndroid Build Coastguard Worker             return halfToFloat(m_value) >= halfToFloat(other.m_value);
665*35238bceSAndroid Build Coastguard Worker         }
666*35238bceSAndroid Build Coastguard Worker 
667*35238bceSAndroid Build Coastguard Worker         template <class T>
to(void) const668*35238bceSAndroid Build Coastguard Worker         inline T to(void) const
669*35238bceSAndroid Build Coastguard Worker         {
670*35238bceSAndroid Build Coastguard Worker             return (T)halfToFloat(m_value);
671*35238bceSAndroid Build Coastguard Worker         }
672*35238bceSAndroid Build Coastguard Worker 
673*35238bceSAndroid Build Coastguard Worker         inline static deFloat16 floatToHalf(float f);
674*35238bceSAndroid Build Coastguard Worker         inline static float halfToFloat(deFloat16 h);
675*35238bceSAndroid Build Coastguard Worker 
676*35238bceSAndroid Build Coastguard Worker     private:
677*35238bceSAndroid Build Coastguard Worker         deFloat16 m_value;
678*35238bceSAndroid Build Coastguard Worker     };
679*35238bceSAndroid Build Coastguard Worker 
680*35238bceSAndroid Build Coastguard Worker     class Fixed
681*35238bceSAndroid Build Coastguard Worker     {
682*35238bceSAndroid Build Coastguard Worker     public:
create(int32_t value)683*35238bceSAndroid Build Coastguard Worker         static Fixed create(int32_t value)
684*35238bceSAndroid Build Coastguard Worker         {
685*35238bceSAndroid Build Coastguard Worker             Fixed v;
686*35238bceSAndroid Build Coastguard Worker             v.m_value = value;
687*35238bceSAndroid Build Coastguard Worker             return v;
688*35238bceSAndroid Build Coastguard Worker         }
getValue(void) const689*35238bceSAndroid Build Coastguard Worker         inline int32_t getValue(void) const
690*35238bceSAndroid Build Coastguard Worker         {
691*35238bceSAndroid Build Coastguard Worker             return m_value;
692*35238bceSAndroid Build Coastguard Worker         }
693*35238bceSAndroid Build Coastguard Worker 
operator +(const Fixed & other) const694*35238bceSAndroid Build Coastguard Worker         inline Fixed operator+(const Fixed &other) const
695*35238bceSAndroid Build Coastguard Worker         {
696*35238bceSAndroid Build Coastguard Worker             return create(m_value + other.getValue());
697*35238bceSAndroid Build Coastguard Worker         }
operator *(const Fixed & other) const698*35238bceSAndroid Build Coastguard Worker         inline Fixed operator*(const Fixed &other) const
699*35238bceSAndroid Build Coastguard Worker         {
700*35238bceSAndroid Build Coastguard Worker             return create(m_value * other.getValue());
701*35238bceSAndroid Build Coastguard Worker         }
operator /(const Fixed & other) const702*35238bceSAndroid Build Coastguard Worker         inline Fixed operator/(const Fixed &other) const
703*35238bceSAndroid Build Coastguard Worker         {
704*35238bceSAndroid Build Coastguard Worker             return create(m_value / other.getValue());
705*35238bceSAndroid Build Coastguard Worker         }
operator -(const Fixed & other) const706*35238bceSAndroid Build Coastguard Worker         inline Fixed operator-(const Fixed &other) const
707*35238bceSAndroid Build Coastguard Worker         {
708*35238bceSAndroid Build Coastguard Worker             return create(m_value - other.getValue());
709*35238bceSAndroid Build Coastguard Worker         }
710*35238bceSAndroid Build Coastguard Worker 
operator +=(const Fixed & other)711*35238bceSAndroid Build Coastguard Worker         inline Fixed &operator+=(const Fixed &other)
712*35238bceSAndroid Build Coastguard Worker         {
713*35238bceSAndroid Build Coastguard Worker             m_value += other.getValue();
714*35238bceSAndroid Build Coastguard Worker             return *this;
715*35238bceSAndroid Build Coastguard Worker         }
operator *=(const Fixed & other)716*35238bceSAndroid Build Coastguard Worker         inline Fixed &operator*=(const Fixed &other)
717*35238bceSAndroid Build Coastguard Worker         {
718*35238bceSAndroid Build Coastguard Worker             m_value *= other.getValue();
719*35238bceSAndroid Build Coastguard Worker             return *this;
720*35238bceSAndroid Build Coastguard Worker         }
operator /=(const Fixed & other)721*35238bceSAndroid Build Coastguard Worker         inline Fixed &operator/=(const Fixed &other)
722*35238bceSAndroid Build Coastguard Worker         {
723*35238bceSAndroid Build Coastguard Worker             m_value /= other.getValue();
724*35238bceSAndroid Build Coastguard Worker             return *this;
725*35238bceSAndroid Build Coastguard Worker         }
operator -=(const Fixed & other)726*35238bceSAndroid Build Coastguard Worker         inline Fixed &operator-=(const Fixed &other)
727*35238bceSAndroid Build Coastguard Worker         {
728*35238bceSAndroid Build Coastguard Worker             m_value -= other.getValue();
729*35238bceSAndroid Build Coastguard Worker             return *this;
730*35238bceSAndroid Build Coastguard Worker         }
731*35238bceSAndroid Build Coastguard Worker 
operator ==(const Fixed & other) const732*35238bceSAndroid Build Coastguard Worker         inline bool operator==(const Fixed &other) const
733*35238bceSAndroid Build Coastguard Worker         {
734*35238bceSAndroid Build Coastguard Worker             return m_value == other.m_value;
735*35238bceSAndroid Build Coastguard Worker         }
operator !=(const Fixed & other) const736*35238bceSAndroid Build Coastguard Worker         inline bool operator!=(const Fixed &other) const
737*35238bceSAndroid Build Coastguard Worker         {
738*35238bceSAndroid Build Coastguard Worker             return m_value != other.m_value;
739*35238bceSAndroid Build Coastguard Worker         }
operator <(const Fixed & other) const740*35238bceSAndroid Build Coastguard Worker         inline bool operator<(const Fixed &other) const
741*35238bceSAndroid Build Coastguard Worker         {
742*35238bceSAndroid Build Coastguard Worker             return m_value < other.m_value;
743*35238bceSAndroid Build Coastguard Worker         }
operator >(const Fixed & other) const744*35238bceSAndroid Build Coastguard Worker         inline bool operator>(const Fixed &other) const
745*35238bceSAndroid Build Coastguard Worker         {
746*35238bceSAndroid Build Coastguard Worker             return m_value > other.m_value;
747*35238bceSAndroid Build Coastguard Worker         }
operator <=(const Fixed & other) const748*35238bceSAndroid Build Coastguard Worker         inline bool operator<=(const Fixed &other) const
749*35238bceSAndroid Build Coastguard Worker         {
750*35238bceSAndroid Build Coastguard Worker             return m_value <= other.m_value;
751*35238bceSAndroid Build Coastguard Worker         }
operator >=(const Fixed & other) const752*35238bceSAndroid Build Coastguard Worker         inline bool operator>=(const Fixed &other) const
753*35238bceSAndroid Build Coastguard Worker         {
754*35238bceSAndroid Build Coastguard Worker             return m_value >= other.m_value;
755*35238bceSAndroid Build Coastguard Worker         }
756*35238bceSAndroid Build Coastguard Worker 
operator int32_t(void) const757*35238bceSAndroid Build Coastguard Worker         inline operator int32_t(void) const
758*35238bceSAndroid Build Coastguard Worker         {
759*35238bceSAndroid Build Coastguard Worker             return m_value;
760*35238bceSAndroid Build Coastguard Worker         }
761*35238bceSAndroid Build Coastguard Worker         template <class T>
to(void) const762*35238bceSAndroid Build Coastguard Worker         inline T to(void) const
763*35238bceSAndroid Build Coastguard Worker         {
764*35238bceSAndroid Build Coastguard Worker             return (T)m_value;
765*35238bceSAndroid Build Coastguard Worker         }
766*35238bceSAndroid Build Coastguard Worker 
767*35238bceSAndroid Build Coastguard Worker     private:
768*35238bceSAndroid Build Coastguard Worker         int32_t m_value;
769*35238bceSAndroid Build Coastguard Worker     };
770*35238bceSAndroid Build Coastguard Worker 
771*35238bceSAndroid Build Coastguard Worker     // \todo [mika] This is pretty messy
GLValue(void)772*35238bceSAndroid Build Coastguard Worker     GLValue(void) : type(DrawTestSpec::INPUTTYPE_LAST)
773*35238bceSAndroid Build Coastguard Worker     {
774*35238bceSAndroid Build Coastguard Worker     }
GLValue(Float value)775*35238bceSAndroid Build Coastguard Worker     explicit GLValue(Float value) : type(DrawTestSpec::INPUTTYPE_FLOAT), fl(value)
776*35238bceSAndroid Build Coastguard Worker     {
777*35238bceSAndroid Build Coastguard Worker     }
GLValue(Fixed value)778*35238bceSAndroid Build Coastguard Worker     explicit GLValue(Fixed value) : type(DrawTestSpec::INPUTTYPE_FIXED), fi(value)
779*35238bceSAndroid Build Coastguard Worker     {
780*35238bceSAndroid Build Coastguard Worker     }
GLValue(Byte value)781*35238bceSAndroid Build Coastguard Worker     explicit GLValue(Byte value) : type(DrawTestSpec::INPUTTYPE_BYTE), b(value)
782*35238bceSAndroid Build Coastguard Worker     {
783*35238bceSAndroid Build Coastguard Worker     }
GLValue(Ubyte value)784*35238bceSAndroid Build Coastguard Worker     explicit GLValue(Ubyte value) : type(DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE), ub(value)
785*35238bceSAndroid Build Coastguard Worker     {
786*35238bceSAndroid Build Coastguard Worker     }
GLValue(Short value)787*35238bceSAndroid Build Coastguard Worker     explicit GLValue(Short value) : type(DrawTestSpec::INPUTTYPE_SHORT), s(value)
788*35238bceSAndroid Build Coastguard Worker     {
789*35238bceSAndroid Build Coastguard Worker     }
GLValue(Ushort value)790*35238bceSAndroid Build Coastguard Worker     explicit GLValue(Ushort value) : type(DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT), us(value)
791*35238bceSAndroid Build Coastguard Worker     {
792*35238bceSAndroid Build Coastguard Worker     }
GLValue(Int value)793*35238bceSAndroid Build Coastguard Worker     explicit GLValue(Int value) : type(DrawTestSpec::INPUTTYPE_INT), i(value)
794*35238bceSAndroid Build Coastguard Worker     {
795*35238bceSAndroid Build Coastguard Worker     }
GLValue(Uint value)796*35238bceSAndroid Build Coastguard Worker     explicit GLValue(Uint value) : type(DrawTestSpec::INPUTTYPE_UNSIGNED_INT), ui(value)
797*35238bceSAndroid Build Coastguard Worker     {
798*35238bceSAndroid Build Coastguard Worker     }
GLValue(Half value)799*35238bceSAndroid Build Coastguard Worker     explicit GLValue(Half value) : type(DrawTestSpec::INPUTTYPE_HALF), h(value)
800*35238bceSAndroid Build Coastguard Worker     {
801*35238bceSAndroid Build Coastguard Worker     }
GLValue(Double value)802*35238bceSAndroid Build Coastguard Worker     explicit GLValue(Double value) : type(DrawTestSpec::INPUTTYPE_DOUBLE), d(value)
803*35238bceSAndroid Build Coastguard Worker     {
804*35238bceSAndroid Build Coastguard Worker     }
805*35238bceSAndroid Build Coastguard Worker 
806*35238bceSAndroid Build Coastguard Worker     float toFloat(void) const;
807*35238bceSAndroid Build Coastguard Worker 
808*35238bceSAndroid Build Coastguard Worker     static GLValue getMaxValue(DrawTestSpec::InputType type);
809*35238bceSAndroid Build Coastguard Worker     static GLValue getMinValue(DrawTestSpec::InputType type);
810*35238bceSAndroid Build Coastguard Worker 
811*35238bceSAndroid Build Coastguard Worker     DrawTestSpec::InputType type;
812*35238bceSAndroid Build Coastguard Worker 
813*35238bceSAndroid Build Coastguard Worker     union
814*35238bceSAndroid Build Coastguard Worker     {
815*35238bceSAndroid Build Coastguard Worker         Float fl;
816*35238bceSAndroid Build Coastguard Worker         Fixed fi;
817*35238bceSAndroid Build Coastguard Worker         Double d;
818*35238bceSAndroid Build Coastguard Worker         Byte b;
819*35238bceSAndroid Build Coastguard Worker         Ubyte ub;
820*35238bceSAndroid Build Coastguard Worker         Short s;
821*35238bceSAndroid Build Coastguard Worker         Ushort us;
822*35238bceSAndroid Build Coastguard Worker         Int i;
823*35238bceSAndroid Build Coastguard Worker         Uint ui;
824*35238bceSAndroid Build Coastguard Worker         Half h;
825*35238bceSAndroid Build Coastguard Worker     };
826*35238bceSAndroid Build Coastguard Worker };
827*35238bceSAndroid Build Coastguard Worker 
floatToHalf(float f)828*35238bceSAndroid Build Coastguard Worker inline deFloat16 GLValue::Half::floatToHalf(float f)
829*35238bceSAndroid Build Coastguard Worker {
830*35238bceSAndroid Build Coastguard Worker     // No denorm support.
831*35238bceSAndroid Build Coastguard Worker     tcu::Float<uint16_t, 5, 10, 15, tcu::FLOAT_HAS_SIGN> v(f);
832*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!v.isNaN() && !v.isInf());
833*35238bceSAndroid Build Coastguard Worker     return v.bits();
834*35238bceSAndroid Build Coastguard Worker }
835*35238bceSAndroid Build Coastguard Worker 
halfToFloat(deFloat16 h)836*35238bceSAndroid Build Coastguard Worker inline float GLValue::Half::halfToFloat(deFloat16 h)
837*35238bceSAndroid Build Coastguard Worker {
838*35238bceSAndroid Build Coastguard Worker     return tcu::Float16((uint16_t)h).asFloat();
839*35238bceSAndroid Build Coastguard Worker }
840*35238bceSAndroid Build Coastguard Worker 
toFloat(void) const841*35238bceSAndroid Build Coastguard Worker float GLValue::toFloat(void) const
842*35238bceSAndroid Build Coastguard Worker {
843*35238bceSAndroid Build Coastguard Worker     switch (type)
844*35238bceSAndroid Build Coastguard Worker     {
845*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::INPUTTYPE_FLOAT:
846*35238bceSAndroid Build Coastguard Worker         return fl.getValue();
847*35238bceSAndroid Build Coastguard Worker 
848*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::INPUTTYPE_BYTE:
849*35238bceSAndroid Build Coastguard Worker         return b.getValue();
850*35238bceSAndroid Build Coastguard Worker 
851*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE:
852*35238bceSAndroid Build Coastguard Worker         return ub.getValue();
853*35238bceSAndroid Build Coastguard Worker 
854*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::INPUTTYPE_SHORT:
855*35238bceSAndroid Build Coastguard Worker         return s.getValue();
856*35238bceSAndroid Build Coastguard Worker 
857*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT:
858*35238bceSAndroid Build Coastguard Worker         return us.getValue();
859*35238bceSAndroid Build Coastguard Worker 
860*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::INPUTTYPE_FIXED:
861*35238bceSAndroid Build Coastguard Worker     {
862*35238bceSAndroid Build Coastguard Worker         int maxValue = 65536;
863*35238bceSAndroid Build Coastguard Worker         return (float)(double(2 * fi.getValue() + 1) / (maxValue - 1));
864*35238bceSAndroid Build Coastguard Worker     }
865*35238bceSAndroid Build Coastguard Worker 
866*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::INPUTTYPE_UNSIGNED_INT:
867*35238bceSAndroid Build Coastguard Worker         return (float)ui.getValue();
868*35238bceSAndroid Build Coastguard Worker 
869*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::INPUTTYPE_INT:
870*35238bceSAndroid Build Coastguard Worker         return (float)i.getValue();
871*35238bceSAndroid Build Coastguard Worker 
872*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::INPUTTYPE_HALF:
873*35238bceSAndroid Build Coastguard Worker         return h.to<float>();
874*35238bceSAndroid Build Coastguard Worker 
875*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::INPUTTYPE_DOUBLE:
876*35238bceSAndroid Build Coastguard Worker         return d.to<float>();
877*35238bceSAndroid Build Coastguard Worker 
878*35238bceSAndroid Build Coastguard Worker     default:
879*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
880*35238bceSAndroid Build Coastguard Worker         return 0.0f;
881*35238bceSAndroid Build Coastguard Worker     }
882*35238bceSAndroid Build Coastguard Worker }
883*35238bceSAndroid Build Coastguard Worker 
getMaxValue(DrawTestSpec::InputType type)884*35238bceSAndroid Build Coastguard Worker GLValue GLValue::getMaxValue(DrawTestSpec::InputType type)
885*35238bceSAndroid Build Coastguard Worker {
886*35238bceSAndroid Build Coastguard Worker     GLValue rangesHi[(int)DrawTestSpec::INPUTTYPE_LAST];
887*35238bceSAndroid Build Coastguard Worker 
888*35238bceSAndroid Build Coastguard Worker     rangesHi[(int)DrawTestSpec::INPUTTYPE_FLOAT]          = GLValue(Float::create(127.0f));
889*35238bceSAndroid Build Coastguard Worker     rangesHi[(int)DrawTestSpec::INPUTTYPE_DOUBLE]         = GLValue(Double::create(127.0f));
890*35238bceSAndroid Build Coastguard Worker     rangesHi[(int)DrawTestSpec::INPUTTYPE_BYTE]           = GLValue(Byte::create(127));
891*35238bceSAndroid Build Coastguard Worker     rangesHi[(int)DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE]  = GLValue(Ubyte::create(255));
892*35238bceSAndroid Build Coastguard Worker     rangesHi[(int)DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT] = GLValue(Ushort::create(65530));
893*35238bceSAndroid Build Coastguard Worker     rangesHi[(int)DrawTestSpec::INPUTTYPE_SHORT]          = GLValue(Short::create(32760));
894*35238bceSAndroid Build Coastguard Worker     rangesHi[(int)DrawTestSpec::INPUTTYPE_FIXED]          = GLValue(Fixed::create(32760));
895*35238bceSAndroid Build Coastguard Worker     rangesHi[(int)DrawTestSpec::INPUTTYPE_INT]            = GLValue(Int::create(2147483647));
896*35238bceSAndroid Build Coastguard Worker     rangesHi[(int)DrawTestSpec::INPUTTYPE_UNSIGNED_INT]   = GLValue(Uint::create(4294967295u));
897*35238bceSAndroid Build Coastguard Worker     rangesHi[(int)DrawTestSpec::INPUTTYPE_HALF]           = GLValue(Half::create(256.0f));
898*35238bceSAndroid Build Coastguard Worker 
899*35238bceSAndroid Build Coastguard Worker     return rangesHi[(int)type];
900*35238bceSAndroid Build Coastguard Worker }
901*35238bceSAndroid Build Coastguard Worker 
getMinValue(DrawTestSpec::InputType type)902*35238bceSAndroid Build Coastguard Worker GLValue GLValue::getMinValue(DrawTestSpec::InputType type)
903*35238bceSAndroid Build Coastguard Worker {
904*35238bceSAndroid Build Coastguard Worker     GLValue rangesLo[(int)DrawTestSpec::INPUTTYPE_LAST];
905*35238bceSAndroid Build Coastguard Worker 
906*35238bceSAndroid Build Coastguard Worker     rangesLo[(int)DrawTestSpec::INPUTTYPE_FLOAT]          = GLValue(Float::create(-127.0f));
907*35238bceSAndroid Build Coastguard Worker     rangesLo[(int)DrawTestSpec::INPUTTYPE_DOUBLE]         = GLValue(Double::create(-127.0f));
908*35238bceSAndroid Build Coastguard Worker     rangesLo[(int)DrawTestSpec::INPUTTYPE_BYTE]           = GLValue(Byte::create(-127));
909*35238bceSAndroid Build Coastguard Worker     rangesLo[(int)DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE]  = GLValue(Ubyte::create(0));
910*35238bceSAndroid Build Coastguard Worker     rangesLo[(int)DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT] = GLValue(Ushort::create(0));
911*35238bceSAndroid Build Coastguard Worker     rangesLo[(int)DrawTestSpec::INPUTTYPE_SHORT]          = GLValue(Short::create(-32760));
912*35238bceSAndroid Build Coastguard Worker     rangesLo[(int)DrawTestSpec::INPUTTYPE_FIXED]          = GLValue(Fixed::create(-32760));
913*35238bceSAndroid Build Coastguard Worker     rangesLo[(int)DrawTestSpec::INPUTTYPE_INT]            = GLValue(Int::create(-2147483647));
914*35238bceSAndroid Build Coastguard Worker     rangesLo[(int)DrawTestSpec::INPUTTYPE_UNSIGNED_INT]   = GLValue(Uint::create(0));
915*35238bceSAndroid Build Coastguard Worker     rangesLo[(int)DrawTestSpec::INPUTTYPE_HALF]           = GLValue(Half::create(-256.0f));
916*35238bceSAndroid Build Coastguard Worker 
917*35238bceSAndroid Build Coastguard Worker     return rangesLo[(int)type];
918*35238bceSAndroid Build Coastguard Worker }
919*35238bceSAndroid Build Coastguard Worker 
920*35238bceSAndroid Build Coastguard Worker template <typename T>
921*35238bceSAndroid Build Coastguard Worker struct GLValueTypeTraits;
922*35238bceSAndroid Build Coastguard Worker 
923*35238bceSAndroid Build Coastguard Worker template <>
924*35238bceSAndroid Build Coastguard Worker struct GLValueTypeTraits<GLValue::Float>
925*35238bceSAndroid Build Coastguard Worker {
926*35238bceSAndroid Build Coastguard Worker     static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_FLOAT;
927*35238bceSAndroid Build Coastguard Worker };
928*35238bceSAndroid Build Coastguard Worker template <>
929*35238bceSAndroid Build Coastguard Worker struct GLValueTypeTraits<GLValue::Double>
930*35238bceSAndroid Build Coastguard Worker {
931*35238bceSAndroid Build Coastguard Worker     static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_DOUBLE;
932*35238bceSAndroid Build Coastguard Worker };
933*35238bceSAndroid Build Coastguard Worker template <>
934*35238bceSAndroid Build Coastguard Worker struct GLValueTypeTraits<GLValue::Byte>
935*35238bceSAndroid Build Coastguard Worker {
936*35238bceSAndroid Build Coastguard Worker     static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_BYTE;
937*35238bceSAndroid Build Coastguard Worker };
938*35238bceSAndroid Build Coastguard Worker template <>
939*35238bceSAndroid Build Coastguard Worker struct GLValueTypeTraits<GLValue::Ubyte>
940*35238bceSAndroid Build Coastguard Worker {
941*35238bceSAndroid Build Coastguard Worker     static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE;
942*35238bceSAndroid Build Coastguard Worker };
943*35238bceSAndroid Build Coastguard Worker template <>
944*35238bceSAndroid Build Coastguard Worker struct GLValueTypeTraits<GLValue::Ushort>
945*35238bceSAndroid Build Coastguard Worker {
946*35238bceSAndroid Build Coastguard Worker     static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT;
947*35238bceSAndroid Build Coastguard Worker };
948*35238bceSAndroid Build Coastguard Worker template <>
949*35238bceSAndroid Build Coastguard Worker struct GLValueTypeTraits<GLValue::Short>
950*35238bceSAndroid Build Coastguard Worker {
951*35238bceSAndroid Build Coastguard Worker     static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_SHORT;
952*35238bceSAndroid Build Coastguard Worker };
953*35238bceSAndroid Build Coastguard Worker template <>
954*35238bceSAndroid Build Coastguard Worker struct GLValueTypeTraits<GLValue::Fixed>
955*35238bceSAndroid Build Coastguard Worker {
956*35238bceSAndroid Build Coastguard Worker     static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_FIXED;
957*35238bceSAndroid Build Coastguard Worker };
958*35238bceSAndroid Build Coastguard Worker template <>
959*35238bceSAndroid Build Coastguard Worker struct GLValueTypeTraits<GLValue::Int>
960*35238bceSAndroid Build Coastguard Worker {
961*35238bceSAndroid Build Coastguard Worker     static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_INT;
962*35238bceSAndroid Build Coastguard Worker };
963*35238bceSAndroid Build Coastguard Worker template <>
964*35238bceSAndroid Build Coastguard Worker struct GLValueTypeTraits<GLValue::Uint>
965*35238bceSAndroid Build Coastguard Worker {
966*35238bceSAndroid Build Coastguard Worker     static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_UNSIGNED_INT;
967*35238bceSAndroid Build Coastguard Worker };
968*35238bceSAndroid Build Coastguard Worker template <>
969*35238bceSAndroid Build Coastguard Worker struct GLValueTypeTraits<GLValue::Half>
970*35238bceSAndroid Build Coastguard Worker {
971*35238bceSAndroid Build Coastguard Worker     static const DrawTestSpec::InputType Type = DrawTestSpec::INPUTTYPE_HALF;
972*35238bceSAndroid Build Coastguard Worker };
973*35238bceSAndroid Build Coastguard Worker 
974*35238bceSAndroid Build Coastguard Worker template <typename T>
975*35238bceSAndroid Build Coastguard Worker inline T extractGLValue(const GLValue &v);
976*35238bceSAndroid Build Coastguard Worker 
977*35238bceSAndroid Build Coastguard Worker template <>
extractGLValue(const GLValue & v)978*35238bceSAndroid Build Coastguard Worker GLValue::Float inline extractGLValue<GLValue::Float>(const GLValue &v)
979*35238bceSAndroid Build Coastguard Worker {
980*35238bceSAndroid Build Coastguard Worker     return v.fl;
981*35238bceSAndroid Build Coastguard Worker }
982*35238bceSAndroid Build Coastguard Worker template <>
extractGLValue(const GLValue & v)983*35238bceSAndroid Build Coastguard Worker GLValue::Double inline extractGLValue<GLValue::Double>(const GLValue &v)
984*35238bceSAndroid Build Coastguard Worker {
985*35238bceSAndroid Build Coastguard Worker     return v.d;
986*35238bceSAndroid Build Coastguard Worker }
987*35238bceSAndroid Build Coastguard Worker template <>
extractGLValue(const GLValue & v)988*35238bceSAndroid Build Coastguard Worker GLValue::Byte inline extractGLValue<GLValue::Byte>(const GLValue &v)
989*35238bceSAndroid Build Coastguard Worker {
990*35238bceSAndroid Build Coastguard Worker     return v.b;
991*35238bceSAndroid Build Coastguard Worker }
992*35238bceSAndroid Build Coastguard Worker template <>
extractGLValue(const GLValue & v)993*35238bceSAndroid Build Coastguard Worker GLValue::Ubyte inline extractGLValue<GLValue::Ubyte>(const GLValue &v)
994*35238bceSAndroid Build Coastguard Worker {
995*35238bceSAndroid Build Coastguard Worker     return v.ub;
996*35238bceSAndroid Build Coastguard Worker }
997*35238bceSAndroid Build Coastguard Worker template <>
extractGLValue(const GLValue & v)998*35238bceSAndroid Build Coastguard Worker GLValue::Ushort inline extractGLValue<GLValue::Ushort>(const GLValue &v)
999*35238bceSAndroid Build Coastguard Worker {
1000*35238bceSAndroid Build Coastguard Worker     return v.us;
1001*35238bceSAndroid Build Coastguard Worker }
1002*35238bceSAndroid Build Coastguard Worker template <>
extractGLValue(const GLValue & v)1003*35238bceSAndroid Build Coastguard Worker GLValue::Short inline extractGLValue<GLValue::Short>(const GLValue &v)
1004*35238bceSAndroid Build Coastguard Worker {
1005*35238bceSAndroid Build Coastguard Worker     return v.s;
1006*35238bceSAndroid Build Coastguard Worker }
1007*35238bceSAndroid Build Coastguard Worker template <>
extractGLValue(const GLValue & v)1008*35238bceSAndroid Build Coastguard Worker GLValue::Fixed inline extractGLValue<GLValue::Fixed>(const GLValue &v)
1009*35238bceSAndroid Build Coastguard Worker {
1010*35238bceSAndroid Build Coastguard Worker     return v.fi;
1011*35238bceSAndroid Build Coastguard Worker }
1012*35238bceSAndroid Build Coastguard Worker template <>
extractGLValue(const GLValue & v)1013*35238bceSAndroid Build Coastguard Worker GLValue::Int inline extractGLValue<GLValue::Int>(const GLValue &v)
1014*35238bceSAndroid Build Coastguard Worker {
1015*35238bceSAndroid Build Coastguard Worker     return v.i;
1016*35238bceSAndroid Build Coastguard Worker }
1017*35238bceSAndroid Build Coastguard Worker template <>
extractGLValue(const GLValue & v)1018*35238bceSAndroid Build Coastguard Worker GLValue::Uint inline extractGLValue<GLValue::Uint>(const GLValue &v)
1019*35238bceSAndroid Build Coastguard Worker {
1020*35238bceSAndroid Build Coastguard Worker     return v.ui;
1021*35238bceSAndroid Build Coastguard Worker }
1022*35238bceSAndroid Build Coastguard Worker template <>
extractGLValue(const GLValue & v)1023*35238bceSAndroid Build Coastguard Worker GLValue::Half inline extractGLValue<GLValue::Half>(const GLValue &v)
1024*35238bceSAndroid Build Coastguard Worker {
1025*35238bceSAndroid Build Coastguard Worker     return v.h;
1026*35238bceSAndroid Build Coastguard Worker }
1027*35238bceSAndroid Build Coastguard Worker 
1028*35238bceSAndroid Build Coastguard Worker template <class T>
1029*35238bceSAndroid Build Coastguard Worker inline T getRandom(deRandom &rnd, T min, T max);
1030*35238bceSAndroid Build Coastguard Worker 
1031*35238bceSAndroid Build Coastguard Worker template <>
getRandom(deRandom & rnd,GLValue::Float min,GLValue::Float max)1032*35238bceSAndroid Build Coastguard Worker inline GLValue::Float getRandom(deRandom &rnd, GLValue::Float min, GLValue::Float max)
1033*35238bceSAndroid Build Coastguard Worker {
1034*35238bceSAndroid Build Coastguard Worker     if (max < min)
1035*35238bceSAndroid Build Coastguard Worker         return min;
1036*35238bceSAndroid Build Coastguard Worker 
1037*35238bceSAndroid Build Coastguard Worker     return GLValue::Float::create(min + deRandom_getFloat(&rnd) * (max.to<float>() - min.to<float>()));
1038*35238bceSAndroid Build Coastguard Worker }
1039*35238bceSAndroid Build Coastguard Worker 
1040*35238bceSAndroid Build Coastguard Worker template <>
getRandom(deRandom & rnd,GLValue::Double min,GLValue::Double max)1041*35238bceSAndroid Build Coastguard Worker inline GLValue::Double getRandom(deRandom &rnd, GLValue::Double min, GLValue::Double max)
1042*35238bceSAndroid Build Coastguard Worker {
1043*35238bceSAndroid Build Coastguard Worker     if (max < min)
1044*35238bceSAndroid Build Coastguard Worker         return min;
1045*35238bceSAndroid Build Coastguard Worker 
1046*35238bceSAndroid Build Coastguard Worker     return GLValue::Double::create(min + deRandom_getFloat(&rnd) * (max.to<float>() - min.to<float>()));
1047*35238bceSAndroid Build Coastguard Worker }
1048*35238bceSAndroid Build Coastguard Worker 
1049*35238bceSAndroid Build Coastguard Worker template <>
getRandom(deRandom & rnd,GLValue::Short min,GLValue::Short max)1050*35238bceSAndroid Build Coastguard Worker inline GLValue::Short getRandom(deRandom &rnd, GLValue::Short min, GLValue::Short max)
1051*35238bceSAndroid Build Coastguard Worker {
1052*35238bceSAndroid Build Coastguard Worker     if (max < min)
1053*35238bceSAndroid Build Coastguard Worker         return min;
1054*35238bceSAndroid Build Coastguard Worker 
1055*35238bceSAndroid Build Coastguard Worker     return GLValue::Short::create(
1056*35238bceSAndroid Build Coastguard Worker         (min == max ? min : (int16_t)(min + (deRandom_getUint32(&rnd) % (max.to<int>() - min.to<int>())))));
1057*35238bceSAndroid Build Coastguard Worker }
1058*35238bceSAndroid Build Coastguard Worker 
1059*35238bceSAndroid Build Coastguard Worker template <>
getRandom(deRandom & rnd,GLValue::Ushort min,GLValue::Ushort max)1060*35238bceSAndroid Build Coastguard Worker inline GLValue::Ushort getRandom(deRandom &rnd, GLValue::Ushort min, GLValue::Ushort max)
1061*35238bceSAndroid Build Coastguard Worker {
1062*35238bceSAndroid Build Coastguard Worker     if (max < min)
1063*35238bceSAndroid Build Coastguard Worker         return min;
1064*35238bceSAndroid Build Coastguard Worker 
1065*35238bceSAndroid Build Coastguard Worker     return GLValue::Ushort::create(
1066*35238bceSAndroid Build Coastguard Worker         (min == max ? min : (uint16_t)(min + (deRandom_getUint32(&rnd) % (max.to<int>() - min.to<int>())))));
1067*35238bceSAndroid Build Coastguard Worker }
1068*35238bceSAndroid Build Coastguard Worker 
1069*35238bceSAndroid Build Coastguard Worker template <>
getRandom(deRandom & rnd,GLValue::Byte min,GLValue::Byte max)1070*35238bceSAndroid Build Coastguard Worker inline GLValue::Byte getRandom(deRandom &rnd, GLValue::Byte min, GLValue::Byte max)
1071*35238bceSAndroid Build Coastguard Worker {
1072*35238bceSAndroid Build Coastguard Worker     if (max < min)
1073*35238bceSAndroid Build Coastguard Worker         return min;
1074*35238bceSAndroid Build Coastguard Worker 
1075*35238bceSAndroid Build Coastguard Worker     return GLValue::Byte::create(
1076*35238bceSAndroid Build Coastguard Worker         (min == max ? min : (int8_t)(min + (deRandom_getUint32(&rnd) % (max.to<int>() - min.to<int>())))));
1077*35238bceSAndroid Build Coastguard Worker }
1078*35238bceSAndroid Build Coastguard Worker 
1079*35238bceSAndroid Build Coastguard Worker template <>
getRandom(deRandom & rnd,GLValue::Ubyte min,GLValue::Ubyte max)1080*35238bceSAndroid Build Coastguard Worker inline GLValue::Ubyte getRandom(deRandom &rnd, GLValue::Ubyte min, GLValue::Ubyte max)
1081*35238bceSAndroid Build Coastguard Worker {
1082*35238bceSAndroid Build Coastguard Worker     if (max < min)
1083*35238bceSAndroid Build Coastguard Worker         return min;
1084*35238bceSAndroid Build Coastguard Worker 
1085*35238bceSAndroid Build Coastguard Worker     return GLValue::Ubyte::create(
1086*35238bceSAndroid Build Coastguard Worker         (min == max ? min : (uint8_t)(min + (deRandom_getUint32(&rnd) % (max.to<int>() - min.to<int>())))));
1087*35238bceSAndroid Build Coastguard Worker }
1088*35238bceSAndroid Build Coastguard Worker 
1089*35238bceSAndroid Build Coastguard Worker template <>
getRandom(deRandom & rnd,GLValue::Fixed min,GLValue::Fixed max)1090*35238bceSAndroid Build Coastguard Worker inline GLValue::Fixed getRandom(deRandom &rnd, GLValue::Fixed min, GLValue::Fixed max)
1091*35238bceSAndroid Build Coastguard Worker {
1092*35238bceSAndroid Build Coastguard Worker     if (max < min)
1093*35238bceSAndroid Build Coastguard Worker         return min;
1094*35238bceSAndroid Build Coastguard Worker 
1095*35238bceSAndroid Build Coastguard Worker     return GLValue::Fixed::create(
1096*35238bceSAndroid Build Coastguard Worker         (min == max ? min : min + (deRandom_getUint32(&rnd) % (max.to<uint32_t>() - min.to<uint32_t>()))));
1097*35238bceSAndroid Build Coastguard Worker }
1098*35238bceSAndroid Build Coastguard Worker 
1099*35238bceSAndroid Build Coastguard Worker template <>
getRandom(deRandom & rnd,GLValue::Half min,GLValue::Half max)1100*35238bceSAndroid Build Coastguard Worker inline GLValue::Half getRandom(deRandom &rnd, GLValue::Half min, GLValue::Half max)
1101*35238bceSAndroid Build Coastguard Worker {
1102*35238bceSAndroid Build Coastguard Worker     if (max < min)
1103*35238bceSAndroid Build Coastguard Worker         return min;
1104*35238bceSAndroid Build Coastguard Worker 
1105*35238bceSAndroid Build Coastguard Worker     float fMax      = max.to<float>();
1106*35238bceSAndroid Build Coastguard Worker     float fMin      = min.to<float>();
1107*35238bceSAndroid Build Coastguard Worker     GLValue::Half h = GLValue::Half::create(fMin + deRandom_getFloat(&rnd) * (fMax - fMin));
1108*35238bceSAndroid Build Coastguard Worker     return h;
1109*35238bceSAndroid Build Coastguard Worker }
1110*35238bceSAndroid Build Coastguard Worker 
1111*35238bceSAndroid Build Coastguard Worker template <>
getRandom(deRandom & rnd,GLValue::Int min,GLValue::Int max)1112*35238bceSAndroid Build Coastguard Worker inline GLValue::Int getRandom(deRandom &rnd, GLValue::Int min, GLValue::Int max)
1113*35238bceSAndroid Build Coastguard Worker {
1114*35238bceSAndroid Build Coastguard Worker     if (max < min)
1115*35238bceSAndroid Build Coastguard Worker         return min;
1116*35238bceSAndroid Build Coastguard Worker 
1117*35238bceSAndroid Build Coastguard Worker     return GLValue::Int::create(
1118*35238bceSAndroid Build Coastguard Worker         (min == max ? min : min + (deRandom_getUint32(&rnd) % (max.to<uint32_t>() - min.to<uint32_t>()))));
1119*35238bceSAndroid Build Coastguard Worker }
1120*35238bceSAndroid Build Coastguard Worker 
1121*35238bceSAndroid Build Coastguard Worker template <>
getRandom(deRandom & rnd,GLValue::Uint min,GLValue::Uint max)1122*35238bceSAndroid Build Coastguard Worker inline GLValue::Uint getRandom(deRandom &rnd, GLValue::Uint min, GLValue::Uint max)
1123*35238bceSAndroid Build Coastguard Worker {
1124*35238bceSAndroid Build Coastguard Worker     if (max < min)
1125*35238bceSAndroid Build Coastguard Worker         return min;
1126*35238bceSAndroid Build Coastguard Worker 
1127*35238bceSAndroid Build Coastguard Worker     return GLValue::Uint::create(
1128*35238bceSAndroid Build Coastguard Worker         (min == max ? min : min + (deRandom_getUint32(&rnd) % (max.to<uint32_t>() - min.to<uint32_t>()))));
1129*35238bceSAndroid Build Coastguard Worker }
1130*35238bceSAndroid Build Coastguard Worker 
1131*35238bceSAndroid Build Coastguard Worker // Minimum difference required between coordinates
1132*35238bceSAndroid Build Coastguard Worker template <class T>
1133*35238bceSAndroid Build Coastguard Worker inline T minValue(void);
1134*35238bceSAndroid Build Coastguard Worker 
1135*35238bceSAndroid Build Coastguard Worker template <>
minValue(void)1136*35238bceSAndroid Build Coastguard Worker inline GLValue::Float minValue(void)
1137*35238bceSAndroid Build Coastguard Worker {
1138*35238bceSAndroid Build Coastguard Worker     return GLValue::Float::create(4 * 1.0f);
1139*35238bceSAndroid Build Coastguard Worker }
1140*35238bceSAndroid Build Coastguard Worker 
1141*35238bceSAndroid Build Coastguard Worker template <>
minValue(void)1142*35238bceSAndroid Build Coastguard Worker inline GLValue::Double minValue(void)
1143*35238bceSAndroid Build Coastguard Worker {
1144*35238bceSAndroid Build Coastguard Worker     return GLValue::Double::create(4 * 1.0f);
1145*35238bceSAndroid Build Coastguard Worker }
1146*35238bceSAndroid Build Coastguard Worker 
1147*35238bceSAndroid Build Coastguard Worker template <>
minValue(void)1148*35238bceSAndroid Build Coastguard Worker inline GLValue::Short minValue(void)
1149*35238bceSAndroid Build Coastguard Worker {
1150*35238bceSAndroid Build Coastguard Worker     return GLValue::Short::create(4 * 256);
1151*35238bceSAndroid Build Coastguard Worker }
1152*35238bceSAndroid Build Coastguard Worker 
1153*35238bceSAndroid Build Coastguard Worker template <>
minValue(void)1154*35238bceSAndroid Build Coastguard Worker inline GLValue::Ushort minValue(void)
1155*35238bceSAndroid Build Coastguard Worker {
1156*35238bceSAndroid Build Coastguard Worker     return GLValue::Ushort::create(4 * 256);
1157*35238bceSAndroid Build Coastguard Worker }
1158*35238bceSAndroid Build Coastguard Worker 
1159*35238bceSAndroid Build Coastguard Worker template <>
minValue(void)1160*35238bceSAndroid Build Coastguard Worker inline GLValue::Byte minValue(void)
1161*35238bceSAndroid Build Coastguard Worker {
1162*35238bceSAndroid Build Coastguard Worker     return GLValue::Byte::create(4 * 1);
1163*35238bceSAndroid Build Coastguard Worker }
1164*35238bceSAndroid Build Coastguard Worker 
1165*35238bceSAndroid Build Coastguard Worker template <>
minValue(void)1166*35238bceSAndroid Build Coastguard Worker inline GLValue::Ubyte minValue(void)
1167*35238bceSAndroid Build Coastguard Worker {
1168*35238bceSAndroid Build Coastguard Worker     return GLValue::Ubyte::create(4 * 2);
1169*35238bceSAndroid Build Coastguard Worker }
1170*35238bceSAndroid Build Coastguard Worker 
1171*35238bceSAndroid Build Coastguard Worker template <>
minValue(void)1172*35238bceSAndroid Build Coastguard Worker inline GLValue::Fixed minValue(void)
1173*35238bceSAndroid Build Coastguard Worker {
1174*35238bceSAndroid Build Coastguard Worker     return GLValue::Fixed::create(4 * 1);
1175*35238bceSAndroid Build Coastguard Worker }
1176*35238bceSAndroid Build Coastguard Worker 
1177*35238bceSAndroid Build Coastguard Worker template <>
minValue(void)1178*35238bceSAndroid Build Coastguard Worker inline GLValue::Int minValue(void)
1179*35238bceSAndroid Build Coastguard Worker {
1180*35238bceSAndroid Build Coastguard Worker     return GLValue::Int::create(4 * 16777216);
1181*35238bceSAndroid Build Coastguard Worker }
1182*35238bceSAndroid Build Coastguard Worker 
1183*35238bceSAndroid Build Coastguard Worker template <>
minValue(void)1184*35238bceSAndroid Build Coastguard Worker inline GLValue::Uint minValue(void)
1185*35238bceSAndroid Build Coastguard Worker {
1186*35238bceSAndroid Build Coastguard Worker     return GLValue::Uint::create(4 * 16777216);
1187*35238bceSAndroid Build Coastguard Worker }
1188*35238bceSAndroid Build Coastguard Worker 
1189*35238bceSAndroid Build Coastguard Worker template <>
minValue(void)1190*35238bceSAndroid Build Coastguard Worker inline GLValue::Half minValue(void)
1191*35238bceSAndroid Build Coastguard Worker {
1192*35238bceSAndroid Build Coastguard Worker     return GLValue::Half::create(4 * 1.0f);
1193*35238bceSAndroid Build Coastguard Worker }
1194*35238bceSAndroid Build Coastguard Worker 
1195*35238bceSAndroid Build Coastguard Worker template <class T>
1196*35238bceSAndroid Build Coastguard Worker inline T abs(T val);
1197*35238bceSAndroid Build Coastguard Worker 
1198*35238bceSAndroid Build Coastguard Worker template <>
abs(GLValue::Fixed val)1199*35238bceSAndroid Build Coastguard Worker inline GLValue::Fixed abs(GLValue::Fixed val)
1200*35238bceSAndroid Build Coastguard Worker {
1201*35238bceSAndroid Build Coastguard Worker     return GLValue::Fixed::create(0x7FFFu & val.getValue());
1202*35238bceSAndroid Build Coastguard Worker }
1203*35238bceSAndroid Build Coastguard Worker 
1204*35238bceSAndroid Build Coastguard Worker template <>
abs(GLValue::Ubyte val)1205*35238bceSAndroid Build Coastguard Worker inline GLValue::Ubyte abs(GLValue::Ubyte val)
1206*35238bceSAndroid Build Coastguard Worker {
1207*35238bceSAndroid Build Coastguard Worker     return val;
1208*35238bceSAndroid Build Coastguard Worker }
1209*35238bceSAndroid Build Coastguard Worker 
1210*35238bceSAndroid Build Coastguard Worker template <>
abs(GLValue::Byte val)1211*35238bceSAndroid Build Coastguard Worker inline GLValue::Byte abs(GLValue::Byte val)
1212*35238bceSAndroid Build Coastguard Worker {
1213*35238bceSAndroid Build Coastguard Worker     return GLValue::Byte::create(0x7Fu & val.getValue());
1214*35238bceSAndroid Build Coastguard Worker }
1215*35238bceSAndroid Build Coastguard Worker 
1216*35238bceSAndroid Build Coastguard Worker template <>
abs(GLValue::Ushort val)1217*35238bceSAndroid Build Coastguard Worker inline GLValue::Ushort abs(GLValue::Ushort val)
1218*35238bceSAndroid Build Coastguard Worker {
1219*35238bceSAndroid Build Coastguard Worker     return val;
1220*35238bceSAndroid Build Coastguard Worker }
1221*35238bceSAndroid Build Coastguard Worker 
1222*35238bceSAndroid Build Coastguard Worker template <>
abs(GLValue::Short val)1223*35238bceSAndroid Build Coastguard Worker inline GLValue::Short abs(GLValue::Short val)
1224*35238bceSAndroid Build Coastguard Worker {
1225*35238bceSAndroid Build Coastguard Worker     return GLValue::Short::create(0x7FFFu & val.getValue());
1226*35238bceSAndroid Build Coastguard Worker }
1227*35238bceSAndroid Build Coastguard Worker 
1228*35238bceSAndroid Build Coastguard Worker template <>
abs(GLValue::Float val)1229*35238bceSAndroid Build Coastguard Worker inline GLValue::Float abs(GLValue::Float val)
1230*35238bceSAndroid Build Coastguard Worker {
1231*35238bceSAndroid Build Coastguard Worker     return GLValue::Float::create(std::fabs(val.to<float>()));
1232*35238bceSAndroid Build Coastguard Worker }
1233*35238bceSAndroid Build Coastguard Worker 
1234*35238bceSAndroid Build Coastguard Worker template <>
abs(GLValue::Double val)1235*35238bceSAndroid Build Coastguard Worker inline GLValue::Double abs(GLValue::Double val)
1236*35238bceSAndroid Build Coastguard Worker {
1237*35238bceSAndroid Build Coastguard Worker     return GLValue::Double::create(std::fabs(val.to<float>()));
1238*35238bceSAndroid Build Coastguard Worker }
1239*35238bceSAndroid Build Coastguard Worker 
1240*35238bceSAndroid Build Coastguard Worker template <>
abs(GLValue::Uint val)1241*35238bceSAndroid Build Coastguard Worker inline GLValue::Uint abs(GLValue::Uint val)
1242*35238bceSAndroid Build Coastguard Worker {
1243*35238bceSAndroid Build Coastguard Worker     return val;
1244*35238bceSAndroid Build Coastguard Worker }
1245*35238bceSAndroid Build Coastguard Worker 
1246*35238bceSAndroid Build Coastguard Worker template <>
abs(GLValue::Int val)1247*35238bceSAndroid Build Coastguard Worker inline GLValue::Int abs(GLValue::Int val)
1248*35238bceSAndroid Build Coastguard Worker {
1249*35238bceSAndroid Build Coastguard Worker     return GLValue::Int::create(0x7FFFFFFFu & val.getValue());
1250*35238bceSAndroid Build Coastguard Worker }
1251*35238bceSAndroid Build Coastguard Worker 
1252*35238bceSAndroid Build Coastguard Worker template <>
abs(GLValue::Half val)1253*35238bceSAndroid Build Coastguard Worker inline GLValue::Half abs(GLValue::Half val)
1254*35238bceSAndroid Build Coastguard Worker {
1255*35238bceSAndroid Build Coastguard Worker     return GLValue::Half::create(std::fabs(val.to<float>()));
1256*35238bceSAndroid Build Coastguard Worker }
1257*35238bceSAndroid Build Coastguard Worker 
1258*35238bceSAndroid Build Coastguard Worker // AttributeArray
1259*35238bceSAndroid Build Coastguard Worker 
1260*35238bceSAndroid Build Coastguard Worker class AttributeArray
1261*35238bceSAndroid Build Coastguard Worker {
1262*35238bceSAndroid Build Coastguard Worker public:
1263*35238bceSAndroid Build Coastguard Worker     AttributeArray(DrawTestSpec::Storage storage, sglr::Context &context);
1264*35238bceSAndroid Build Coastguard Worker     ~AttributeArray(void);
1265*35238bceSAndroid Build Coastguard Worker 
1266*35238bceSAndroid Build Coastguard Worker     void data(DrawTestSpec::Target target, size_t size, const char *data, DrawTestSpec::Usage usage);
1267*35238bceSAndroid Build Coastguard Worker     void setupArray(bool bound, int offset, int size, DrawTestSpec::InputType inType, DrawTestSpec::OutputType outType,
1268*35238bceSAndroid Build Coastguard Worker                     bool normalized, int stride, int instanceDivisor, const rr::GenericVec4 &defaultAttrib,
1269*35238bceSAndroid Build Coastguard Worker                     bool isPositionAttr, bool bgraComponentOrder);
1270*35238bceSAndroid Build Coastguard Worker     void bindAttribute(uint32_t loc);
1271*35238bceSAndroid Build Coastguard Worker     void bindIndexArray(DrawTestSpec::Target storage);
1272*35238bceSAndroid Build Coastguard Worker 
getComponentCount(void) const1273*35238bceSAndroid Build Coastguard Worker     int getComponentCount(void) const
1274*35238bceSAndroid Build Coastguard Worker     {
1275*35238bceSAndroid Build Coastguard Worker         return m_componentCount;
1276*35238bceSAndroid Build Coastguard Worker     }
getTarget(void) const1277*35238bceSAndroid Build Coastguard Worker     DrawTestSpec::Target getTarget(void) const
1278*35238bceSAndroid Build Coastguard Worker     {
1279*35238bceSAndroid Build Coastguard Worker         return m_target;
1280*35238bceSAndroid Build Coastguard Worker     }
getInputType(void) const1281*35238bceSAndroid Build Coastguard Worker     DrawTestSpec::InputType getInputType(void) const
1282*35238bceSAndroid Build Coastguard Worker     {
1283*35238bceSAndroid Build Coastguard Worker         return m_inputType;
1284*35238bceSAndroid Build Coastguard Worker     }
getOutputType(void) const1285*35238bceSAndroid Build Coastguard Worker     DrawTestSpec::OutputType getOutputType(void) const
1286*35238bceSAndroid Build Coastguard Worker     {
1287*35238bceSAndroid Build Coastguard Worker         return m_outputType;
1288*35238bceSAndroid Build Coastguard Worker     }
getStorageType(void) const1289*35238bceSAndroid Build Coastguard Worker     DrawTestSpec::Storage getStorageType(void) const
1290*35238bceSAndroid Build Coastguard Worker     {
1291*35238bceSAndroid Build Coastguard Worker         return m_storage;
1292*35238bceSAndroid Build Coastguard Worker     }
getNormalized(void) const1293*35238bceSAndroid Build Coastguard Worker     bool getNormalized(void) const
1294*35238bceSAndroid Build Coastguard Worker     {
1295*35238bceSAndroid Build Coastguard Worker         return m_normalize;
1296*35238bceSAndroid Build Coastguard Worker     }
getStride(void) const1297*35238bceSAndroid Build Coastguard Worker     int getStride(void) const
1298*35238bceSAndroid Build Coastguard Worker     {
1299*35238bceSAndroid Build Coastguard Worker         return m_stride;
1300*35238bceSAndroid Build Coastguard Worker     }
isBound(void) const1301*35238bceSAndroid Build Coastguard Worker     bool isBound(void) const
1302*35238bceSAndroid Build Coastguard Worker     {
1303*35238bceSAndroid Build Coastguard Worker         return m_bound;
1304*35238bceSAndroid Build Coastguard Worker     }
isPositionAttribute(void) const1305*35238bceSAndroid Build Coastguard Worker     bool isPositionAttribute(void) const
1306*35238bceSAndroid Build Coastguard Worker     {
1307*35238bceSAndroid Build Coastguard Worker         return m_isPositionAttr;
1308*35238bceSAndroid Build Coastguard Worker     }
1309*35238bceSAndroid Build Coastguard Worker 
1310*35238bceSAndroid Build Coastguard Worker private:
1311*35238bceSAndroid Build Coastguard Worker     DrawTestSpec::Storage m_storage;
1312*35238bceSAndroid Build Coastguard Worker     sglr::Context &m_ctx;
1313*35238bceSAndroid Build Coastguard Worker     uint32_t m_glBuffer;
1314*35238bceSAndroid Build Coastguard Worker 
1315*35238bceSAndroid Build Coastguard Worker     int m_size;
1316*35238bceSAndroid Build Coastguard Worker     char *m_data;
1317*35238bceSAndroid Build Coastguard Worker     int m_componentCount;
1318*35238bceSAndroid Build Coastguard Worker     bool m_bound;
1319*35238bceSAndroid Build Coastguard Worker     DrawTestSpec::Target m_target;
1320*35238bceSAndroid Build Coastguard Worker     DrawTestSpec::InputType m_inputType;
1321*35238bceSAndroid Build Coastguard Worker     DrawTestSpec::OutputType m_outputType;
1322*35238bceSAndroid Build Coastguard Worker     bool m_normalize;
1323*35238bceSAndroid Build Coastguard Worker     int m_stride;
1324*35238bceSAndroid Build Coastguard Worker     int m_offset;
1325*35238bceSAndroid Build Coastguard Worker     rr::GenericVec4 m_defaultAttrib;
1326*35238bceSAndroid Build Coastguard Worker     int m_instanceDivisor;
1327*35238bceSAndroid Build Coastguard Worker     bool m_isPositionAttr;
1328*35238bceSAndroid Build Coastguard Worker     bool m_bgraOrder;
1329*35238bceSAndroid Build Coastguard Worker };
1330*35238bceSAndroid Build Coastguard Worker 
AttributeArray(DrawTestSpec::Storage storage,sglr::Context & context)1331*35238bceSAndroid Build Coastguard Worker AttributeArray::AttributeArray(DrawTestSpec::Storage storage, sglr::Context &context)
1332*35238bceSAndroid Build Coastguard Worker     : m_storage(storage)
1333*35238bceSAndroid Build Coastguard Worker     , m_ctx(context)
1334*35238bceSAndroid Build Coastguard Worker     , m_glBuffer(0)
1335*35238bceSAndroid Build Coastguard Worker     , m_size(0)
1336*35238bceSAndroid Build Coastguard Worker     , m_data(DE_NULL)
1337*35238bceSAndroid Build Coastguard Worker     , m_componentCount(1)
1338*35238bceSAndroid Build Coastguard Worker     , m_bound(false)
1339*35238bceSAndroid Build Coastguard Worker     , m_target(DrawTestSpec::TARGET_ARRAY)
1340*35238bceSAndroid Build Coastguard Worker     , m_inputType(DrawTestSpec::INPUTTYPE_FLOAT)
1341*35238bceSAndroid Build Coastguard Worker     , m_outputType(DrawTestSpec::OUTPUTTYPE_VEC4)
1342*35238bceSAndroid Build Coastguard Worker     , m_normalize(false)
1343*35238bceSAndroid Build Coastguard Worker     , m_stride(0)
1344*35238bceSAndroid Build Coastguard Worker     , m_offset(0)
1345*35238bceSAndroid Build Coastguard Worker     , m_instanceDivisor(0)
1346*35238bceSAndroid Build Coastguard Worker     , m_isPositionAttr(false)
1347*35238bceSAndroid Build Coastguard Worker     , m_bgraOrder(false)
1348*35238bceSAndroid Build Coastguard Worker {
1349*35238bceSAndroid Build Coastguard Worker     if (m_storage == DrawTestSpec::STORAGE_BUFFER)
1350*35238bceSAndroid Build Coastguard Worker     {
1351*35238bceSAndroid Build Coastguard Worker         m_ctx.genBuffers(1, &m_glBuffer);
1352*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glGenBuffers()");
1353*35238bceSAndroid Build Coastguard Worker     }
1354*35238bceSAndroid Build Coastguard Worker }
1355*35238bceSAndroid Build Coastguard Worker 
~AttributeArray(void)1356*35238bceSAndroid Build Coastguard Worker AttributeArray::~AttributeArray(void)
1357*35238bceSAndroid Build Coastguard Worker {
1358*35238bceSAndroid Build Coastguard Worker     if (m_storage == DrawTestSpec::STORAGE_BUFFER)
1359*35238bceSAndroid Build Coastguard Worker     {
1360*35238bceSAndroid Build Coastguard Worker         m_ctx.deleteBuffers(1, &m_glBuffer);
1361*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDeleteBuffers()");
1362*35238bceSAndroid Build Coastguard Worker     }
1363*35238bceSAndroid Build Coastguard Worker     else if (m_storage == DrawTestSpec::STORAGE_USER)
1364*35238bceSAndroid Build Coastguard Worker         delete[] m_data;
1365*35238bceSAndroid Build Coastguard Worker     else
1366*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1367*35238bceSAndroid Build Coastguard Worker }
1368*35238bceSAndroid Build Coastguard Worker 
data(DrawTestSpec::Target target,size_t size,const char * ptr,DrawTestSpec::Usage usage)1369*35238bceSAndroid Build Coastguard Worker void AttributeArray::data(DrawTestSpec::Target target, size_t size, const char *ptr, DrawTestSpec::Usage usage)
1370*35238bceSAndroid Build Coastguard Worker {
1371*35238bceSAndroid Build Coastguard Worker     m_size   = (int)size;
1372*35238bceSAndroid Build Coastguard Worker     m_target = target;
1373*35238bceSAndroid Build Coastguard Worker 
1374*35238bceSAndroid Build Coastguard Worker     if (m_storage == DrawTestSpec::STORAGE_BUFFER)
1375*35238bceSAndroid Build Coastguard Worker     {
1376*35238bceSAndroid Build Coastguard Worker         m_ctx.bindBuffer(targetToGL(target), m_glBuffer);
1377*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glBindBuffer()");
1378*35238bceSAndroid Build Coastguard Worker 
1379*35238bceSAndroid Build Coastguard Worker         m_ctx.bufferData(targetToGL(target), size, ptr, usageToGL(usage));
1380*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glBufferData()");
1381*35238bceSAndroid Build Coastguard Worker     }
1382*35238bceSAndroid Build Coastguard Worker     else if (m_storage == DrawTestSpec::STORAGE_USER)
1383*35238bceSAndroid Build Coastguard Worker     {
1384*35238bceSAndroid Build Coastguard Worker         if (m_data)
1385*35238bceSAndroid Build Coastguard Worker             delete[] m_data;
1386*35238bceSAndroid Build Coastguard Worker 
1387*35238bceSAndroid Build Coastguard Worker         m_data = new char[size];
1388*35238bceSAndroid Build Coastguard Worker         std::memcpy(m_data, ptr, size);
1389*35238bceSAndroid Build Coastguard Worker     }
1390*35238bceSAndroid Build Coastguard Worker     else
1391*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1392*35238bceSAndroid Build Coastguard Worker }
1393*35238bceSAndroid Build Coastguard Worker 
setupArray(bool bound,int offset,int size,DrawTestSpec::InputType inputType,DrawTestSpec::OutputType outType,bool normalized,int stride,int instanceDivisor,const rr::GenericVec4 & defaultAttrib,bool isPositionAttr,bool bgraComponentOrder)1394*35238bceSAndroid Build Coastguard Worker void AttributeArray::setupArray(bool bound, int offset, int size, DrawTestSpec::InputType inputType,
1395*35238bceSAndroid Build Coastguard Worker                                 DrawTestSpec::OutputType outType, bool normalized, int stride, int instanceDivisor,
1396*35238bceSAndroid Build Coastguard Worker                                 const rr::GenericVec4 &defaultAttrib, bool isPositionAttr, bool bgraComponentOrder)
1397*35238bceSAndroid Build Coastguard Worker {
1398*35238bceSAndroid Build Coastguard Worker     m_componentCount  = size;
1399*35238bceSAndroid Build Coastguard Worker     m_bound           = bound;
1400*35238bceSAndroid Build Coastguard Worker     m_inputType       = inputType;
1401*35238bceSAndroid Build Coastguard Worker     m_outputType      = outType;
1402*35238bceSAndroid Build Coastguard Worker     m_normalize       = normalized;
1403*35238bceSAndroid Build Coastguard Worker     m_stride          = stride;
1404*35238bceSAndroid Build Coastguard Worker     m_offset          = offset;
1405*35238bceSAndroid Build Coastguard Worker     m_defaultAttrib   = defaultAttrib;
1406*35238bceSAndroid Build Coastguard Worker     m_instanceDivisor = instanceDivisor;
1407*35238bceSAndroid Build Coastguard Worker     m_isPositionAttr  = isPositionAttr;
1408*35238bceSAndroid Build Coastguard Worker     m_bgraOrder       = bgraComponentOrder;
1409*35238bceSAndroid Build Coastguard Worker }
1410*35238bceSAndroid Build Coastguard Worker 
bindAttribute(uint32_t loc)1411*35238bceSAndroid Build Coastguard Worker void AttributeArray::bindAttribute(uint32_t loc)
1412*35238bceSAndroid Build Coastguard Worker {
1413*35238bceSAndroid Build Coastguard Worker     if (!isBound())
1414*35238bceSAndroid Build Coastguard Worker     {
1415*35238bceSAndroid Build Coastguard Worker         switch (m_inputType)
1416*35238bceSAndroid Build Coastguard Worker         {
1417*35238bceSAndroid Build Coastguard Worker         case DrawTestSpec::INPUTTYPE_FLOAT:
1418*35238bceSAndroid Build Coastguard Worker         {
1419*35238bceSAndroid Build Coastguard Worker             tcu::Vec4 attr = m_defaultAttrib.get<float>();
1420*35238bceSAndroid Build Coastguard Worker 
1421*35238bceSAndroid Build Coastguard Worker             switch (m_componentCount)
1422*35238bceSAndroid Build Coastguard Worker             {
1423*35238bceSAndroid Build Coastguard Worker             case 1:
1424*35238bceSAndroid Build Coastguard Worker                 m_ctx.vertexAttrib1f(loc, attr.x());
1425*35238bceSAndroid Build Coastguard Worker                 break;
1426*35238bceSAndroid Build Coastguard Worker             case 2:
1427*35238bceSAndroid Build Coastguard Worker                 m_ctx.vertexAttrib2f(loc, attr.x(), attr.y());
1428*35238bceSAndroid Build Coastguard Worker                 break;
1429*35238bceSAndroid Build Coastguard Worker             case 3:
1430*35238bceSAndroid Build Coastguard Worker                 m_ctx.vertexAttrib3f(loc, attr.x(), attr.y(), attr.z());
1431*35238bceSAndroid Build Coastguard Worker                 break;
1432*35238bceSAndroid Build Coastguard Worker             case 4:
1433*35238bceSAndroid Build Coastguard Worker                 m_ctx.vertexAttrib4f(loc, attr.x(), attr.y(), attr.z(), attr.w());
1434*35238bceSAndroid Build Coastguard Worker                 break;
1435*35238bceSAndroid Build Coastguard Worker             default:
1436*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(false);
1437*35238bceSAndroid Build Coastguard Worker                 break;
1438*35238bceSAndroid Build Coastguard Worker             }
1439*35238bceSAndroid Build Coastguard Worker             break;
1440*35238bceSAndroid Build Coastguard Worker         }
1441*35238bceSAndroid Build Coastguard Worker         case DrawTestSpec::INPUTTYPE_INT:
1442*35238bceSAndroid Build Coastguard Worker         {
1443*35238bceSAndroid Build Coastguard Worker             tcu::IVec4 attr = m_defaultAttrib.get<int32_t>();
1444*35238bceSAndroid Build Coastguard Worker             m_ctx.vertexAttribI4i(loc, attr.x(), attr.y(), attr.z(), attr.w());
1445*35238bceSAndroid Build Coastguard Worker             break;
1446*35238bceSAndroid Build Coastguard Worker         }
1447*35238bceSAndroid Build Coastguard Worker         case DrawTestSpec::INPUTTYPE_UNSIGNED_INT:
1448*35238bceSAndroid Build Coastguard Worker         {
1449*35238bceSAndroid Build Coastguard Worker             tcu::UVec4 attr = m_defaultAttrib.get<uint32_t>();
1450*35238bceSAndroid Build Coastguard Worker             m_ctx.vertexAttribI4ui(loc, attr.x(), attr.y(), attr.z(), attr.w());
1451*35238bceSAndroid Build Coastguard Worker             break;
1452*35238bceSAndroid Build Coastguard Worker         }
1453*35238bceSAndroid Build Coastguard Worker         default:
1454*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
1455*35238bceSAndroid Build Coastguard Worker             break;
1456*35238bceSAndroid Build Coastguard Worker         }
1457*35238bceSAndroid Build Coastguard Worker     }
1458*35238bceSAndroid Build Coastguard Worker     else
1459*35238bceSAndroid Build Coastguard Worker     {
1460*35238bceSAndroid Build Coastguard Worker         const uint8_t *basePtr = DE_NULL;
1461*35238bceSAndroid Build Coastguard Worker 
1462*35238bceSAndroid Build Coastguard Worker         if (m_storage == DrawTestSpec::STORAGE_BUFFER)
1463*35238bceSAndroid Build Coastguard Worker         {
1464*35238bceSAndroid Build Coastguard Worker             m_ctx.bindBuffer(targetToGL(m_target), m_glBuffer);
1465*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glBindBuffer()");
1466*35238bceSAndroid Build Coastguard Worker 
1467*35238bceSAndroid Build Coastguard Worker             basePtr = DE_NULL;
1468*35238bceSAndroid Build Coastguard Worker         }
1469*35238bceSAndroid Build Coastguard Worker         else if (m_storage == DrawTestSpec::STORAGE_USER)
1470*35238bceSAndroid Build Coastguard Worker         {
1471*35238bceSAndroid Build Coastguard Worker             m_ctx.bindBuffer(targetToGL(m_target), 0);
1472*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glBindBuffer()");
1473*35238bceSAndroid Build Coastguard Worker 
1474*35238bceSAndroid Build Coastguard Worker             basePtr = (const uint8_t *)m_data;
1475*35238bceSAndroid Build Coastguard Worker         }
1476*35238bceSAndroid Build Coastguard Worker         else
1477*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
1478*35238bceSAndroid Build Coastguard Worker 
1479*35238bceSAndroid Build Coastguard Worker         if (!inputTypeIsFloatType(m_inputType))
1480*35238bceSAndroid Build Coastguard Worker         {
1481*35238bceSAndroid Build Coastguard Worker             // Input is not float type
1482*35238bceSAndroid Build Coastguard Worker 
1483*35238bceSAndroid Build Coastguard Worker             if (outputTypeIsFloatType(m_outputType))
1484*35238bceSAndroid Build Coastguard Worker             {
1485*35238bceSAndroid Build Coastguard Worker                 const int size = (m_bgraOrder) ? (GL_BGRA) : (m_componentCount);
1486*35238bceSAndroid Build Coastguard Worker 
1487*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(!(m_bgraOrder && m_componentCount != 4));
1488*35238bceSAndroid Build Coastguard Worker 
1489*35238bceSAndroid Build Coastguard Worker                 // Output type is float type
1490*35238bceSAndroid Build Coastguard Worker                 m_ctx.vertexAttribPointer(loc, size, inputTypeToGL(m_inputType), m_normalize, m_stride,
1491*35238bceSAndroid Build Coastguard Worker                                           basePtr + m_offset);
1492*35238bceSAndroid Build Coastguard Worker                 GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glVertexAttribPointer()");
1493*35238bceSAndroid Build Coastguard Worker             }
1494*35238bceSAndroid Build Coastguard Worker             else
1495*35238bceSAndroid Build Coastguard Worker             {
1496*35238bceSAndroid Build Coastguard Worker                 // Output type is int type
1497*35238bceSAndroid Build Coastguard Worker                 m_ctx.vertexAttribIPointer(loc, m_componentCount, inputTypeToGL(m_inputType), m_stride,
1498*35238bceSAndroid Build Coastguard Worker                                            basePtr + m_offset);
1499*35238bceSAndroid Build Coastguard Worker                 GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glVertexAttribIPointer()");
1500*35238bceSAndroid Build Coastguard Worker             }
1501*35238bceSAndroid Build Coastguard Worker         }
1502*35238bceSAndroid Build Coastguard Worker         else
1503*35238bceSAndroid Build Coastguard Worker         {
1504*35238bceSAndroid Build Coastguard Worker             // Input type is float type
1505*35238bceSAndroid Build Coastguard Worker 
1506*35238bceSAndroid Build Coastguard Worker             // Output type must be float type
1507*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(outputTypeIsFloatType(m_outputType));
1508*35238bceSAndroid Build Coastguard Worker 
1509*35238bceSAndroid Build Coastguard Worker             m_ctx.vertexAttribPointer(loc, m_componentCount, inputTypeToGL(m_inputType), m_normalize, m_stride,
1510*35238bceSAndroid Build Coastguard Worker                                       basePtr + m_offset);
1511*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glVertexAttribPointer()");
1512*35238bceSAndroid Build Coastguard Worker         }
1513*35238bceSAndroid Build Coastguard Worker 
1514*35238bceSAndroid Build Coastguard Worker         if (m_instanceDivisor)
1515*35238bceSAndroid Build Coastguard Worker             m_ctx.vertexAttribDivisor(loc, m_instanceDivisor);
1516*35238bceSAndroid Build Coastguard Worker     }
1517*35238bceSAndroid Build Coastguard Worker }
1518*35238bceSAndroid Build Coastguard Worker 
bindIndexArray(DrawTestSpec::Target target)1519*35238bceSAndroid Build Coastguard Worker void AttributeArray::bindIndexArray(DrawTestSpec::Target target)
1520*35238bceSAndroid Build Coastguard Worker {
1521*35238bceSAndroid Build Coastguard Worker     if (m_storage == DrawTestSpec::STORAGE_USER)
1522*35238bceSAndroid Build Coastguard Worker     {
1523*35238bceSAndroid Build Coastguard Worker     }
1524*35238bceSAndroid Build Coastguard Worker     else if (m_storage == DrawTestSpec::STORAGE_BUFFER)
1525*35238bceSAndroid Build Coastguard Worker     {
1526*35238bceSAndroid Build Coastguard Worker         m_ctx.bindBuffer(targetToGL(target), m_glBuffer);
1527*35238bceSAndroid Build Coastguard Worker     }
1528*35238bceSAndroid Build Coastguard Worker }
1529*35238bceSAndroid Build Coastguard Worker 
1530*35238bceSAndroid Build Coastguard Worker // DrawTestShaderProgram
1531*35238bceSAndroid Build Coastguard Worker 
1532*35238bceSAndroid Build Coastguard Worker class DrawTestShaderProgram : public sglr::ShaderProgram
1533*35238bceSAndroid Build Coastguard Worker {
1534*35238bceSAndroid Build Coastguard Worker public:
1535*35238bceSAndroid Build Coastguard Worker     DrawTestShaderProgram(const glu::RenderContext &ctx, const std::vector<AttributeArray *> &arrays);
1536*35238bceSAndroid Build Coastguard Worker 
1537*35238bceSAndroid Build Coastguard Worker     void shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets, const int numPackets) const;
1538*35238bceSAndroid Build Coastguard Worker     void shadeFragments(rr::FragmentPacket *packets, const int numPackets,
1539*35238bceSAndroid Build Coastguard Worker                         const rr::FragmentShadingContext &context) const;
1540*35238bceSAndroid Build Coastguard Worker 
1541*35238bceSAndroid Build Coastguard Worker private:
1542*35238bceSAndroid Build Coastguard Worker     static std::string genVertexSource(const glu::RenderContext &ctx, const std::vector<AttributeArray *> &arrays);
1543*35238bceSAndroid Build Coastguard Worker     static std::string genFragmentSource(const glu::RenderContext &ctx);
1544*35238bceSAndroid Build Coastguard Worker     static void generateShaderParams(std::map<std::string, std::string> &params, glu::ContextType type);
1545*35238bceSAndroid Build Coastguard Worker     static rr::GenericVecType mapOutputType(const DrawTestSpec::OutputType &type);
1546*35238bceSAndroid Build Coastguard Worker     static int getComponentCount(const DrawTestSpec::OutputType &type);
1547*35238bceSAndroid Build Coastguard Worker 
1548*35238bceSAndroid Build Coastguard Worker     static sglr::pdec::ShaderProgramDeclaration createProgramDeclaration(const glu::RenderContext &ctx,
1549*35238bceSAndroid Build Coastguard Worker                                                                          const std::vector<AttributeArray *> &arrays);
1550*35238bceSAndroid Build Coastguard Worker 
1551*35238bceSAndroid Build Coastguard Worker     std::vector<int> m_componentCount;
1552*35238bceSAndroid Build Coastguard Worker     std::vector<bool> m_isCoord;
1553*35238bceSAndroid Build Coastguard Worker     std::vector<rr::GenericVecType> m_attrType;
1554*35238bceSAndroid Build Coastguard Worker };
1555*35238bceSAndroid Build Coastguard Worker 
DrawTestShaderProgram(const glu::RenderContext & ctx,const std::vector<AttributeArray * > & arrays)1556*35238bceSAndroid Build Coastguard Worker DrawTestShaderProgram::DrawTestShaderProgram(const glu::RenderContext &ctx, const std::vector<AttributeArray *> &arrays)
1557*35238bceSAndroid Build Coastguard Worker     : sglr::ShaderProgram(createProgramDeclaration(ctx, arrays))
1558*35238bceSAndroid Build Coastguard Worker     , m_componentCount(arrays.size())
1559*35238bceSAndroid Build Coastguard Worker     , m_isCoord(arrays.size())
1560*35238bceSAndroid Build Coastguard Worker     , m_attrType(arrays.size())
1561*35238bceSAndroid Build Coastguard Worker {
1562*35238bceSAndroid Build Coastguard Worker     for (int arrayNdx = 0; arrayNdx < (int)arrays.size(); arrayNdx++)
1563*35238bceSAndroid Build Coastguard Worker     {
1564*35238bceSAndroid Build Coastguard Worker         m_componentCount[arrayNdx] = getComponentCount(arrays[arrayNdx]->getOutputType());
1565*35238bceSAndroid Build Coastguard Worker         m_isCoord[arrayNdx]        = arrays[arrayNdx]->isPositionAttribute();
1566*35238bceSAndroid Build Coastguard Worker         m_attrType[arrayNdx]       = mapOutputType(arrays[arrayNdx]->getOutputType());
1567*35238bceSAndroid Build Coastguard Worker     }
1568*35238bceSAndroid Build Coastguard Worker }
1569*35238bceSAndroid Build Coastguard Worker 
1570*35238bceSAndroid Build Coastguard Worker template <typename T>
calcShaderColorCoord(tcu::Vec2 & coord,tcu::Vec3 & color,const tcu::Vector<T,4> & attribValue,bool isCoordinate,int numComponents)1571*35238bceSAndroid Build Coastguard Worker void calcShaderColorCoord(tcu::Vec2 &coord, tcu::Vec3 &color, const tcu::Vector<T, 4> &attribValue, bool isCoordinate,
1572*35238bceSAndroid Build Coastguard Worker                           int numComponents)
1573*35238bceSAndroid Build Coastguard Worker {
1574*35238bceSAndroid Build Coastguard Worker     if (isCoordinate)
1575*35238bceSAndroid Build Coastguard Worker         switch (numComponents)
1576*35238bceSAndroid Build Coastguard Worker         {
1577*35238bceSAndroid Build Coastguard Worker         case 1:
1578*35238bceSAndroid Build Coastguard Worker             coord += tcu::Vec2((float)attribValue.x(), (float)attribValue.x());
1579*35238bceSAndroid Build Coastguard Worker             break;
1580*35238bceSAndroid Build Coastguard Worker         case 2:
1581*35238bceSAndroid Build Coastguard Worker             coord += tcu::Vec2((float)attribValue.x(), (float)attribValue.y());
1582*35238bceSAndroid Build Coastguard Worker             break;
1583*35238bceSAndroid Build Coastguard Worker         case 3:
1584*35238bceSAndroid Build Coastguard Worker             coord += tcu::Vec2((float)attribValue.x() + (float)attribValue.z(), (float)attribValue.y());
1585*35238bceSAndroid Build Coastguard Worker             break;
1586*35238bceSAndroid Build Coastguard Worker         case 4:
1587*35238bceSAndroid Build Coastguard Worker             coord += tcu::Vec2((float)attribValue.x() + (float)attribValue.z(),
1588*35238bceSAndroid Build Coastguard Worker                                (float)attribValue.y() + (float)attribValue.w());
1589*35238bceSAndroid Build Coastguard Worker             break;
1590*35238bceSAndroid Build Coastguard Worker 
1591*35238bceSAndroid Build Coastguard Worker         default:
1592*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
1593*35238bceSAndroid Build Coastguard Worker         }
1594*35238bceSAndroid Build Coastguard Worker     else
1595*35238bceSAndroid Build Coastguard Worker     {
1596*35238bceSAndroid Build Coastguard Worker         switch (numComponents)
1597*35238bceSAndroid Build Coastguard Worker         {
1598*35238bceSAndroid Build Coastguard Worker         case 1:
1599*35238bceSAndroid Build Coastguard Worker             color = color * (float)attribValue.x();
1600*35238bceSAndroid Build Coastguard Worker             break;
1601*35238bceSAndroid Build Coastguard Worker 
1602*35238bceSAndroid Build Coastguard Worker         case 2:
1603*35238bceSAndroid Build Coastguard Worker             color.x() = color.x() * (float)attribValue.x();
1604*35238bceSAndroid Build Coastguard Worker             color.y() = color.y() * (float)attribValue.y();
1605*35238bceSAndroid Build Coastguard Worker             break;
1606*35238bceSAndroid Build Coastguard Worker 
1607*35238bceSAndroid Build Coastguard Worker         case 3:
1608*35238bceSAndroid Build Coastguard Worker             color.x() = color.x() * (float)attribValue.x();
1609*35238bceSAndroid Build Coastguard Worker             color.y() = color.y() * (float)attribValue.y();
1610*35238bceSAndroid Build Coastguard Worker             color.z() = color.z() * (float)attribValue.z();
1611*35238bceSAndroid Build Coastguard Worker             break;
1612*35238bceSAndroid Build Coastguard Worker 
1613*35238bceSAndroid Build Coastguard Worker         case 4:
1614*35238bceSAndroid Build Coastguard Worker             color.x() = color.x() * (float)attribValue.x() * (float)attribValue.w();
1615*35238bceSAndroid Build Coastguard Worker             color.y() = color.y() * (float)attribValue.y() * (float)attribValue.w();
1616*35238bceSAndroid Build Coastguard Worker             color.z() = color.z() * (float)attribValue.z() * (float)attribValue.w();
1617*35238bceSAndroid Build Coastguard Worker             break;
1618*35238bceSAndroid Build Coastguard Worker 
1619*35238bceSAndroid Build Coastguard Worker         default:
1620*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
1621*35238bceSAndroid Build Coastguard Worker         }
1622*35238bceSAndroid Build Coastguard Worker     }
1623*35238bceSAndroid Build Coastguard Worker }
1624*35238bceSAndroid Build Coastguard Worker 
shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const1625*35238bceSAndroid Build Coastguard Worker void DrawTestShaderProgram::shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets,
1626*35238bceSAndroid Build Coastguard Worker                                           const int numPackets) const
1627*35238bceSAndroid Build Coastguard Worker {
1628*35238bceSAndroid Build Coastguard Worker     const float u_coordScale = getUniformByName("u_coordScale").value.f;
1629*35238bceSAndroid Build Coastguard Worker     const float u_colorScale = getUniformByName("u_colorScale").value.f;
1630*35238bceSAndroid Build Coastguard Worker 
1631*35238bceSAndroid Build Coastguard Worker     for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
1632*35238bceSAndroid Build Coastguard Worker     {
1633*35238bceSAndroid Build Coastguard Worker         const size_t varyingLocColor = 0;
1634*35238bceSAndroid Build Coastguard Worker 
1635*35238bceSAndroid Build Coastguard Worker         rr::VertexPacket &packet = *packets[packetNdx];
1636*35238bceSAndroid Build Coastguard Worker 
1637*35238bceSAndroid Build Coastguard Worker         // Calc output color
1638*35238bceSAndroid Build Coastguard Worker         tcu::Vec2 coord = tcu::Vec2(0.0, 0.0);
1639*35238bceSAndroid Build Coastguard Worker         tcu::Vec3 color = tcu::Vec3(1.0, 1.0, 1.0);
1640*35238bceSAndroid Build Coastguard Worker 
1641*35238bceSAndroid Build Coastguard Worker         for (int attribNdx = 0; attribNdx < (int)m_attrType.size(); attribNdx++)
1642*35238bceSAndroid Build Coastguard Worker         {
1643*35238bceSAndroid Build Coastguard Worker             const int numComponents = m_componentCount[attribNdx];
1644*35238bceSAndroid Build Coastguard Worker             const bool isCoord      = m_isCoord[attribNdx];
1645*35238bceSAndroid Build Coastguard Worker 
1646*35238bceSAndroid Build Coastguard Worker             switch (m_attrType[attribNdx])
1647*35238bceSAndroid Build Coastguard Worker             {
1648*35238bceSAndroid Build Coastguard Worker             case rr::GENERICVECTYPE_FLOAT:
1649*35238bceSAndroid Build Coastguard Worker                 calcShaderColorCoord(coord, color,
1650*35238bceSAndroid Build Coastguard Worker                                      rr::readVertexAttribFloat(inputs[attribNdx], packet.instanceNdx, packet.vertexNdx),
1651*35238bceSAndroid Build Coastguard Worker                                      isCoord, numComponents);
1652*35238bceSAndroid Build Coastguard Worker                 break;
1653*35238bceSAndroid Build Coastguard Worker             case rr::GENERICVECTYPE_INT32:
1654*35238bceSAndroid Build Coastguard Worker                 calcShaderColorCoord(coord, color,
1655*35238bceSAndroid Build Coastguard Worker                                      rr::readVertexAttribInt(inputs[attribNdx], packet.instanceNdx, packet.vertexNdx),
1656*35238bceSAndroid Build Coastguard Worker                                      isCoord, numComponents);
1657*35238bceSAndroid Build Coastguard Worker                 break;
1658*35238bceSAndroid Build Coastguard Worker             case rr::GENERICVECTYPE_UINT32:
1659*35238bceSAndroid Build Coastguard Worker                 calcShaderColorCoord(coord, color,
1660*35238bceSAndroid Build Coastguard Worker                                      rr::readVertexAttribUint(inputs[attribNdx], packet.instanceNdx, packet.vertexNdx),
1661*35238bceSAndroid Build Coastguard Worker                                      isCoord, numComponents);
1662*35238bceSAndroid Build Coastguard Worker                 break;
1663*35238bceSAndroid Build Coastguard Worker             default:
1664*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(false);
1665*35238bceSAndroid Build Coastguard Worker             }
1666*35238bceSAndroid Build Coastguard Worker         }
1667*35238bceSAndroid Build Coastguard Worker 
1668*35238bceSAndroid Build Coastguard Worker         // Transform position
1669*35238bceSAndroid Build Coastguard Worker         {
1670*35238bceSAndroid Build Coastguard Worker             packet.position  = tcu::Vec4(u_coordScale * coord.x(), u_coordScale * coord.y(), 1.0f, 1.0f);
1671*35238bceSAndroid Build Coastguard Worker             packet.pointSize = 1.0f;
1672*35238bceSAndroid Build Coastguard Worker         }
1673*35238bceSAndroid Build Coastguard Worker 
1674*35238bceSAndroid Build Coastguard Worker         // Pass color to FS
1675*35238bceSAndroid Build Coastguard Worker         {
1676*35238bceSAndroid Build Coastguard Worker             packet.outputs[varyingLocColor] =
1677*35238bceSAndroid Build Coastguard Worker                 tcu::Vec4(u_colorScale * color.x(), u_colorScale * color.y(), u_colorScale * color.z(), 1.0f) * 0.5f +
1678*35238bceSAndroid Build Coastguard Worker                 tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f);
1679*35238bceSAndroid Build Coastguard Worker         }
1680*35238bceSAndroid Build Coastguard Worker     }
1681*35238bceSAndroid Build Coastguard Worker }
1682*35238bceSAndroid Build Coastguard Worker 
shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const1683*35238bceSAndroid Build Coastguard Worker void DrawTestShaderProgram::shadeFragments(rr::FragmentPacket *packets, const int numPackets,
1684*35238bceSAndroid Build Coastguard Worker                                            const rr::FragmentShadingContext &context) const
1685*35238bceSAndroid Build Coastguard Worker {
1686*35238bceSAndroid Build Coastguard Worker     const size_t varyingLocColor = 0;
1687*35238bceSAndroid Build Coastguard Worker 
1688*35238bceSAndroid Build Coastguard Worker     for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
1689*35238bceSAndroid Build Coastguard Worker     {
1690*35238bceSAndroid Build Coastguard Worker         rr::FragmentPacket &packet = packets[packetNdx];
1691*35238bceSAndroid Build Coastguard Worker 
1692*35238bceSAndroid Build Coastguard Worker         for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
1693*35238bceSAndroid Build Coastguard Worker             rr::writeFragmentOutput(context, packetNdx, fragNdx, 0,
1694*35238bceSAndroid Build Coastguard Worker                                     rr::readVarying<float>(packet, context, varyingLocColor, fragNdx));
1695*35238bceSAndroid Build Coastguard Worker     }
1696*35238bceSAndroid Build Coastguard Worker }
1697*35238bceSAndroid Build Coastguard Worker 
genVertexSource(const glu::RenderContext & ctx,const std::vector<AttributeArray * > & arrays)1698*35238bceSAndroid Build Coastguard Worker std::string DrawTestShaderProgram::genVertexSource(const glu::RenderContext &ctx,
1699*35238bceSAndroid Build Coastguard Worker                                                    const std::vector<AttributeArray *> &arrays)
1700*35238bceSAndroid Build Coastguard Worker {
1701*35238bceSAndroid Build Coastguard Worker     std::map<std::string, std::string> params;
1702*35238bceSAndroid Build Coastguard Worker     std::stringstream vertexShaderTmpl;
1703*35238bceSAndroid Build Coastguard Worker 
1704*35238bceSAndroid Build Coastguard Worker     generateShaderParams(params, ctx.getType());
1705*35238bceSAndroid Build Coastguard Worker 
1706*35238bceSAndroid Build Coastguard Worker     vertexShaderTmpl << "${VTX_HDR}";
1707*35238bceSAndroid Build Coastguard Worker 
1708*35238bceSAndroid Build Coastguard Worker     for (int arrayNdx = 0; arrayNdx < (int)arrays.size(); arrayNdx++)
1709*35238bceSAndroid Build Coastguard Worker     {
1710*35238bceSAndroid Build Coastguard Worker         vertexShaderTmpl << "${VTX_IN} highp " << outputTypeToGLType(arrays[arrayNdx]->getOutputType()) << " a_"
1711*35238bceSAndroid Build Coastguard Worker                          << arrayNdx << ";\n";
1712*35238bceSAndroid Build Coastguard Worker     }
1713*35238bceSAndroid Build Coastguard Worker 
1714*35238bceSAndroid Build Coastguard Worker     vertexShaderTmpl << "uniform highp float u_coordScale;\n"
1715*35238bceSAndroid Build Coastguard Worker                         "uniform highp float u_colorScale;\n"
1716*35238bceSAndroid Build Coastguard Worker                         "${VTX_OUT} ${COL_PRECISION} vec4 v_color;\n"
1717*35238bceSAndroid Build Coastguard Worker                         "void main(void)\n"
1718*35238bceSAndroid Build Coastguard Worker                         "{\n"
1719*35238bceSAndroid Build Coastguard Worker                         "\tgl_PointSize = 1.0;\n"
1720*35238bceSAndroid Build Coastguard Worker                         "\thighp vec2 coord = vec2(0.0, 0.0);\n"
1721*35238bceSAndroid Build Coastguard Worker                         "\thighp vec3 color = vec3(1.0, 1.0, 1.0);\n";
1722*35238bceSAndroid Build Coastguard Worker 
1723*35238bceSAndroid Build Coastguard Worker     for (int arrayNdx = 0; arrayNdx < (int)arrays.size(); arrayNdx++)
1724*35238bceSAndroid Build Coastguard Worker     {
1725*35238bceSAndroid Build Coastguard Worker         const bool isPositionAttr = arrays[arrayNdx]->isPositionAttribute();
1726*35238bceSAndroid Build Coastguard Worker 
1727*35238bceSAndroid Build Coastguard Worker         if (isPositionAttr)
1728*35238bceSAndroid Build Coastguard Worker         {
1729*35238bceSAndroid Build Coastguard Worker             switch (arrays[arrayNdx]->getOutputType())
1730*35238bceSAndroid Build Coastguard Worker             {
1731*35238bceSAndroid Build Coastguard Worker             case (DrawTestSpec::OUTPUTTYPE_FLOAT):
1732*35238bceSAndroid Build Coastguard Worker             case (DrawTestSpec::OUTPUTTYPE_INT):
1733*35238bceSAndroid Build Coastguard Worker             case (DrawTestSpec::OUTPUTTYPE_UINT):
1734*35238bceSAndroid Build Coastguard Worker                 vertexShaderTmpl << "\tcoord += vec2(float(a_" << arrayNdx << "), float(a_" << arrayNdx << "));\n";
1735*35238bceSAndroid Build Coastguard Worker                 break;
1736*35238bceSAndroid Build Coastguard Worker 
1737*35238bceSAndroid Build Coastguard Worker             case (DrawTestSpec::OUTPUTTYPE_VEC2):
1738*35238bceSAndroid Build Coastguard Worker             case (DrawTestSpec::OUTPUTTYPE_IVEC2):
1739*35238bceSAndroid Build Coastguard Worker             case (DrawTestSpec::OUTPUTTYPE_UVEC2):
1740*35238bceSAndroid Build Coastguard Worker                 vertexShaderTmpl << "\tcoord += vec2(a_" << arrayNdx << ".xy);\n";
1741*35238bceSAndroid Build Coastguard Worker                 break;
1742*35238bceSAndroid Build Coastguard Worker 
1743*35238bceSAndroid Build Coastguard Worker             case (DrawTestSpec::OUTPUTTYPE_VEC3):
1744*35238bceSAndroid Build Coastguard Worker             case (DrawTestSpec::OUTPUTTYPE_IVEC3):
1745*35238bceSAndroid Build Coastguard Worker             case (DrawTestSpec::OUTPUTTYPE_UVEC3):
1746*35238bceSAndroid Build Coastguard Worker                 vertexShaderTmpl << "\tcoord += vec2(a_" << arrayNdx
1747*35238bceSAndroid Build Coastguard Worker                                  << ".xy);\n"
1748*35238bceSAndroid Build Coastguard Worker                                     "\tcoord.x += float(a_"
1749*35238bceSAndroid Build Coastguard Worker                                  << arrayNdx << ".z);\n";
1750*35238bceSAndroid Build Coastguard Worker                 break;
1751*35238bceSAndroid Build Coastguard Worker 
1752*35238bceSAndroid Build Coastguard Worker             case (DrawTestSpec::OUTPUTTYPE_VEC4):
1753*35238bceSAndroid Build Coastguard Worker             case (DrawTestSpec::OUTPUTTYPE_IVEC4):
1754*35238bceSAndroid Build Coastguard Worker             case (DrawTestSpec::OUTPUTTYPE_UVEC4):
1755*35238bceSAndroid Build Coastguard Worker                 vertexShaderTmpl << "\tcoord += vec2(a_" << arrayNdx
1756*35238bceSAndroid Build Coastguard Worker                                  << ".xy);\n"
1757*35238bceSAndroid Build Coastguard Worker                                     "\tcoord += vec2(a_"
1758*35238bceSAndroid Build Coastguard Worker                                  << arrayNdx << ".zw);\n";
1759*35238bceSAndroid Build Coastguard Worker                 break;
1760*35238bceSAndroid Build Coastguard Worker 
1761*35238bceSAndroid Build Coastguard Worker             default:
1762*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(false);
1763*35238bceSAndroid Build Coastguard Worker                 break;
1764*35238bceSAndroid Build Coastguard Worker             }
1765*35238bceSAndroid Build Coastguard Worker         }
1766*35238bceSAndroid Build Coastguard Worker         else
1767*35238bceSAndroid Build Coastguard Worker         {
1768*35238bceSAndroid Build Coastguard Worker             switch (arrays[arrayNdx]->getOutputType())
1769*35238bceSAndroid Build Coastguard Worker             {
1770*35238bceSAndroid Build Coastguard Worker             case (DrawTestSpec::OUTPUTTYPE_FLOAT):
1771*35238bceSAndroid Build Coastguard Worker             case (DrawTestSpec::OUTPUTTYPE_INT):
1772*35238bceSAndroid Build Coastguard Worker             case (DrawTestSpec::OUTPUTTYPE_UINT):
1773*35238bceSAndroid Build Coastguard Worker                 vertexShaderTmpl << "\tcolor = color * float(a_" << arrayNdx << ");\n";
1774*35238bceSAndroid Build Coastguard Worker                 break;
1775*35238bceSAndroid Build Coastguard Worker 
1776*35238bceSAndroid Build Coastguard Worker             case (DrawTestSpec::OUTPUTTYPE_VEC2):
1777*35238bceSAndroid Build Coastguard Worker             case (DrawTestSpec::OUTPUTTYPE_IVEC2):
1778*35238bceSAndroid Build Coastguard Worker             case (DrawTestSpec::OUTPUTTYPE_UVEC2):
1779*35238bceSAndroid Build Coastguard Worker                 vertexShaderTmpl << "\tcolor.rg = color.rg * vec2(a_" << arrayNdx << ".xy);\n";
1780*35238bceSAndroid Build Coastguard Worker                 break;
1781*35238bceSAndroid Build Coastguard Worker 
1782*35238bceSAndroid Build Coastguard Worker             case (DrawTestSpec::OUTPUTTYPE_VEC3):
1783*35238bceSAndroid Build Coastguard Worker             case (DrawTestSpec::OUTPUTTYPE_IVEC3):
1784*35238bceSAndroid Build Coastguard Worker             case (DrawTestSpec::OUTPUTTYPE_UVEC3):
1785*35238bceSAndroid Build Coastguard Worker                 vertexShaderTmpl << "\tcolor = color.rgb * vec3(a_" << arrayNdx << ".xyz);\n";
1786*35238bceSAndroid Build Coastguard Worker                 break;
1787*35238bceSAndroid Build Coastguard Worker 
1788*35238bceSAndroid Build Coastguard Worker             case (DrawTestSpec::OUTPUTTYPE_VEC4):
1789*35238bceSAndroid Build Coastguard Worker             case (DrawTestSpec::OUTPUTTYPE_IVEC4):
1790*35238bceSAndroid Build Coastguard Worker             case (DrawTestSpec::OUTPUTTYPE_UVEC4):
1791*35238bceSAndroid Build Coastguard Worker                 vertexShaderTmpl << "\tcolor = color.rgb * vec3(a_" << arrayNdx << ".xyz) * float(a_" << arrayNdx
1792*35238bceSAndroid Build Coastguard Worker                                  << ".w);\n";
1793*35238bceSAndroid Build Coastguard Worker                 break;
1794*35238bceSAndroid Build Coastguard Worker 
1795*35238bceSAndroid Build Coastguard Worker             default:
1796*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(false);
1797*35238bceSAndroid Build Coastguard Worker                 break;
1798*35238bceSAndroid Build Coastguard Worker             }
1799*35238bceSAndroid Build Coastguard Worker         }
1800*35238bceSAndroid Build Coastguard Worker     }
1801*35238bceSAndroid Build Coastguard Worker 
1802*35238bceSAndroid Build Coastguard Worker     vertexShaderTmpl << "\tv_color = vec4(u_colorScale * color, 1.0) * 0.5 + vec4(0.5, 0.5, 0.5, 0.5);\n"
1803*35238bceSAndroid Build Coastguard Worker                         "\tgl_Position = vec4(u_coordScale * coord, 1.0, 1.0);\n"
1804*35238bceSAndroid Build Coastguard Worker                         "}\n";
1805*35238bceSAndroid Build Coastguard Worker 
1806*35238bceSAndroid Build Coastguard Worker     return tcu::StringTemplate(vertexShaderTmpl.str().c_str()).specialize(params);
1807*35238bceSAndroid Build Coastguard Worker }
1808*35238bceSAndroid Build Coastguard Worker 
genFragmentSource(const glu::RenderContext & ctx)1809*35238bceSAndroid Build Coastguard Worker std::string DrawTestShaderProgram::genFragmentSource(const glu::RenderContext &ctx)
1810*35238bceSAndroid Build Coastguard Worker {
1811*35238bceSAndroid Build Coastguard Worker     std::map<std::string, std::string> params;
1812*35238bceSAndroid Build Coastguard Worker 
1813*35238bceSAndroid Build Coastguard Worker     generateShaderParams(params, ctx.getType());
1814*35238bceSAndroid Build Coastguard Worker 
1815*35238bceSAndroid Build Coastguard Worker     static const char *fragmentShaderTmpl = "${FRAG_HDR}"
1816*35238bceSAndroid Build Coastguard Worker                                             "${FRAG_IN} ${COL_PRECISION} vec4 v_color;\n"
1817*35238bceSAndroid Build Coastguard Worker                                             "void main(void)\n"
1818*35238bceSAndroid Build Coastguard Worker                                             "{\n"
1819*35238bceSAndroid Build Coastguard Worker                                             "\t${FRAG_COLOR} = v_color;\n"
1820*35238bceSAndroid Build Coastguard Worker                                             "}\n";
1821*35238bceSAndroid Build Coastguard Worker 
1822*35238bceSAndroid Build Coastguard Worker     return tcu::StringTemplate(fragmentShaderTmpl).specialize(params);
1823*35238bceSAndroid Build Coastguard Worker }
1824*35238bceSAndroid Build Coastguard Worker 
generateShaderParams(std::map<std::string,std::string> & params,glu::ContextType type)1825*35238bceSAndroid Build Coastguard Worker void DrawTestShaderProgram::generateShaderParams(std::map<std::string, std::string> &params, glu::ContextType type)
1826*35238bceSAndroid Build Coastguard Worker {
1827*35238bceSAndroid Build Coastguard Worker     if (glu::isGLSLVersionSupported(type, glu::GLSL_VERSION_300_ES))
1828*35238bceSAndroid Build Coastguard Worker     {
1829*35238bceSAndroid Build Coastguard Worker         params["VTX_IN"]        = "in";
1830*35238bceSAndroid Build Coastguard Worker         params["VTX_OUT"]       = "out";
1831*35238bceSAndroid Build Coastguard Worker         params["FRAG_IN"]       = "in";
1832*35238bceSAndroid Build Coastguard Worker         params["FRAG_COLOR"]    = "dEQP_FragColor";
1833*35238bceSAndroid Build Coastguard Worker         params["VTX_HDR"]       = "#version 300 es\n";
1834*35238bceSAndroid Build Coastguard Worker         params["FRAG_HDR"]      = "#version 300 es\nlayout(location = 0) out mediump vec4 dEQP_FragColor;\n";
1835*35238bceSAndroid Build Coastguard Worker         params["COL_PRECISION"] = "mediump";
1836*35238bceSAndroid Build Coastguard Worker     }
1837*35238bceSAndroid Build Coastguard Worker     else if (glu::isGLSLVersionSupported(type, glu::GLSL_VERSION_100_ES))
1838*35238bceSAndroid Build Coastguard Worker     {
1839*35238bceSAndroid Build Coastguard Worker         params["VTX_IN"]        = "attribute";
1840*35238bceSAndroid Build Coastguard Worker         params["VTX_OUT"]       = "varying";
1841*35238bceSAndroid Build Coastguard Worker         params["FRAG_IN"]       = "varying";
1842*35238bceSAndroid Build Coastguard Worker         params["FRAG_COLOR"]    = "gl_FragColor";
1843*35238bceSAndroid Build Coastguard Worker         params["VTX_HDR"]       = "";
1844*35238bceSAndroid Build Coastguard Worker         params["FRAG_HDR"]      = "";
1845*35238bceSAndroid Build Coastguard Worker         params["COL_PRECISION"] = "mediump";
1846*35238bceSAndroid Build Coastguard Worker     }
1847*35238bceSAndroid Build Coastguard Worker     else if (glu::isGLSLVersionSupported(type, glu::GLSL_VERSION_430))
1848*35238bceSAndroid Build Coastguard Worker     {
1849*35238bceSAndroid Build Coastguard Worker         params["VTX_IN"]        = "in";
1850*35238bceSAndroid Build Coastguard Worker         params["VTX_OUT"]       = "out";
1851*35238bceSAndroid Build Coastguard Worker         params["FRAG_IN"]       = "in";
1852*35238bceSAndroid Build Coastguard Worker         params["FRAG_COLOR"]    = "dEQP_FragColor";
1853*35238bceSAndroid Build Coastguard Worker         params["VTX_HDR"]       = "#version 430\n";
1854*35238bceSAndroid Build Coastguard Worker         params["FRAG_HDR"]      = "#version 430\nlayout(location = 0) out highp vec4 dEQP_FragColor;\n";
1855*35238bceSAndroid Build Coastguard Worker         params["COL_PRECISION"] = "highp";
1856*35238bceSAndroid Build Coastguard Worker     }
1857*35238bceSAndroid Build Coastguard Worker     else if (glu::isGLSLVersionSupported(type, glu::GLSL_VERSION_330))
1858*35238bceSAndroid Build Coastguard Worker     {
1859*35238bceSAndroid Build Coastguard Worker         params["VTX_IN"]        = "in";
1860*35238bceSAndroid Build Coastguard Worker         params["VTX_OUT"]       = "out";
1861*35238bceSAndroid Build Coastguard Worker         params["FRAG_IN"]       = "in";
1862*35238bceSAndroid Build Coastguard Worker         params["FRAG_COLOR"]    = "dEQP_FragColor";
1863*35238bceSAndroid Build Coastguard Worker         params["VTX_HDR"]       = "#version 330\n";
1864*35238bceSAndroid Build Coastguard Worker         params["FRAG_HDR"]      = "#version 330\nlayout(location = 0) out mediump vec4 dEQP_FragColor;\n";
1865*35238bceSAndroid Build Coastguard Worker         params["COL_PRECISION"] = "mediump";
1866*35238bceSAndroid Build Coastguard Worker     }
1867*35238bceSAndroid Build Coastguard Worker     else
1868*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1869*35238bceSAndroid Build Coastguard Worker }
1870*35238bceSAndroid Build Coastguard Worker 
mapOutputType(const DrawTestSpec::OutputType & type)1871*35238bceSAndroid Build Coastguard Worker rr::GenericVecType DrawTestShaderProgram::mapOutputType(const DrawTestSpec::OutputType &type)
1872*35238bceSAndroid Build Coastguard Worker {
1873*35238bceSAndroid Build Coastguard Worker     switch (type)
1874*35238bceSAndroid Build Coastguard Worker     {
1875*35238bceSAndroid Build Coastguard Worker     case (DrawTestSpec::OUTPUTTYPE_FLOAT):
1876*35238bceSAndroid Build Coastguard Worker     case (DrawTestSpec::OUTPUTTYPE_VEC2):
1877*35238bceSAndroid Build Coastguard Worker     case (DrawTestSpec::OUTPUTTYPE_VEC3):
1878*35238bceSAndroid Build Coastguard Worker     case (DrawTestSpec::OUTPUTTYPE_VEC4):
1879*35238bceSAndroid Build Coastguard Worker         return rr::GENERICVECTYPE_FLOAT;
1880*35238bceSAndroid Build Coastguard Worker 
1881*35238bceSAndroid Build Coastguard Worker     case (DrawTestSpec::OUTPUTTYPE_INT):
1882*35238bceSAndroid Build Coastguard Worker     case (DrawTestSpec::OUTPUTTYPE_IVEC2):
1883*35238bceSAndroid Build Coastguard Worker     case (DrawTestSpec::OUTPUTTYPE_IVEC3):
1884*35238bceSAndroid Build Coastguard Worker     case (DrawTestSpec::OUTPUTTYPE_IVEC4):
1885*35238bceSAndroid Build Coastguard Worker         return rr::GENERICVECTYPE_INT32;
1886*35238bceSAndroid Build Coastguard Worker 
1887*35238bceSAndroid Build Coastguard Worker     case (DrawTestSpec::OUTPUTTYPE_UINT):
1888*35238bceSAndroid Build Coastguard Worker     case (DrawTestSpec::OUTPUTTYPE_UVEC2):
1889*35238bceSAndroid Build Coastguard Worker     case (DrawTestSpec::OUTPUTTYPE_UVEC3):
1890*35238bceSAndroid Build Coastguard Worker     case (DrawTestSpec::OUTPUTTYPE_UVEC4):
1891*35238bceSAndroid Build Coastguard Worker         return rr::GENERICVECTYPE_UINT32;
1892*35238bceSAndroid Build Coastguard Worker 
1893*35238bceSAndroid Build Coastguard Worker     default:
1894*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1895*35238bceSAndroid Build Coastguard Worker         return rr::GENERICVECTYPE_LAST;
1896*35238bceSAndroid Build Coastguard Worker     }
1897*35238bceSAndroid Build Coastguard Worker }
1898*35238bceSAndroid Build Coastguard Worker 
getComponentCount(const DrawTestSpec::OutputType & type)1899*35238bceSAndroid Build Coastguard Worker int DrawTestShaderProgram::getComponentCount(const DrawTestSpec::OutputType &type)
1900*35238bceSAndroid Build Coastguard Worker {
1901*35238bceSAndroid Build Coastguard Worker     switch (type)
1902*35238bceSAndroid Build Coastguard Worker     {
1903*35238bceSAndroid Build Coastguard Worker     case (DrawTestSpec::OUTPUTTYPE_FLOAT):
1904*35238bceSAndroid Build Coastguard Worker     case (DrawTestSpec::OUTPUTTYPE_INT):
1905*35238bceSAndroid Build Coastguard Worker     case (DrawTestSpec::OUTPUTTYPE_UINT):
1906*35238bceSAndroid Build Coastguard Worker         return 1;
1907*35238bceSAndroid Build Coastguard Worker 
1908*35238bceSAndroid Build Coastguard Worker     case (DrawTestSpec::OUTPUTTYPE_VEC2):
1909*35238bceSAndroid Build Coastguard Worker     case (DrawTestSpec::OUTPUTTYPE_IVEC2):
1910*35238bceSAndroid Build Coastguard Worker     case (DrawTestSpec::OUTPUTTYPE_UVEC2):
1911*35238bceSAndroid Build Coastguard Worker         return 2;
1912*35238bceSAndroid Build Coastguard Worker 
1913*35238bceSAndroid Build Coastguard Worker     case (DrawTestSpec::OUTPUTTYPE_VEC3):
1914*35238bceSAndroid Build Coastguard Worker     case (DrawTestSpec::OUTPUTTYPE_IVEC3):
1915*35238bceSAndroid Build Coastguard Worker     case (DrawTestSpec::OUTPUTTYPE_UVEC3):
1916*35238bceSAndroid Build Coastguard Worker         return 3;
1917*35238bceSAndroid Build Coastguard Worker 
1918*35238bceSAndroid Build Coastguard Worker     case (DrawTestSpec::OUTPUTTYPE_VEC4):
1919*35238bceSAndroid Build Coastguard Worker     case (DrawTestSpec::OUTPUTTYPE_IVEC4):
1920*35238bceSAndroid Build Coastguard Worker     case (DrawTestSpec::OUTPUTTYPE_UVEC4):
1921*35238bceSAndroid Build Coastguard Worker         return 4;
1922*35238bceSAndroid Build Coastguard Worker 
1923*35238bceSAndroid Build Coastguard Worker     default:
1924*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1925*35238bceSAndroid Build Coastguard Worker         return 0;
1926*35238bceSAndroid Build Coastguard Worker     }
1927*35238bceSAndroid Build Coastguard Worker }
1928*35238bceSAndroid Build Coastguard Worker 
createProgramDeclaration(const glu::RenderContext & ctx,const std::vector<AttributeArray * > & arrays)1929*35238bceSAndroid Build Coastguard Worker sglr::pdec::ShaderProgramDeclaration DrawTestShaderProgram::createProgramDeclaration(
1930*35238bceSAndroid Build Coastguard Worker     const glu::RenderContext &ctx, const std::vector<AttributeArray *> &arrays)
1931*35238bceSAndroid Build Coastguard Worker {
1932*35238bceSAndroid Build Coastguard Worker     sglr::pdec::ShaderProgramDeclaration decl;
1933*35238bceSAndroid Build Coastguard Worker 
1934*35238bceSAndroid Build Coastguard Worker     for (int arrayNdx = 0; arrayNdx < (int)arrays.size(); arrayNdx++)
1935*35238bceSAndroid Build Coastguard Worker         decl << sglr::pdec::VertexAttribute(std::string("a_") + de::toString(arrayNdx),
1936*35238bceSAndroid Build Coastguard Worker                                             mapOutputType(arrays[arrayNdx]->getOutputType()));
1937*35238bceSAndroid Build Coastguard Worker 
1938*35238bceSAndroid Build Coastguard Worker     decl << sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT);
1939*35238bceSAndroid Build Coastguard Worker     decl << sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT);
1940*35238bceSAndroid Build Coastguard Worker 
1941*35238bceSAndroid Build Coastguard Worker     decl << sglr::pdec::VertexSource(genVertexSource(ctx, arrays));
1942*35238bceSAndroid Build Coastguard Worker     decl << sglr::pdec::FragmentSource(genFragmentSource(ctx));
1943*35238bceSAndroid Build Coastguard Worker 
1944*35238bceSAndroid Build Coastguard Worker     decl << sglr::pdec::Uniform("u_coordScale", glu::TYPE_FLOAT);
1945*35238bceSAndroid Build Coastguard Worker     decl << sglr::pdec::Uniform("u_colorScale", glu::TYPE_FLOAT);
1946*35238bceSAndroid Build Coastguard Worker 
1947*35238bceSAndroid Build Coastguard Worker     return decl;
1948*35238bceSAndroid Build Coastguard Worker }
1949*35238bceSAndroid Build Coastguard Worker 
1950*35238bceSAndroid Build Coastguard Worker class RandomArrayGenerator
1951*35238bceSAndroid Build Coastguard Worker {
1952*35238bceSAndroid Build Coastguard Worker public:
1953*35238bceSAndroid Build Coastguard Worker     static char *generateArray(int seed, int elementCount, int componentCount, int offset, int stride,
1954*35238bceSAndroid Build Coastguard Worker                                DrawTestSpec::InputType type);
1955*35238bceSAndroid Build Coastguard Worker     static char *generateIndices(int seed, int elementCount, DrawTestSpec::IndexType type, int offset, int min, int max,
1956*35238bceSAndroid Build Coastguard Worker                                  int indexBase);
1957*35238bceSAndroid Build Coastguard Worker     static rr::GenericVec4 generateAttributeValue(int seed, DrawTestSpec::InputType type);
1958*35238bceSAndroid Build Coastguard Worker 
1959*35238bceSAndroid Build Coastguard Worker private:
1960*35238bceSAndroid Build Coastguard Worker     template <typename T>
1961*35238bceSAndroid Build Coastguard Worker     static char *createIndices(int seed, int elementCount, int offset, int min, int max, int indexBase);
1962*35238bceSAndroid Build Coastguard Worker 
1963*35238bceSAndroid Build Coastguard Worker     static char *generateBasicArray(int seed, int elementCount, int componentCount, int offset, int stride,
1964*35238bceSAndroid Build Coastguard Worker                                     DrawTestSpec::InputType type);
1965*35238bceSAndroid Build Coastguard Worker     template <typename T, typename GLType>
1966*35238bceSAndroid Build Coastguard Worker     static char *createBasicArray(int seed, int elementCount, int componentCount, int offset, int stride);
1967*35238bceSAndroid Build Coastguard Worker     static char *generatePackedArray(int seed, int elementCount, int componentCount, int offset, int stride);
1968*35238bceSAndroid Build Coastguard Worker };
1969*35238bceSAndroid Build Coastguard Worker 
generateArray(int seed,int elementCount,int componentCount,int offset,int stride,DrawTestSpec::InputType type)1970*35238bceSAndroid Build Coastguard Worker char *RandomArrayGenerator::generateArray(int seed, int elementCount, int componentCount, int offset, int stride,
1971*35238bceSAndroid Build Coastguard Worker                                           DrawTestSpec::InputType type)
1972*35238bceSAndroid Build Coastguard Worker {
1973*35238bceSAndroid Build Coastguard Worker     if (type == DrawTestSpec::INPUTTYPE_INT_2_10_10_10 || type == DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10)
1974*35238bceSAndroid Build Coastguard Worker         return generatePackedArray(seed, elementCount, componentCount, offset, stride);
1975*35238bceSAndroid Build Coastguard Worker     else
1976*35238bceSAndroid Build Coastguard Worker         return generateBasicArray(seed, elementCount, componentCount, offset, stride, type);
1977*35238bceSAndroid Build Coastguard Worker }
1978*35238bceSAndroid Build Coastguard Worker 
generateBasicArray(int seed,int elementCount,int componentCount,int offset,int stride,DrawTestSpec::InputType type)1979*35238bceSAndroid Build Coastguard Worker char *RandomArrayGenerator::generateBasicArray(int seed, int elementCount, int componentCount, int offset, int stride,
1980*35238bceSAndroid Build Coastguard Worker                                                DrawTestSpec::InputType type)
1981*35238bceSAndroid Build Coastguard Worker {
1982*35238bceSAndroid Build Coastguard Worker     switch (type)
1983*35238bceSAndroid Build Coastguard Worker     {
1984*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::INPUTTYPE_FLOAT:
1985*35238bceSAndroid Build Coastguard Worker         return createBasicArray<float, GLValue::Float>(seed, elementCount, componentCount, offset, stride);
1986*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::INPUTTYPE_DOUBLE:
1987*35238bceSAndroid Build Coastguard Worker         return createBasicArray<double, GLValue::Double>(seed, elementCount, componentCount, offset, stride);
1988*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::INPUTTYPE_SHORT:
1989*35238bceSAndroid Build Coastguard Worker         return createBasicArray<int16_t, GLValue::Short>(seed, elementCount, componentCount, offset, stride);
1990*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT:
1991*35238bceSAndroid Build Coastguard Worker         return createBasicArray<uint16_t, GLValue::Ushort>(seed, elementCount, componentCount, offset, stride);
1992*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::INPUTTYPE_BYTE:
1993*35238bceSAndroid Build Coastguard Worker         return createBasicArray<int8_t, GLValue::Byte>(seed, elementCount, componentCount, offset, stride);
1994*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE:
1995*35238bceSAndroid Build Coastguard Worker         return createBasicArray<uint8_t, GLValue::Ubyte>(seed, elementCount, componentCount, offset, stride);
1996*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::INPUTTYPE_FIXED:
1997*35238bceSAndroid Build Coastguard Worker         return createBasicArray<int32_t, GLValue::Fixed>(seed, elementCount, componentCount, offset, stride);
1998*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::INPUTTYPE_INT:
1999*35238bceSAndroid Build Coastguard Worker         return createBasicArray<int32_t, GLValue::Int>(seed, elementCount, componentCount, offset, stride);
2000*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::INPUTTYPE_UNSIGNED_INT:
2001*35238bceSAndroid Build Coastguard Worker         return createBasicArray<uint32_t, GLValue::Uint>(seed, elementCount, componentCount, offset, stride);
2002*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::INPUTTYPE_HALF:
2003*35238bceSAndroid Build Coastguard Worker         return createBasicArray<deFloat16, GLValue::Half>(seed, elementCount, componentCount, offset, stride);
2004*35238bceSAndroid Build Coastguard Worker     default:
2005*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
2006*35238bceSAndroid Build Coastguard Worker         break;
2007*35238bceSAndroid Build Coastguard Worker     }
2008*35238bceSAndroid Build Coastguard Worker     return DE_NULL;
2009*35238bceSAndroid Build Coastguard Worker }
2010*35238bceSAndroid Build Coastguard Worker 
2011*35238bceSAndroid Build Coastguard Worker #if (DE_COMPILER == DE_COMPILER_GCC) && (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)
2012*35238bceSAndroid Build Coastguard Worker // GCC 4.8/4.9 incorrectly emits array-bounds warning from createBasicArray()
2013*35238bceSAndroid Build Coastguard Worker #define GCC_ARRAY_BOUNDS_FALSE_NEGATIVE 1
2014*35238bceSAndroid Build Coastguard Worker #endif
2015*35238bceSAndroid Build Coastguard Worker 
2016*35238bceSAndroid Build Coastguard Worker #if defined(GCC_ARRAY_BOUNDS_FALSE_NEGATIVE)
2017*35238bceSAndroid Build Coastguard Worker #pragma GCC diagnostic push
2018*35238bceSAndroid Build Coastguard Worker #pragma GCC diagnostic ignored "-Warray-bounds"
2019*35238bceSAndroid Build Coastguard Worker #endif
2020*35238bceSAndroid Build Coastguard Worker 
2021*35238bceSAndroid Build Coastguard Worker template <typename T, typename GLType>
createBasicArray(int seed,int elementCount,int componentCount,int offset,int stride)2022*35238bceSAndroid Build Coastguard Worker char *RandomArrayGenerator::createBasicArray(int seed, int elementCount, int componentCount, int offset, int stride)
2023*35238bceSAndroid Build Coastguard Worker {
2024*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(componentCount >= 1 && componentCount <= 4);
2025*35238bceSAndroid Build Coastguard Worker 
2026*35238bceSAndroid Build Coastguard Worker     const GLType min = extractGLValue<GLType>(GLValue::getMinValue(GLValueTypeTraits<GLType>::Type));
2027*35238bceSAndroid Build Coastguard Worker     const GLType max = extractGLValue<GLType>(GLValue::getMaxValue(GLValueTypeTraits<GLType>::Type));
2028*35238bceSAndroid Build Coastguard Worker 
2029*35238bceSAndroid Build Coastguard Worker     const size_t componentSize = sizeof(T);
2030*35238bceSAndroid Build Coastguard Worker     const size_t elementSize   = componentSize * componentCount;
2031*35238bceSAndroid Build Coastguard Worker     const size_t bufferSize    = offset + (elementCount - 1) * stride + elementSize;
2032*35238bceSAndroid Build Coastguard Worker 
2033*35238bceSAndroid Build Coastguard Worker     char *data     = new char[bufferSize];
2034*35238bceSAndroid Build Coastguard Worker     char *writePtr = data + offset;
2035*35238bceSAndroid Build Coastguard Worker 
2036*35238bceSAndroid Build Coastguard Worker     GLType previousComponents[4];
2037*35238bceSAndroid Build Coastguard Worker 
2038*35238bceSAndroid Build Coastguard Worker     deRandom rnd;
2039*35238bceSAndroid Build Coastguard Worker     deRandom_init(&rnd, seed);
2040*35238bceSAndroid Build Coastguard Worker 
2041*35238bceSAndroid Build Coastguard Worker     for (int vertexNdx = 0; vertexNdx < elementCount; vertexNdx++)
2042*35238bceSAndroid Build Coastguard Worker     {
2043*35238bceSAndroid Build Coastguard Worker         GLType components[4];
2044*35238bceSAndroid Build Coastguard Worker 
2045*35238bceSAndroid Build Coastguard Worker         for (int componentNdx = 0; componentNdx < componentCount; componentNdx++)
2046*35238bceSAndroid Build Coastguard Worker         {
2047*35238bceSAndroid Build Coastguard Worker             components[componentNdx] = getRandom<GLType>(rnd, min, max);
2048*35238bceSAndroid Build Coastguard Worker 
2049*35238bceSAndroid Build Coastguard Worker             // Try to not create vertex near previous
2050*35238bceSAndroid Build Coastguard Worker             if (vertexNdx != 0 && abs(components[componentNdx] - previousComponents[componentNdx]) < minValue<GLType>())
2051*35238bceSAndroid Build Coastguard Worker             {
2052*35238bceSAndroid Build Coastguard Worker                 // Too close, try again (but only once)
2053*35238bceSAndroid Build Coastguard Worker                 components[componentNdx] = getRandom<GLType>(rnd, min, max);
2054*35238bceSAndroid Build Coastguard Worker             }
2055*35238bceSAndroid Build Coastguard Worker         }
2056*35238bceSAndroid Build Coastguard Worker 
2057*35238bceSAndroid Build Coastguard Worker         for (int componentNdx = 0; componentNdx < componentCount; componentNdx++)
2058*35238bceSAndroid Build Coastguard Worker             previousComponents[componentNdx] = components[componentNdx];
2059*35238bceSAndroid Build Coastguard Worker 
2060*35238bceSAndroid Build Coastguard Worker         for (int componentNdx = 0; componentNdx < componentCount; componentNdx++)
2061*35238bceSAndroid Build Coastguard Worker             alignmentSafeAssignment(writePtr + componentNdx * componentSize, components[componentNdx].getValue());
2062*35238bceSAndroid Build Coastguard Worker 
2063*35238bceSAndroid Build Coastguard Worker         writePtr += stride;
2064*35238bceSAndroid Build Coastguard Worker     }
2065*35238bceSAndroid Build Coastguard Worker 
2066*35238bceSAndroid Build Coastguard Worker     return data;
2067*35238bceSAndroid Build Coastguard Worker }
2068*35238bceSAndroid Build Coastguard Worker 
2069*35238bceSAndroid Build Coastguard Worker #if defined(GCC_ARRAY_BOUNDS_FALSE_NEGATIVE)
2070*35238bceSAndroid Build Coastguard Worker #pragma GCC diagnostic pop
2071*35238bceSAndroid Build Coastguard Worker #endif
2072*35238bceSAndroid Build Coastguard Worker 
generatePackedArray(int seed,int elementCount,int componentCount,int offset,int stride)2073*35238bceSAndroid Build Coastguard Worker char *RandomArrayGenerator::generatePackedArray(int seed, int elementCount, int componentCount, int offset, int stride)
2074*35238bceSAndroid Build Coastguard Worker {
2075*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(componentCount == 4);
2076*35238bceSAndroid Build Coastguard Worker     DE_UNREF(componentCount);
2077*35238bceSAndroid Build Coastguard Worker 
2078*35238bceSAndroid Build Coastguard Worker     const uint32_t limit10   = (1 << 10);
2079*35238bceSAndroid Build Coastguard Worker     const uint32_t limit2    = (1 << 2);
2080*35238bceSAndroid Build Coastguard Worker     const size_t elementSize = 4;
2081*35238bceSAndroid Build Coastguard Worker     const size_t bufferSize  = offset + (elementCount - 1) * stride + elementSize;
2082*35238bceSAndroid Build Coastguard Worker 
2083*35238bceSAndroid Build Coastguard Worker     char *data     = new char[bufferSize];
2084*35238bceSAndroid Build Coastguard Worker     char *writePtr = data + offset;
2085*35238bceSAndroid Build Coastguard Worker 
2086*35238bceSAndroid Build Coastguard Worker     deRandom rnd;
2087*35238bceSAndroid Build Coastguard Worker     deRandom_init(&rnd, seed);
2088*35238bceSAndroid Build Coastguard Worker 
2089*35238bceSAndroid Build Coastguard Worker     for (int vertexNdx = 0; vertexNdx < elementCount; vertexNdx++)
2090*35238bceSAndroid Build Coastguard Worker     {
2091*35238bceSAndroid Build Coastguard Worker         const uint32_t x           = deRandom_getUint32(&rnd) % limit10;
2092*35238bceSAndroid Build Coastguard Worker         const uint32_t y           = deRandom_getUint32(&rnd) % limit10;
2093*35238bceSAndroid Build Coastguard Worker         const uint32_t z           = deRandom_getUint32(&rnd) % limit10;
2094*35238bceSAndroid Build Coastguard Worker         const uint32_t w           = deRandom_getUint32(&rnd) % limit2;
2095*35238bceSAndroid Build Coastguard Worker         const uint32_t packedValue = (w << 30) | (z << 20) | (y << 10) | (x);
2096*35238bceSAndroid Build Coastguard Worker 
2097*35238bceSAndroid Build Coastguard Worker         alignmentSafeAssignment(writePtr, packedValue);
2098*35238bceSAndroid Build Coastguard Worker         writePtr += stride;
2099*35238bceSAndroid Build Coastguard Worker     }
2100*35238bceSAndroid Build Coastguard Worker 
2101*35238bceSAndroid Build Coastguard Worker     return data;
2102*35238bceSAndroid Build Coastguard Worker }
2103*35238bceSAndroid Build Coastguard Worker 
generateIndices(int seed,int elementCount,DrawTestSpec::IndexType type,int offset,int min,int max,int indexBase)2104*35238bceSAndroid Build Coastguard Worker char *RandomArrayGenerator::generateIndices(int seed, int elementCount, DrawTestSpec::IndexType type, int offset,
2105*35238bceSAndroid Build Coastguard Worker                                             int min, int max, int indexBase)
2106*35238bceSAndroid Build Coastguard Worker {
2107*35238bceSAndroid Build Coastguard Worker     char *data = DE_NULL;
2108*35238bceSAndroid Build Coastguard Worker 
2109*35238bceSAndroid Build Coastguard Worker     switch (type)
2110*35238bceSAndroid Build Coastguard Worker     {
2111*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::INDEXTYPE_BYTE:
2112*35238bceSAndroid Build Coastguard Worker         data = createIndices<uint8_t>(seed, elementCount, offset, min, max, indexBase);
2113*35238bceSAndroid Build Coastguard Worker         break;
2114*35238bceSAndroid Build Coastguard Worker 
2115*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::INDEXTYPE_SHORT:
2116*35238bceSAndroid Build Coastguard Worker         data = createIndices<uint16_t>(seed, elementCount, offset, min, max, indexBase);
2117*35238bceSAndroid Build Coastguard Worker         break;
2118*35238bceSAndroid Build Coastguard Worker 
2119*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::INDEXTYPE_INT:
2120*35238bceSAndroid Build Coastguard Worker         data = createIndices<uint32_t>(seed, elementCount, offset, min, max, indexBase);
2121*35238bceSAndroid Build Coastguard Worker         break;
2122*35238bceSAndroid Build Coastguard Worker 
2123*35238bceSAndroid Build Coastguard Worker     default:
2124*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
2125*35238bceSAndroid Build Coastguard Worker         break;
2126*35238bceSAndroid Build Coastguard Worker     }
2127*35238bceSAndroid Build Coastguard Worker 
2128*35238bceSAndroid Build Coastguard Worker     return data;
2129*35238bceSAndroid Build Coastguard Worker }
2130*35238bceSAndroid Build Coastguard Worker 
2131*35238bceSAndroid Build Coastguard Worker template <typename T>
createIndices(int seed,int elementCount,int offset,int min,int max,int indexBase)2132*35238bceSAndroid Build Coastguard Worker char *RandomArrayGenerator::createIndices(int seed, int elementCount, int offset, int min, int max, int indexBase)
2133*35238bceSAndroid Build Coastguard Worker {
2134*35238bceSAndroid Build Coastguard Worker     const size_t elementSize = sizeof(T);
2135*35238bceSAndroid Build Coastguard Worker     const size_t bufferSize  = offset + elementCount * elementSize;
2136*35238bceSAndroid Build Coastguard Worker 
2137*35238bceSAndroid Build Coastguard Worker     char *data     = new char[bufferSize];
2138*35238bceSAndroid Build Coastguard Worker     char *writePtr = data + offset;
2139*35238bceSAndroid Build Coastguard Worker 
2140*35238bceSAndroid Build Coastguard Worker     uint32_t oldNdx1 = uint32_t(-1);
2141*35238bceSAndroid Build Coastguard Worker     uint32_t oldNdx2 = uint32_t(-1);
2142*35238bceSAndroid Build Coastguard Worker 
2143*35238bceSAndroid Build Coastguard Worker     deRandom rnd;
2144*35238bceSAndroid Build Coastguard Worker     deRandom_init(&rnd, seed);
2145*35238bceSAndroid Build Coastguard Worker 
2146*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(indexBase >= 0); // watch for underflows
2147*35238bceSAndroid Build Coastguard Worker 
2148*35238bceSAndroid Build Coastguard Worker     if (min < 0 || (size_t)min > std::numeric_limits<T>::max() || max < 0 ||
2149*35238bceSAndroid Build Coastguard Worker         (size_t)max > std::numeric_limits<T>::max() || min > max)
2150*35238bceSAndroid Build Coastguard Worker         DE_FATAL("Invalid range");
2151*35238bceSAndroid Build Coastguard Worker 
2152*35238bceSAndroid Build Coastguard Worker     for (int elementNdx = 0; elementNdx < elementCount; ++elementNdx)
2153*35238bceSAndroid Build Coastguard Worker     {
2154*35238bceSAndroid Build Coastguard Worker         uint32_t ndx = getRandom(rnd, GLValue::Uint::create(min), GLValue::Uint::create(max)).getValue();
2155*35238bceSAndroid Build Coastguard Worker 
2156*35238bceSAndroid Build Coastguard Worker         // Try not to generate same index as any of previous two. This prevents
2157*35238bceSAndroid Build Coastguard Worker         // generation of degenerate triangles and lines. If [min, max] is too
2158*35238bceSAndroid Build Coastguard Worker         // small this cannot be guaranteed.
2159*35238bceSAndroid Build Coastguard Worker 
2160*35238bceSAndroid Build Coastguard Worker         if (ndx == oldNdx1)
2161*35238bceSAndroid Build Coastguard Worker             ++ndx;
2162*35238bceSAndroid Build Coastguard Worker         if (ndx > (uint32_t)max)
2163*35238bceSAndroid Build Coastguard Worker             ndx = min;
2164*35238bceSAndroid Build Coastguard Worker         if (ndx == oldNdx2)
2165*35238bceSAndroid Build Coastguard Worker             ++ndx;
2166*35238bceSAndroid Build Coastguard Worker         if (ndx > (uint32_t)max)
2167*35238bceSAndroid Build Coastguard Worker             ndx = min;
2168*35238bceSAndroid Build Coastguard Worker         if (ndx == oldNdx1)
2169*35238bceSAndroid Build Coastguard Worker             ++ndx;
2170*35238bceSAndroid Build Coastguard Worker         if (ndx > (uint32_t)max)
2171*35238bceSAndroid Build Coastguard Worker             ndx = min;
2172*35238bceSAndroid Build Coastguard Worker 
2173*35238bceSAndroid Build Coastguard Worker         oldNdx2 = oldNdx1;
2174*35238bceSAndroid Build Coastguard Worker         oldNdx1 = ndx;
2175*35238bceSAndroid Build Coastguard Worker 
2176*35238bceSAndroid Build Coastguard Worker         ndx += indexBase;
2177*35238bceSAndroid Build Coastguard Worker 
2178*35238bceSAndroid Build Coastguard Worker         alignmentSafeAssignment<T>(writePtr + elementSize * elementNdx, T(ndx));
2179*35238bceSAndroid Build Coastguard Worker     }
2180*35238bceSAndroid Build Coastguard Worker 
2181*35238bceSAndroid Build Coastguard Worker     return data;
2182*35238bceSAndroid Build Coastguard Worker }
2183*35238bceSAndroid Build Coastguard Worker 
generateAttributeValue(int seed,DrawTestSpec::InputType type)2184*35238bceSAndroid Build Coastguard Worker rr::GenericVec4 RandomArrayGenerator::generateAttributeValue(int seed, DrawTestSpec::InputType type)
2185*35238bceSAndroid Build Coastguard Worker {
2186*35238bceSAndroid Build Coastguard Worker     de::Random random(seed);
2187*35238bceSAndroid Build Coastguard Worker 
2188*35238bceSAndroid Build Coastguard Worker     switch (type)
2189*35238bceSAndroid Build Coastguard Worker     {
2190*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::INPUTTYPE_FLOAT:
2191*35238bceSAndroid Build Coastguard Worker         return rr::GenericVec4(generateRandomVec4(random));
2192*35238bceSAndroid Build Coastguard Worker 
2193*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::INPUTTYPE_INT:
2194*35238bceSAndroid Build Coastguard Worker         return rr::GenericVec4(generateRandomIVec4(random));
2195*35238bceSAndroid Build Coastguard Worker 
2196*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::INPUTTYPE_UNSIGNED_INT:
2197*35238bceSAndroid Build Coastguard Worker         return rr::GenericVec4(generateRandomUVec4(random));
2198*35238bceSAndroid Build Coastguard Worker 
2199*35238bceSAndroid Build Coastguard Worker     default:
2200*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
2201*35238bceSAndroid Build Coastguard Worker         return rr::GenericVec4(tcu::Vec4(1, 1, 1, 1));
2202*35238bceSAndroid Build Coastguard Worker     }
2203*35238bceSAndroid Build Coastguard Worker }
2204*35238bceSAndroid Build Coastguard Worker 
2205*35238bceSAndroid Build Coastguard Worker } // namespace
2206*35238bceSAndroid Build Coastguard Worker 
2207*35238bceSAndroid Build Coastguard Worker // AttributePack
2208*35238bceSAndroid Build Coastguard Worker 
2209*35238bceSAndroid Build Coastguard Worker class AttributePack
2210*35238bceSAndroid Build Coastguard Worker {
2211*35238bceSAndroid Build Coastguard Worker public:
2212*35238bceSAndroid Build Coastguard Worker     AttributePack(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, sglr::Context &drawContext,
2213*35238bceSAndroid Build Coastguard Worker                   const tcu::UVec2 &screenSize, bool useVao, bool logEnabled);
2214*35238bceSAndroid Build Coastguard Worker     ~AttributePack(void);
2215*35238bceSAndroid Build Coastguard Worker 
2216*35238bceSAndroid Build Coastguard Worker     AttributeArray *getArray(int i);
2217*35238bceSAndroid Build Coastguard Worker     int getArrayCount(void);
2218*35238bceSAndroid Build Coastguard Worker 
2219*35238bceSAndroid Build Coastguard Worker     void newArray(DrawTestSpec::Storage storage);
2220*35238bceSAndroid Build Coastguard Worker     void clearArrays(void);
2221*35238bceSAndroid Build Coastguard Worker     void updateProgram(void);
2222*35238bceSAndroid Build Coastguard Worker 
2223*35238bceSAndroid Build Coastguard Worker     void render(DrawTestSpec::Primitive primitive, DrawTestSpec::DrawMethod drawMethod, int firstVertex,
2224*35238bceSAndroid Build Coastguard Worker                 int vertexCount, DrawTestSpec::IndexType indexType, const void *indexOffset, int rangeStart,
2225*35238bceSAndroid Build Coastguard Worker                 int rangeEnd, int instanceCount, int indirectOffset, int baseVertex, float coordScale, float colorScale,
2226*35238bceSAndroid Build Coastguard Worker                 AttributeArray *indexArray);
2227*35238bceSAndroid Build Coastguard Worker 
getSurface(void) const2228*35238bceSAndroid Build Coastguard Worker     const tcu::Surface &getSurface(void) const
2229*35238bceSAndroid Build Coastguard Worker     {
2230*35238bceSAndroid Build Coastguard Worker         return m_screen;
2231*35238bceSAndroid Build Coastguard Worker     }
2232*35238bceSAndroid Build Coastguard Worker 
2233*35238bceSAndroid Build Coastguard Worker private:
2234*35238bceSAndroid Build Coastguard Worker     tcu::TestContext &m_testCtx;
2235*35238bceSAndroid Build Coastguard Worker     glu::RenderContext &m_renderCtx;
2236*35238bceSAndroid Build Coastguard Worker     sglr::Context &m_ctx;
2237*35238bceSAndroid Build Coastguard Worker 
2238*35238bceSAndroid Build Coastguard Worker     std::vector<AttributeArray *> m_arrays;
2239*35238bceSAndroid Build Coastguard Worker     sglr::ShaderProgram *m_program;
2240*35238bceSAndroid Build Coastguard Worker     tcu::Surface m_screen;
2241*35238bceSAndroid Build Coastguard Worker     const bool m_useVao;
2242*35238bceSAndroid Build Coastguard Worker     const bool m_logEnabled;
2243*35238bceSAndroid Build Coastguard Worker     uint32_t m_programID;
2244*35238bceSAndroid Build Coastguard Worker     uint32_t m_vaoID;
2245*35238bceSAndroid Build Coastguard Worker };
2246*35238bceSAndroid Build Coastguard Worker 
AttributePack(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,sglr::Context & drawContext,const tcu::UVec2 & screenSize,bool useVao,bool logEnabled)2247*35238bceSAndroid Build Coastguard Worker AttributePack::AttributePack(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, sglr::Context &drawContext,
2248*35238bceSAndroid Build Coastguard Worker                              const tcu::UVec2 &screenSize, bool useVao, bool logEnabled)
2249*35238bceSAndroid Build Coastguard Worker     : m_testCtx(testCtx)
2250*35238bceSAndroid Build Coastguard Worker     , m_renderCtx(renderCtx)
2251*35238bceSAndroid Build Coastguard Worker     , m_ctx(drawContext)
2252*35238bceSAndroid Build Coastguard Worker     , m_program(DE_NULL)
2253*35238bceSAndroid Build Coastguard Worker     , m_screen(screenSize.x(), screenSize.y())
2254*35238bceSAndroid Build Coastguard Worker     , m_useVao(useVao)
2255*35238bceSAndroid Build Coastguard Worker     , m_logEnabled(logEnabled)
2256*35238bceSAndroid Build Coastguard Worker     , m_programID(0)
2257*35238bceSAndroid Build Coastguard Worker     , m_vaoID(0)
2258*35238bceSAndroid Build Coastguard Worker {
2259*35238bceSAndroid Build Coastguard Worker     if (m_useVao)
2260*35238bceSAndroid Build Coastguard Worker         m_ctx.genVertexArrays(1, &m_vaoID);
2261*35238bceSAndroid Build Coastguard Worker }
2262*35238bceSAndroid Build Coastguard Worker 
~AttributePack(void)2263*35238bceSAndroid Build Coastguard Worker AttributePack::~AttributePack(void)
2264*35238bceSAndroid Build Coastguard Worker {
2265*35238bceSAndroid Build Coastguard Worker     clearArrays();
2266*35238bceSAndroid Build Coastguard Worker 
2267*35238bceSAndroid Build Coastguard Worker     if (m_programID)
2268*35238bceSAndroid Build Coastguard Worker         m_ctx.deleteProgram(m_programID);
2269*35238bceSAndroid Build Coastguard Worker 
2270*35238bceSAndroid Build Coastguard Worker     if (m_program)
2271*35238bceSAndroid Build Coastguard Worker         delete m_program;
2272*35238bceSAndroid Build Coastguard Worker 
2273*35238bceSAndroid Build Coastguard Worker     if (m_useVao)
2274*35238bceSAndroid Build Coastguard Worker         m_ctx.deleteVertexArrays(1, &m_vaoID);
2275*35238bceSAndroid Build Coastguard Worker }
2276*35238bceSAndroid Build Coastguard Worker 
getArray(int i)2277*35238bceSAndroid Build Coastguard Worker AttributeArray *AttributePack::getArray(int i)
2278*35238bceSAndroid Build Coastguard Worker {
2279*35238bceSAndroid Build Coastguard Worker     return m_arrays.at(i);
2280*35238bceSAndroid Build Coastguard Worker }
2281*35238bceSAndroid Build Coastguard Worker 
getArrayCount(void)2282*35238bceSAndroid Build Coastguard Worker int AttributePack::getArrayCount(void)
2283*35238bceSAndroid Build Coastguard Worker {
2284*35238bceSAndroid Build Coastguard Worker     return (int)m_arrays.size();
2285*35238bceSAndroid Build Coastguard Worker }
2286*35238bceSAndroid Build Coastguard Worker 
newArray(DrawTestSpec::Storage storage)2287*35238bceSAndroid Build Coastguard Worker void AttributePack::newArray(DrawTestSpec::Storage storage)
2288*35238bceSAndroid Build Coastguard Worker {
2289*35238bceSAndroid Build Coastguard Worker     m_arrays.push_back(new AttributeArray(storage, m_ctx));
2290*35238bceSAndroid Build Coastguard Worker }
2291*35238bceSAndroid Build Coastguard Worker 
clearArrays(void)2292*35238bceSAndroid Build Coastguard Worker void AttributePack::clearArrays(void)
2293*35238bceSAndroid Build Coastguard Worker {
2294*35238bceSAndroid Build Coastguard Worker     for (std::vector<AttributeArray *>::iterator itr = m_arrays.begin(); itr != m_arrays.end(); itr++)
2295*35238bceSAndroid Build Coastguard Worker         delete *itr;
2296*35238bceSAndroid Build Coastguard Worker     m_arrays.clear();
2297*35238bceSAndroid Build Coastguard Worker }
2298*35238bceSAndroid Build Coastguard Worker 
updateProgram(void)2299*35238bceSAndroid Build Coastguard Worker void AttributePack::updateProgram(void)
2300*35238bceSAndroid Build Coastguard Worker {
2301*35238bceSAndroid Build Coastguard Worker     if (m_programID)
2302*35238bceSAndroid Build Coastguard Worker         m_ctx.deleteProgram(m_programID);
2303*35238bceSAndroid Build Coastguard Worker     if (m_program)
2304*35238bceSAndroid Build Coastguard Worker         delete m_program;
2305*35238bceSAndroid Build Coastguard Worker 
2306*35238bceSAndroid Build Coastguard Worker     m_program   = new DrawTestShaderProgram(m_renderCtx, m_arrays);
2307*35238bceSAndroid Build Coastguard Worker     m_programID = m_ctx.createProgram(m_program);
2308*35238bceSAndroid Build Coastguard Worker }
2309*35238bceSAndroid Build Coastguard Worker 
render(DrawTestSpec::Primitive primitive,DrawTestSpec::DrawMethod drawMethod,int firstVertex,int vertexCount,DrawTestSpec::IndexType indexType,const void * indexOffset,int rangeStart,int rangeEnd,int instanceCount,int indirectOffset,int baseVertex,float coordScale,float colorScale,AttributeArray * indexArray)2310*35238bceSAndroid Build Coastguard Worker void AttributePack::render(DrawTestSpec::Primitive primitive, DrawTestSpec::DrawMethod drawMethod, int firstVertex,
2311*35238bceSAndroid Build Coastguard Worker                            int vertexCount, DrawTestSpec::IndexType indexType, const void *indexOffset, int rangeStart,
2312*35238bceSAndroid Build Coastguard Worker                            int rangeEnd, int instanceCount, int indirectOffset, int baseVertex, float coordScale,
2313*35238bceSAndroid Build Coastguard Worker                            float colorScale, AttributeArray *indexArray)
2314*35238bceSAndroid Build Coastguard Worker {
2315*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_program != DE_NULL);
2316*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_programID != 0);
2317*35238bceSAndroid Build Coastguard Worker 
2318*35238bceSAndroid Build Coastguard Worker     m_ctx.viewport(0, 0, m_screen.getWidth(), m_screen.getHeight());
2319*35238bceSAndroid Build Coastguard Worker     m_ctx.clearColor(0.0, 0.0, 0.0, 1.0);
2320*35238bceSAndroid Build Coastguard Worker     m_ctx.clear(GL_COLOR_BUFFER_BIT);
2321*35238bceSAndroid Build Coastguard Worker 
2322*35238bceSAndroid Build Coastguard Worker     m_ctx.useProgram(m_programID);
2323*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glUseProgram()");
2324*35238bceSAndroid Build Coastguard Worker 
2325*35238bceSAndroid Build Coastguard Worker     m_ctx.uniform1f(m_ctx.getUniformLocation(m_programID, "u_coordScale"), coordScale);
2326*35238bceSAndroid Build Coastguard Worker     m_ctx.uniform1f(m_ctx.getUniformLocation(m_programID, "u_colorScale"), colorScale);
2327*35238bceSAndroid Build Coastguard Worker 
2328*35238bceSAndroid Build Coastguard Worker     if (m_useVao)
2329*35238bceSAndroid Build Coastguard Worker         m_ctx.bindVertexArray(m_vaoID);
2330*35238bceSAndroid Build Coastguard Worker 
2331*35238bceSAndroid Build Coastguard Worker     if (indexArray)
2332*35238bceSAndroid Build Coastguard Worker         indexArray->bindIndexArray(DrawTestSpec::TARGET_ELEMENT_ARRAY);
2333*35238bceSAndroid Build Coastguard Worker 
2334*35238bceSAndroid Build Coastguard Worker     for (int arrayNdx = 0; arrayNdx < (int)m_arrays.size(); arrayNdx++)
2335*35238bceSAndroid Build Coastguard Worker     {
2336*35238bceSAndroid Build Coastguard Worker         std::stringstream attribName;
2337*35238bceSAndroid Build Coastguard Worker         attribName << "a_" << arrayNdx;
2338*35238bceSAndroid Build Coastguard Worker 
2339*35238bceSAndroid Build Coastguard Worker         uint32_t loc = m_ctx.getAttribLocation(m_programID, attribName.str().c_str());
2340*35238bceSAndroid Build Coastguard Worker 
2341*35238bceSAndroid Build Coastguard Worker         if (m_arrays[arrayNdx]->isBound())
2342*35238bceSAndroid Build Coastguard Worker         {
2343*35238bceSAndroid Build Coastguard Worker             m_ctx.enableVertexAttribArray(loc);
2344*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glEnableVertexAttribArray()");
2345*35238bceSAndroid Build Coastguard Worker         }
2346*35238bceSAndroid Build Coastguard Worker 
2347*35238bceSAndroid Build Coastguard Worker         m_arrays[arrayNdx]->bindAttribute(loc);
2348*35238bceSAndroid Build Coastguard Worker     }
2349*35238bceSAndroid Build Coastguard Worker 
2350*35238bceSAndroid Build Coastguard Worker     if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWARRAYS)
2351*35238bceSAndroid Build Coastguard Worker     {
2352*35238bceSAndroid Build Coastguard Worker         m_ctx.drawArrays(primitiveToGL(primitive), firstVertex, vertexCount);
2353*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawArrays()");
2354*35238bceSAndroid Build Coastguard Worker     }
2355*35238bceSAndroid Build Coastguard Worker     else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWARRAYS_INSTANCED)
2356*35238bceSAndroid Build Coastguard Worker     {
2357*35238bceSAndroid Build Coastguard Worker         m_ctx.drawArraysInstanced(primitiveToGL(primitive), firstVertex, vertexCount, instanceCount);
2358*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawArraysInstanced()");
2359*35238bceSAndroid Build Coastguard Worker     }
2360*35238bceSAndroid Build Coastguard Worker     else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS)
2361*35238bceSAndroid Build Coastguard Worker     {
2362*35238bceSAndroid Build Coastguard Worker         m_ctx.drawElements(primitiveToGL(primitive), vertexCount, indexTypeToGL(indexType), indexOffset);
2363*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawElements()");
2364*35238bceSAndroid Build Coastguard Worker     }
2365*35238bceSAndroid Build Coastguard Worker     else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED)
2366*35238bceSAndroid Build Coastguard Worker     {
2367*35238bceSAndroid Build Coastguard Worker         m_ctx.drawRangeElements(primitiveToGL(primitive), rangeStart, rangeEnd, vertexCount, indexTypeToGL(indexType),
2368*35238bceSAndroid Build Coastguard Worker                                 indexOffset);
2369*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawRangeElements()");
2370*35238bceSAndroid Build Coastguard Worker     }
2371*35238bceSAndroid Build Coastguard Worker     else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED)
2372*35238bceSAndroid Build Coastguard Worker     {
2373*35238bceSAndroid Build Coastguard Worker         m_ctx.drawElementsInstanced(primitiveToGL(primitive), vertexCount, indexTypeToGL(indexType), indexOffset,
2374*35238bceSAndroid Build Coastguard Worker                                     instanceCount);
2375*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawElementsInstanced()");
2376*35238bceSAndroid Build Coastguard Worker     }
2377*35238bceSAndroid Build Coastguard Worker     else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWARRAYS_INDIRECT)
2378*35238bceSAndroid Build Coastguard Worker     {
2379*35238bceSAndroid Build Coastguard Worker         struct DrawCommand
2380*35238bceSAndroid Build Coastguard Worker         {
2381*35238bceSAndroid Build Coastguard Worker             GLuint count;
2382*35238bceSAndroid Build Coastguard Worker             GLuint primCount;
2383*35238bceSAndroid Build Coastguard Worker             GLuint first;
2384*35238bceSAndroid Build Coastguard Worker             GLuint reservedMustBeZero;
2385*35238bceSAndroid Build Coastguard Worker         };
2386*35238bceSAndroid Build Coastguard Worker         uint8_t *buffer = new uint8_t[sizeof(DrawCommand) + indirectOffset];
2387*35238bceSAndroid Build Coastguard Worker 
2388*35238bceSAndroid Build Coastguard Worker         {
2389*35238bceSAndroid Build Coastguard Worker             DrawCommand command;
2390*35238bceSAndroid Build Coastguard Worker 
2391*35238bceSAndroid Build Coastguard Worker             command.count              = vertexCount;
2392*35238bceSAndroid Build Coastguard Worker             command.primCount          = instanceCount;
2393*35238bceSAndroid Build Coastguard Worker             command.first              = firstVertex;
2394*35238bceSAndroid Build Coastguard Worker             command.reservedMustBeZero = 0;
2395*35238bceSAndroid Build Coastguard Worker 
2396*35238bceSAndroid Build Coastguard Worker             memcpy(buffer + indirectOffset, &command, sizeof(command));
2397*35238bceSAndroid Build Coastguard Worker 
2398*35238bceSAndroid Build Coastguard Worker             if (m_logEnabled)
2399*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message << "DrawArraysIndirectCommand:\n"
2400*35238bceSAndroid Build Coastguard Worker                                    << "\tcount: " << command.count << "\n"
2401*35238bceSAndroid Build Coastguard Worker                                    << "\tprimCount: " << command.primCount << "\n"
2402*35238bceSAndroid Build Coastguard Worker                                    << "\tfirst: " << command.first << "\n"
2403*35238bceSAndroid Build Coastguard Worker                                    << "\treservedMustBeZero: " << command.reservedMustBeZero << "\n"
2404*35238bceSAndroid Build Coastguard Worker                                    << tcu::TestLog::EndMessage;
2405*35238bceSAndroid Build Coastguard Worker         }
2406*35238bceSAndroid Build Coastguard Worker 
2407*35238bceSAndroid Build Coastguard Worker         GLuint indirectBuf = 0;
2408*35238bceSAndroid Build Coastguard Worker         m_ctx.genBuffers(1, &indirectBuf);
2409*35238bceSAndroid Build Coastguard Worker         m_ctx.bindBuffer(GL_DRAW_INDIRECT_BUFFER, indirectBuf);
2410*35238bceSAndroid Build Coastguard Worker         m_ctx.bufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawCommand) + indirectOffset, buffer, GL_STATIC_DRAW);
2411*35238bceSAndroid Build Coastguard Worker         delete[] buffer;
2412*35238bceSAndroid Build Coastguard Worker 
2413*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(m_ctx.getError(), "Setup draw indirect buffer");
2414*35238bceSAndroid Build Coastguard Worker 
2415*35238bceSAndroid Build Coastguard Worker         m_ctx.drawArraysIndirect(primitiveToGL(primitive), glu::BufferOffsetAsPointer(indirectOffset));
2416*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawArraysIndirect()");
2417*35238bceSAndroid Build Coastguard Worker 
2418*35238bceSAndroid Build Coastguard Worker         m_ctx.deleteBuffers(1, &indirectBuf);
2419*35238bceSAndroid Build Coastguard Worker     }
2420*35238bceSAndroid Build Coastguard Worker     else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INDIRECT)
2421*35238bceSAndroid Build Coastguard Worker     {
2422*35238bceSAndroid Build Coastguard Worker         struct DrawCommand
2423*35238bceSAndroid Build Coastguard Worker         {
2424*35238bceSAndroid Build Coastguard Worker             GLuint count;
2425*35238bceSAndroid Build Coastguard Worker             GLuint primCount;
2426*35238bceSAndroid Build Coastguard Worker             GLuint firstIndex;
2427*35238bceSAndroid Build Coastguard Worker             GLint baseVertex;
2428*35238bceSAndroid Build Coastguard Worker             GLuint reservedMustBeZero;
2429*35238bceSAndroid Build Coastguard Worker         };
2430*35238bceSAndroid Build Coastguard Worker         uint8_t *buffer = new uint8_t[sizeof(DrawCommand) + indirectOffset];
2431*35238bceSAndroid Build Coastguard Worker 
2432*35238bceSAndroid Build Coastguard Worker         {
2433*35238bceSAndroid Build Coastguard Worker             DrawCommand command;
2434*35238bceSAndroid Build Coastguard Worker 
2435*35238bceSAndroid Build Coastguard Worker             // index offset must be converted to firstIndex by dividing with the index element size
2436*35238bceSAndroid Build Coastguard Worker             const auto offsetAsInteger = reinterpret_cast<uintptr_t>(indexOffset);
2437*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(offsetAsInteger % gls::DrawTestSpec::indexTypeSize(indexType) ==
2438*35238bceSAndroid Build Coastguard Worker                       0); // \note This is checked in spec validation
2439*35238bceSAndroid Build Coastguard Worker 
2440*35238bceSAndroid Build Coastguard Worker             command.count              = vertexCount;
2441*35238bceSAndroid Build Coastguard Worker             command.primCount          = instanceCount;
2442*35238bceSAndroid Build Coastguard Worker             command.firstIndex         = (glw::GLuint)(offsetAsInteger / gls::DrawTestSpec::indexTypeSize(indexType));
2443*35238bceSAndroid Build Coastguard Worker             command.baseVertex         = baseVertex;
2444*35238bceSAndroid Build Coastguard Worker             command.reservedMustBeZero = 0;
2445*35238bceSAndroid Build Coastguard Worker 
2446*35238bceSAndroid Build Coastguard Worker             memcpy(buffer + indirectOffset, &command, sizeof(command));
2447*35238bceSAndroid Build Coastguard Worker 
2448*35238bceSAndroid Build Coastguard Worker             if (m_logEnabled)
2449*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << tcu::TestLog::Message << "DrawElementsIndirectCommand:\n"
2450*35238bceSAndroid Build Coastguard Worker                                    << "\tcount: " << command.count << "\n"
2451*35238bceSAndroid Build Coastguard Worker                                    << "\tprimCount: " << command.primCount << "\n"
2452*35238bceSAndroid Build Coastguard Worker                                    << "\tfirstIndex: " << command.firstIndex << "\n"
2453*35238bceSAndroid Build Coastguard Worker                                    << "\tbaseVertex: " << command.baseVertex << "\n"
2454*35238bceSAndroid Build Coastguard Worker                                    << "\treservedMustBeZero: " << command.reservedMustBeZero << "\n"
2455*35238bceSAndroid Build Coastguard Worker                                    << tcu::TestLog::EndMessage;
2456*35238bceSAndroid Build Coastguard Worker         }
2457*35238bceSAndroid Build Coastguard Worker 
2458*35238bceSAndroid Build Coastguard Worker         GLuint indirectBuf = 0;
2459*35238bceSAndroid Build Coastguard Worker         m_ctx.genBuffers(1, &indirectBuf);
2460*35238bceSAndroid Build Coastguard Worker         m_ctx.bindBuffer(GL_DRAW_INDIRECT_BUFFER, indirectBuf);
2461*35238bceSAndroid Build Coastguard Worker         m_ctx.bufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawCommand) + indirectOffset, buffer, GL_STATIC_DRAW);
2462*35238bceSAndroid Build Coastguard Worker         delete[] buffer;
2463*35238bceSAndroid Build Coastguard Worker 
2464*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(m_ctx.getError(), "Setup draw indirect buffer");
2465*35238bceSAndroid Build Coastguard Worker 
2466*35238bceSAndroid Build Coastguard Worker         m_ctx.drawElementsIndirect(primitiveToGL(primitive), indexTypeToGL(indexType),
2467*35238bceSAndroid Build Coastguard Worker                                    glu::BufferOffsetAsPointer(indirectOffset));
2468*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawArraysIndirect()");
2469*35238bceSAndroid Build Coastguard Worker 
2470*35238bceSAndroid Build Coastguard Worker         m_ctx.deleteBuffers(1, &indirectBuf);
2471*35238bceSAndroid Build Coastguard Worker     }
2472*35238bceSAndroid Build Coastguard Worker     else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_BASEVERTEX)
2473*35238bceSAndroid Build Coastguard Worker     {
2474*35238bceSAndroid Build Coastguard Worker         m_ctx.drawElementsBaseVertex(primitiveToGL(primitive), vertexCount, indexTypeToGL(indexType), indexOffset,
2475*35238bceSAndroid Build Coastguard Worker                                      baseVertex);
2476*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawElementsBaseVertex()");
2477*35238bceSAndroid Build Coastguard Worker     }
2478*35238bceSAndroid Build Coastguard Worker     else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX)
2479*35238bceSAndroid Build Coastguard Worker     {
2480*35238bceSAndroid Build Coastguard Worker         m_ctx.drawElementsInstancedBaseVertex(primitiveToGL(primitive), vertexCount, indexTypeToGL(indexType),
2481*35238bceSAndroid Build Coastguard Worker                                               indexOffset, instanceCount, baseVertex);
2482*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawElementsInstancedBaseVertex()");
2483*35238bceSAndroid Build Coastguard Worker     }
2484*35238bceSAndroid Build Coastguard Worker     else if (drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX)
2485*35238bceSAndroid Build Coastguard Worker     {
2486*35238bceSAndroid Build Coastguard Worker         m_ctx.drawRangeElementsBaseVertex(primitiveToGL(primitive), rangeStart, rangeEnd, vertexCount,
2487*35238bceSAndroid Build Coastguard Worker                                           indexTypeToGL(indexType), indexOffset, baseVertex);
2488*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDrawRangeElementsBaseVertex()");
2489*35238bceSAndroid Build Coastguard Worker     }
2490*35238bceSAndroid Build Coastguard Worker     else
2491*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
2492*35238bceSAndroid Build Coastguard Worker 
2493*35238bceSAndroid Build Coastguard Worker     for (int arrayNdx = 0; arrayNdx < (int)m_arrays.size(); arrayNdx++)
2494*35238bceSAndroid Build Coastguard Worker     {
2495*35238bceSAndroid Build Coastguard Worker         if (m_arrays[arrayNdx]->isBound())
2496*35238bceSAndroid Build Coastguard Worker         {
2497*35238bceSAndroid Build Coastguard Worker             std::stringstream attribName;
2498*35238bceSAndroid Build Coastguard Worker             attribName << "a_" << arrayNdx;
2499*35238bceSAndroid Build Coastguard Worker 
2500*35238bceSAndroid Build Coastguard Worker             uint32_t loc = m_ctx.getAttribLocation(m_programID, attribName.str().c_str());
2501*35238bceSAndroid Build Coastguard Worker 
2502*35238bceSAndroid Build Coastguard Worker             m_ctx.disableVertexAttribArray(loc);
2503*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(m_ctx.getError(), "glDisableVertexAttribArray()");
2504*35238bceSAndroid Build Coastguard Worker         }
2505*35238bceSAndroid Build Coastguard Worker     }
2506*35238bceSAndroid Build Coastguard Worker 
2507*35238bceSAndroid Build Coastguard Worker     if (m_useVao)
2508*35238bceSAndroid Build Coastguard Worker         m_ctx.bindVertexArray(0);
2509*35238bceSAndroid Build Coastguard Worker 
2510*35238bceSAndroid Build Coastguard Worker     m_ctx.useProgram(0);
2511*35238bceSAndroid Build Coastguard Worker     m_ctx.readPixels(m_screen, 0, 0, m_screen.getWidth(), m_screen.getHeight());
2512*35238bceSAndroid Build Coastguard Worker }
2513*35238bceSAndroid Build Coastguard Worker 
2514*35238bceSAndroid Build Coastguard Worker // DrawTestSpec
2515*35238bceSAndroid Build Coastguard Worker 
createAttributeArray(InputType inputType,OutputType outputType,Storage storage,Usage usage,int componentCount,int offset,int stride,bool normalize,int instanceDivisor)2516*35238bceSAndroid Build Coastguard Worker DrawTestSpec::AttributeSpec DrawTestSpec::AttributeSpec::createAttributeArray(InputType inputType,
2517*35238bceSAndroid Build Coastguard Worker                                                                               OutputType outputType, Storage storage,
2518*35238bceSAndroid Build Coastguard Worker                                                                               Usage usage, int componentCount,
2519*35238bceSAndroid Build Coastguard Worker                                                                               int offset, int stride, bool normalize,
2520*35238bceSAndroid Build Coastguard Worker                                                                               int instanceDivisor)
2521*35238bceSAndroid Build Coastguard Worker {
2522*35238bceSAndroid Build Coastguard Worker     DrawTestSpec::AttributeSpec spec;
2523*35238bceSAndroid Build Coastguard Worker 
2524*35238bceSAndroid Build Coastguard Worker     spec.inputType       = inputType;
2525*35238bceSAndroid Build Coastguard Worker     spec.outputType      = outputType;
2526*35238bceSAndroid Build Coastguard Worker     spec.storage         = storage;
2527*35238bceSAndroid Build Coastguard Worker     spec.usage           = usage;
2528*35238bceSAndroid Build Coastguard Worker     spec.componentCount  = componentCount;
2529*35238bceSAndroid Build Coastguard Worker     spec.offset          = offset;
2530*35238bceSAndroid Build Coastguard Worker     spec.stride          = stride;
2531*35238bceSAndroid Build Coastguard Worker     spec.normalize       = normalize;
2532*35238bceSAndroid Build Coastguard Worker     spec.instanceDivisor = instanceDivisor;
2533*35238bceSAndroid Build Coastguard Worker 
2534*35238bceSAndroid Build Coastguard Worker     spec.useDefaultAttribute = false;
2535*35238bceSAndroid Build Coastguard Worker 
2536*35238bceSAndroid Build Coastguard Worker     return spec;
2537*35238bceSAndroid Build Coastguard Worker }
2538*35238bceSAndroid Build Coastguard Worker 
createDefaultAttribute(InputType inputType,OutputType outputType,int componentCount)2539*35238bceSAndroid Build Coastguard Worker DrawTestSpec::AttributeSpec DrawTestSpec::AttributeSpec::createDefaultAttribute(InputType inputType,
2540*35238bceSAndroid Build Coastguard Worker                                                                                 OutputType outputType,
2541*35238bceSAndroid Build Coastguard Worker                                                                                 int componentCount)
2542*35238bceSAndroid Build Coastguard Worker {
2543*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(inputType == INPUTTYPE_INT || inputType == INPUTTYPE_UNSIGNED_INT || inputType == INPUTTYPE_FLOAT);
2544*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(inputType == INPUTTYPE_FLOAT || componentCount == 4);
2545*35238bceSAndroid Build Coastguard Worker 
2546*35238bceSAndroid Build Coastguard Worker     DrawTestSpec::AttributeSpec spec;
2547*35238bceSAndroid Build Coastguard Worker 
2548*35238bceSAndroid Build Coastguard Worker     spec.inputType       = inputType;
2549*35238bceSAndroid Build Coastguard Worker     spec.outputType      = outputType;
2550*35238bceSAndroid Build Coastguard Worker     spec.storage         = DrawTestSpec::STORAGE_LAST;
2551*35238bceSAndroid Build Coastguard Worker     spec.usage           = DrawTestSpec::USAGE_LAST;
2552*35238bceSAndroid Build Coastguard Worker     spec.componentCount  = componentCount;
2553*35238bceSAndroid Build Coastguard Worker     spec.offset          = 0;
2554*35238bceSAndroid Build Coastguard Worker     spec.stride          = 0;
2555*35238bceSAndroid Build Coastguard Worker     spec.normalize       = 0;
2556*35238bceSAndroid Build Coastguard Worker     spec.instanceDivisor = 0;
2557*35238bceSAndroid Build Coastguard Worker 
2558*35238bceSAndroid Build Coastguard Worker     spec.useDefaultAttribute = true;
2559*35238bceSAndroid Build Coastguard Worker 
2560*35238bceSAndroid Build Coastguard Worker     return spec;
2561*35238bceSAndroid Build Coastguard Worker }
2562*35238bceSAndroid Build Coastguard Worker 
AttributeSpec(void)2563*35238bceSAndroid Build Coastguard Worker DrawTestSpec::AttributeSpec::AttributeSpec(void)
2564*35238bceSAndroid Build Coastguard Worker {
2565*35238bceSAndroid Build Coastguard Worker     inputType                   = DrawTestSpec::INPUTTYPE_LAST;
2566*35238bceSAndroid Build Coastguard Worker     outputType                  = DrawTestSpec::OUTPUTTYPE_LAST;
2567*35238bceSAndroid Build Coastguard Worker     storage                     = DrawTestSpec::STORAGE_LAST;
2568*35238bceSAndroid Build Coastguard Worker     usage                       = DrawTestSpec::USAGE_LAST;
2569*35238bceSAndroid Build Coastguard Worker     componentCount              = 0;
2570*35238bceSAndroid Build Coastguard Worker     offset                      = 0;
2571*35238bceSAndroid Build Coastguard Worker     stride                      = 0;
2572*35238bceSAndroid Build Coastguard Worker     normalize                   = false;
2573*35238bceSAndroid Build Coastguard Worker     instanceDivisor             = 0;
2574*35238bceSAndroid Build Coastguard Worker     useDefaultAttribute         = false;
2575*35238bceSAndroid Build Coastguard Worker     additionalPositionAttribute = false;
2576*35238bceSAndroid Build Coastguard Worker     bgraComponentOrder          = false;
2577*35238bceSAndroid Build Coastguard Worker }
2578*35238bceSAndroid Build Coastguard Worker 
hash(void) const2579*35238bceSAndroid Build Coastguard Worker int DrawTestSpec::AttributeSpec::hash(void) const
2580*35238bceSAndroid Build Coastguard Worker {
2581*35238bceSAndroid Build Coastguard Worker     if (useDefaultAttribute)
2582*35238bceSAndroid Build Coastguard Worker     {
2583*35238bceSAndroid Build Coastguard Worker         return 1 * int(inputType) + 7 * int(outputType) + 13 * componentCount;
2584*35238bceSAndroid Build Coastguard Worker     }
2585*35238bceSAndroid Build Coastguard Worker     else
2586*35238bceSAndroid Build Coastguard Worker     {
2587*35238bceSAndroid Build Coastguard Worker         return 1 * int(inputType) + 2 * int(outputType) + 3 * int(storage) + 5 * int(usage) + 7 * componentCount +
2588*35238bceSAndroid Build Coastguard Worker                11 * offset + 13 * stride + 17 * (normalize ? 0 : 1) + 19 * instanceDivisor;
2589*35238bceSAndroid Build Coastguard Worker     }
2590*35238bceSAndroid Build Coastguard Worker }
2591*35238bceSAndroid Build Coastguard Worker 
valid(glu::ApiType ctxType) const2592*35238bceSAndroid Build Coastguard Worker bool DrawTestSpec::AttributeSpec::valid(glu::ApiType ctxType) const
2593*35238bceSAndroid Build Coastguard Worker {
2594*35238bceSAndroid Build Coastguard Worker     const bool inputTypeFloat = inputType == DrawTestSpec::INPUTTYPE_FLOAT ||
2595*35238bceSAndroid Build Coastguard Worker                                 inputType == DrawTestSpec::INPUTTYPE_FIXED || inputType == DrawTestSpec::INPUTTYPE_HALF;
2596*35238bceSAndroid Build Coastguard Worker     const bool inputTypeUnsignedInteger = inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE ||
2597*35238bceSAndroid Build Coastguard Worker                                           inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT ||
2598*35238bceSAndroid Build Coastguard Worker                                           inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_INT ||
2599*35238bceSAndroid Build Coastguard Worker                                           inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10;
2600*35238bceSAndroid Build Coastguard Worker     const bool inputTypeSignedInteger =
2601*35238bceSAndroid Build Coastguard Worker         inputType == DrawTestSpec::INPUTTYPE_BYTE || inputType == DrawTestSpec::INPUTTYPE_SHORT ||
2602*35238bceSAndroid Build Coastguard Worker         inputType == DrawTestSpec::INPUTTYPE_INT || inputType == DrawTestSpec::INPUTTYPE_INT_2_10_10_10;
2603*35238bceSAndroid Build Coastguard Worker     const bool inputTypePacked = inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10 ||
2604*35238bceSAndroid Build Coastguard Worker                                  inputType == DrawTestSpec::INPUTTYPE_INT_2_10_10_10;
2605*35238bceSAndroid Build Coastguard Worker 
2606*35238bceSAndroid Build Coastguard Worker     const bool outputTypeFloat =
2607*35238bceSAndroid Build Coastguard Worker         outputType == DrawTestSpec::OUTPUTTYPE_FLOAT || outputType == DrawTestSpec::OUTPUTTYPE_VEC2 ||
2608*35238bceSAndroid Build Coastguard Worker         outputType == DrawTestSpec::OUTPUTTYPE_VEC3 || outputType == DrawTestSpec::OUTPUTTYPE_VEC4;
2609*35238bceSAndroid Build Coastguard Worker     const bool outputTypeSignedInteger =
2610*35238bceSAndroid Build Coastguard Worker         outputType == DrawTestSpec::OUTPUTTYPE_INT || outputType == DrawTestSpec::OUTPUTTYPE_IVEC2 ||
2611*35238bceSAndroid Build Coastguard Worker         outputType == DrawTestSpec::OUTPUTTYPE_IVEC3 || outputType == DrawTestSpec::OUTPUTTYPE_IVEC4;
2612*35238bceSAndroid Build Coastguard Worker     const bool outputTypeUnsignedInteger =
2613*35238bceSAndroid Build Coastguard Worker         outputType == DrawTestSpec::OUTPUTTYPE_UINT || outputType == DrawTestSpec::OUTPUTTYPE_UVEC2 ||
2614*35238bceSAndroid Build Coastguard Worker         outputType == DrawTestSpec::OUTPUTTYPE_UVEC3 || outputType == DrawTestSpec::OUTPUTTYPE_UVEC4;
2615*35238bceSAndroid Build Coastguard Worker 
2616*35238bceSAndroid Build Coastguard Worker     if (useDefaultAttribute)
2617*35238bceSAndroid Build Coastguard Worker     {
2618*35238bceSAndroid Build Coastguard Worker         if (inputType != DrawTestSpec::INPUTTYPE_INT && inputType != DrawTestSpec::INPUTTYPE_UNSIGNED_INT &&
2619*35238bceSAndroid Build Coastguard Worker             inputType != DrawTestSpec::INPUTTYPE_FLOAT)
2620*35238bceSAndroid Build Coastguard Worker             return false;
2621*35238bceSAndroid Build Coastguard Worker 
2622*35238bceSAndroid Build Coastguard Worker         if (inputType != DrawTestSpec::INPUTTYPE_FLOAT && componentCount != 4)
2623*35238bceSAndroid Build Coastguard Worker             return false;
2624*35238bceSAndroid Build Coastguard Worker 
2625*35238bceSAndroid Build Coastguard Worker         // no casting allowed (undefined results)
2626*35238bceSAndroid Build Coastguard Worker         if (inputType == DrawTestSpec::INPUTTYPE_INT && !outputTypeSignedInteger)
2627*35238bceSAndroid Build Coastguard Worker             return false;
2628*35238bceSAndroid Build Coastguard Worker         if (inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_INT && !outputTypeUnsignedInteger)
2629*35238bceSAndroid Build Coastguard Worker             return false;
2630*35238bceSAndroid Build Coastguard Worker     }
2631*35238bceSAndroid Build Coastguard Worker 
2632*35238bceSAndroid Build Coastguard Worker     if (inputTypePacked && componentCount != 4)
2633*35238bceSAndroid Build Coastguard Worker         return false;
2634*35238bceSAndroid Build Coastguard Worker 
2635*35238bceSAndroid Build Coastguard Worker     // Invalid conversions:
2636*35238bceSAndroid Build Coastguard Worker 
2637*35238bceSAndroid Build Coastguard Worker     // float -> [u]int
2638*35238bceSAndroid Build Coastguard Worker     if (inputTypeFloat && !outputTypeFloat)
2639*35238bceSAndroid Build Coastguard Worker         return false;
2640*35238bceSAndroid Build Coastguard Worker 
2641*35238bceSAndroid Build Coastguard Worker     // uint -> int        (undefined results)
2642*35238bceSAndroid Build Coastguard Worker     if (inputTypeUnsignedInteger && outputTypeSignedInteger)
2643*35238bceSAndroid Build Coastguard Worker         return false;
2644*35238bceSAndroid Build Coastguard Worker 
2645*35238bceSAndroid Build Coastguard Worker     // int -> uint        (undefined results)
2646*35238bceSAndroid Build Coastguard Worker     if (inputTypeSignedInteger && outputTypeUnsignedInteger)
2647*35238bceSAndroid Build Coastguard Worker         return false;
2648*35238bceSAndroid Build Coastguard Worker 
2649*35238bceSAndroid Build Coastguard Worker     // packed -> non-float (packed formats are converted to floats)
2650*35238bceSAndroid Build Coastguard Worker     if (inputTypePacked && !outputTypeFloat)
2651*35238bceSAndroid Build Coastguard Worker         return false;
2652*35238bceSAndroid Build Coastguard Worker 
2653*35238bceSAndroid Build Coastguard Worker     // Invalid normalize. Normalize is only valid if output type is float
2654*35238bceSAndroid Build Coastguard Worker     if (normalize && !outputTypeFloat)
2655*35238bceSAndroid Build Coastguard Worker         return false;
2656*35238bceSAndroid Build Coastguard Worker 
2657*35238bceSAndroid Build Coastguard Worker     // Allow reverse order (GL_BGRA) only for packed and 4-component ubyte
2658*35238bceSAndroid Build Coastguard Worker     if (bgraComponentOrder && componentCount != 4)
2659*35238bceSAndroid Build Coastguard Worker         return false;
2660*35238bceSAndroid Build Coastguard Worker     if (bgraComponentOrder && inputType != DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10 &&
2661*35238bceSAndroid Build Coastguard Worker         inputType != DrawTestSpec::INPUTTYPE_INT_2_10_10_10 && inputType != DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE)
2662*35238bceSAndroid Build Coastguard Worker         return false;
2663*35238bceSAndroid Build Coastguard Worker     if (bgraComponentOrder && normalize != true)
2664*35238bceSAndroid Build Coastguard Worker         return false;
2665*35238bceSAndroid Build Coastguard Worker 
2666*35238bceSAndroid Build Coastguard Worker     // GLES2 limits
2667*35238bceSAndroid Build Coastguard Worker     if (ctxType == glu::ApiType::es(2, 0))
2668*35238bceSAndroid Build Coastguard Worker     {
2669*35238bceSAndroid Build Coastguard Worker         if (inputType != DrawTestSpec::INPUTTYPE_FLOAT && inputType != DrawTestSpec::INPUTTYPE_FIXED &&
2670*35238bceSAndroid Build Coastguard Worker             inputType != DrawTestSpec::INPUTTYPE_BYTE && inputType != DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE &&
2671*35238bceSAndroid Build Coastguard Worker             inputType != DrawTestSpec::INPUTTYPE_SHORT && inputType != DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT)
2672*35238bceSAndroid Build Coastguard Worker             return false;
2673*35238bceSAndroid Build Coastguard Worker 
2674*35238bceSAndroid Build Coastguard Worker         if (!outputTypeFloat)
2675*35238bceSAndroid Build Coastguard Worker             return false;
2676*35238bceSAndroid Build Coastguard Worker 
2677*35238bceSAndroid Build Coastguard Worker         if (bgraComponentOrder)
2678*35238bceSAndroid Build Coastguard Worker             return false;
2679*35238bceSAndroid Build Coastguard Worker     }
2680*35238bceSAndroid Build Coastguard Worker 
2681*35238bceSAndroid Build Coastguard Worker     // GLES3 limits
2682*35238bceSAndroid Build Coastguard Worker     if (ctxType.getProfile() == glu::PROFILE_ES && ctxType.getMajorVersion() == 3)
2683*35238bceSAndroid Build Coastguard Worker     {
2684*35238bceSAndroid Build Coastguard Worker         if (bgraComponentOrder)
2685*35238bceSAndroid Build Coastguard Worker             return false;
2686*35238bceSAndroid Build Coastguard Worker     }
2687*35238bceSAndroid Build Coastguard Worker 
2688*35238bceSAndroid Build Coastguard Worker     // No user pointers in GL core
2689*35238bceSAndroid Build Coastguard Worker     if (ctxType.getProfile() == glu::PROFILE_CORE)
2690*35238bceSAndroid Build Coastguard Worker     {
2691*35238bceSAndroid Build Coastguard Worker         if (!useDefaultAttribute && storage == DrawTestSpec::STORAGE_USER)
2692*35238bceSAndroid Build Coastguard Worker             return false;
2693*35238bceSAndroid Build Coastguard Worker     }
2694*35238bceSAndroid Build Coastguard Worker 
2695*35238bceSAndroid Build Coastguard Worker     return true;
2696*35238bceSAndroid Build Coastguard Worker }
2697*35238bceSAndroid Build Coastguard Worker 
isBufferAligned(void) const2698*35238bceSAndroid Build Coastguard Worker bool DrawTestSpec::AttributeSpec::isBufferAligned(void) const
2699*35238bceSAndroid Build Coastguard Worker {
2700*35238bceSAndroid Build Coastguard Worker     const bool inputTypePacked = inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10 ||
2701*35238bceSAndroid Build Coastguard Worker                                  inputType == DrawTestSpec::INPUTTYPE_INT_2_10_10_10;
2702*35238bceSAndroid Build Coastguard Worker 
2703*35238bceSAndroid Build Coastguard Worker     // Buffer alignment, offset is a multiple of underlying data type size?
2704*35238bceSAndroid Build Coastguard Worker     if (storage == STORAGE_BUFFER)
2705*35238bceSAndroid Build Coastguard Worker     {
2706*35238bceSAndroid Build Coastguard Worker         int dataTypeSize = gls::DrawTestSpec::inputTypeSize(inputType);
2707*35238bceSAndroid Build Coastguard Worker         if (inputTypePacked)
2708*35238bceSAndroid Build Coastguard Worker             dataTypeSize = 4;
2709*35238bceSAndroid Build Coastguard Worker 
2710*35238bceSAndroid Build Coastguard Worker         if (offset % dataTypeSize != 0)
2711*35238bceSAndroid Build Coastguard Worker             return false;
2712*35238bceSAndroid Build Coastguard Worker     }
2713*35238bceSAndroid Build Coastguard Worker 
2714*35238bceSAndroid Build Coastguard Worker     return true;
2715*35238bceSAndroid Build Coastguard Worker }
2716*35238bceSAndroid Build Coastguard Worker 
isBufferStrideAligned(void) const2717*35238bceSAndroid Build Coastguard Worker bool DrawTestSpec::AttributeSpec::isBufferStrideAligned(void) const
2718*35238bceSAndroid Build Coastguard Worker {
2719*35238bceSAndroid Build Coastguard Worker     const bool inputTypePacked = inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10 ||
2720*35238bceSAndroid Build Coastguard Worker                                  inputType == DrawTestSpec::INPUTTYPE_INT_2_10_10_10;
2721*35238bceSAndroid Build Coastguard Worker 
2722*35238bceSAndroid Build Coastguard Worker     // Buffer alignment, offset is a multiple of underlying data type size?
2723*35238bceSAndroid Build Coastguard Worker     if (storage == STORAGE_BUFFER)
2724*35238bceSAndroid Build Coastguard Worker     {
2725*35238bceSAndroid Build Coastguard Worker         int dataTypeSize = gls::DrawTestSpec::inputTypeSize(inputType);
2726*35238bceSAndroid Build Coastguard Worker         if (inputTypePacked)
2727*35238bceSAndroid Build Coastguard Worker             dataTypeSize = 4;
2728*35238bceSAndroid Build Coastguard Worker 
2729*35238bceSAndroid Build Coastguard Worker         if (stride % dataTypeSize != 0)
2730*35238bceSAndroid Build Coastguard Worker             return false;
2731*35238bceSAndroid Build Coastguard Worker     }
2732*35238bceSAndroid Build Coastguard Worker 
2733*35238bceSAndroid Build Coastguard Worker     return true;
2734*35238bceSAndroid Build Coastguard Worker }
2735*35238bceSAndroid Build Coastguard Worker 
targetToString(Target target)2736*35238bceSAndroid Build Coastguard Worker std::string DrawTestSpec::targetToString(Target target)
2737*35238bceSAndroid Build Coastguard Worker {
2738*35238bceSAndroid Build Coastguard Worker     static const char *targets[] = {
2739*35238bceSAndroid Build Coastguard Worker         "element_array", // TARGET_ELEMENT_ARRAY = 0,
2740*35238bceSAndroid Build Coastguard Worker         "array"          // TARGET_ARRAY,
2741*35238bceSAndroid Build Coastguard Worker     };
2742*35238bceSAndroid Build Coastguard Worker 
2743*35238bceSAndroid Build Coastguard Worker     return de::getSizedArrayElement<DrawTestSpec::TARGET_LAST>(targets, (int)target);
2744*35238bceSAndroid Build Coastguard Worker }
2745*35238bceSAndroid Build Coastguard Worker 
inputTypeToString(InputType type)2746*35238bceSAndroid Build Coastguard Worker std::string DrawTestSpec::inputTypeToString(InputType type)
2747*35238bceSAndroid Build Coastguard Worker {
2748*35238bceSAndroid Build Coastguard Worker     static const char *types[] = {
2749*35238bceSAndroid Build Coastguard Worker         "float",  // INPUTTYPE_FLOAT = 0,
2750*35238bceSAndroid Build Coastguard Worker         "fixed",  // INPUTTYPE_FIXED,
2751*35238bceSAndroid Build Coastguard Worker         "double", // INPUTTYPE_DOUBLE
2752*35238bceSAndroid Build Coastguard Worker 
2753*35238bceSAndroid Build Coastguard Worker         "byte",  // INPUTTYPE_BYTE,
2754*35238bceSAndroid Build Coastguard Worker         "short", // INPUTTYPE_SHORT,
2755*35238bceSAndroid Build Coastguard Worker 
2756*35238bceSAndroid Build Coastguard Worker         "unsigned_byte",  // INPUTTYPE_UNSIGNED_BYTE,
2757*35238bceSAndroid Build Coastguard Worker         "unsigned_short", // INPUTTYPE_UNSIGNED_SHORT,
2758*35238bceSAndroid Build Coastguard Worker 
2759*35238bceSAndroid Build Coastguard Worker         "int",                    // INPUTTYPE_INT,
2760*35238bceSAndroid Build Coastguard Worker         "unsigned_int",           // INPUTTYPE_UNSIGNED_INT,
2761*35238bceSAndroid Build Coastguard Worker         "half",                   // INPUTTYPE_HALF,
2762*35238bceSAndroid Build Coastguard Worker         "unsigned_int2_10_10_10", // INPUTTYPE_UNSIGNED_INT_2_10_10_10,
2763*35238bceSAndroid Build Coastguard Worker         "int2_10_10_10"           // INPUTTYPE_INT_2_10_10_10,
2764*35238bceSAndroid Build Coastguard Worker     };
2765*35238bceSAndroid Build Coastguard Worker 
2766*35238bceSAndroid Build Coastguard Worker     return de::getSizedArrayElement<DrawTestSpec::INPUTTYPE_LAST>(types, (int)type);
2767*35238bceSAndroid Build Coastguard Worker }
2768*35238bceSAndroid Build Coastguard Worker 
outputTypeToString(OutputType type)2769*35238bceSAndroid Build Coastguard Worker std::string DrawTestSpec::outputTypeToString(OutputType type)
2770*35238bceSAndroid Build Coastguard Worker {
2771*35238bceSAndroid Build Coastguard Worker     static const char *types[] = {
2772*35238bceSAndroid Build Coastguard Worker         "float", // OUTPUTTYPE_FLOAT = 0,
2773*35238bceSAndroid Build Coastguard Worker         "vec2",  // OUTPUTTYPE_VEC2,
2774*35238bceSAndroid Build Coastguard Worker         "vec3",  // OUTPUTTYPE_VEC3,
2775*35238bceSAndroid Build Coastguard Worker         "vec4",  // OUTPUTTYPE_VEC4,
2776*35238bceSAndroid Build Coastguard Worker 
2777*35238bceSAndroid Build Coastguard Worker         "int",  // OUTPUTTYPE_INT,
2778*35238bceSAndroid Build Coastguard Worker         "uint", // OUTPUTTYPE_UINT,
2779*35238bceSAndroid Build Coastguard Worker 
2780*35238bceSAndroid Build Coastguard Worker         "ivec2", // OUTPUTTYPE_IVEC2,
2781*35238bceSAndroid Build Coastguard Worker         "ivec3", // OUTPUTTYPE_IVEC3,
2782*35238bceSAndroid Build Coastguard Worker         "ivec4", // OUTPUTTYPE_IVEC4,
2783*35238bceSAndroid Build Coastguard Worker 
2784*35238bceSAndroid Build Coastguard Worker         "uvec2", // OUTPUTTYPE_UVEC2,
2785*35238bceSAndroid Build Coastguard Worker         "uvec3", // OUTPUTTYPE_UVEC3,
2786*35238bceSAndroid Build Coastguard Worker         "uvec4", // OUTPUTTYPE_UVEC4,
2787*35238bceSAndroid Build Coastguard Worker     };
2788*35238bceSAndroid Build Coastguard Worker 
2789*35238bceSAndroid Build Coastguard Worker     return de::getSizedArrayElement<DrawTestSpec::OUTPUTTYPE_LAST>(types, (int)type);
2790*35238bceSAndroid Build Coastguard Worker }
2791*35238bceSAndroid Build Coastguard Worker 
usageTypeToString(Usage usage)2792*35238bceSAndroid Build Coastguard Worker std::string DrawTestSpec::usageTypeToString(Usage usage)
2793*35238bceSAndroid Build Coastguard Worker {
2794*35238bceSAndroid Build Coastguard Worker     static const char *usages[] = {
2795*35238bceSAndroid Build Coastguard Worker         "dynamic_draw", // USAGE_DYNAMIC_DRAW = 0,
2796*35238bceSAndroid Build Coastguard Worker         "static_draw",  // USAGE_STATIC_DRAW,
2797*35238bceSAndroid Build Coastguard Worker         "stream_draw",  // USAGE_STREAM_DRAW,
2798*35238bceSAndroid Build Coastguard Worker 
2799*35238bceSAndroid Build Coastguard Worker         "stream_read", // USAGE_STREAM_READ,
2800*35238bceSAndroid Build Coastguard Worker         "stream_copy", // USAGE_STREAM_COPY,
2801*35238bceSAndroid Build Coastguard Worker 
2802*35238bceSAndroid Build Coastguard Worker         "static_read", // USAGE_STATIC_READ,
2803*35238bceSAndroid Build Coastguard Worker         "static_copy", // USAGE_STATIC_COPY,
2804*35238bceSAndroid Build Coastguard Worker 
2805*35238bceSAndroid Build Coastguard Worker         "dynamic_read", // USAGE_DYNAMIC_READ,
2806*35238bceSAndroid Build Coastguard Worker         "dynamic_copy", // USAGE_DYNAMIC_COPY,
2807*35238bceSAndroid Build Coastguard Worker     };
2808*35238bceSAndroid Build Coastguard Worker 
2809*35238bceSAndroid Build Coastguard Worker     return de::getSizedArrayElement<DrawTestSpec::USAGE_LAST>(usages, (int)usage);
2810*35238bceSAndroid Build Coastguard Worker }
2811*35238bceSAndroid Build Coastguard Worker 
storageToString(Storage storage)2812*35238bceSAndroid Build Coastguard Worker std::string DrawTestSpec::storageToString(Storage storage)
2813*35238bceSAndroid Build Coastguard Worker {
2814*35238bceSAndroid Build Coastguard Worker     static const char *storages[] = {
2815*35238bceSAndroid Build Coastguard Worker         "user_ptr", // STORAGE_USER = 0,
2816*35238bceSAndroid Build Coastguard Worker         "buffer"    // STORAGE_BUFFER,
2817*35238bceSAndroid Build Coastguard Worker     };
2818*35238bceSAndroid Build Coastguard Worker 
2819*35238bceSAndroid Build Coastguard Worker     return de::getSizedArrayElement<DrawTestSpec::STORAGE_LAST>(storages, (int)storage);
2820*35238bceSAndroid Build Coastguard Worker }
2821*35238bceSAndroid Build Coastguard Worker 
primitiveToString(Primitive primitive)2822*35238bceSAndroid Build Coastguard Worker std::string DrawTestSpec::primitiveToString(Primitive primitive)
2823*35238bceSAndroid Build Coastguard Worker {
2824*35238bceSAndroid Build Coastguard Worker     static const char *primitives[] = {
2825*35238bceSAndroid Build Coastguard Worker         "points",                   // PRIMITIVE_POINTS ,
2826*35238bceSAndroid Build Coastguard Worker         "triangles",                // PRIMITIVE_TRIANGLES,
2827*35238bceSAndroid Build Coastguard Worker         "triangle_fan",             // PRIMITIVE_TRIANGLE_FAN,
2828*35238bceSAndroid Build Coastguard Worker         "triangle_strip",           // PRIMITIVE_TRIANGLE_STRIP,
2829*35238bceSAndroid Build Coastguard Worker         "lines",                    // PRIMITIVE_LINES
2830*35238bceSAndroid Build Coastguard Worker         "line_strip",               // PRIMITIVE_LINE_STRIP
2831*35238bceSAndroid Build Coastguard Worker         "line_loop",                // PRIMITIVE_LINE_LOOP
2832*35238bceSAndroid Build Coastguard Worker         "lines_adjacency",          // PRIMITIVE_LINES_ADJACENCY
2833*35238bceSAndroid Build Coastguard Worker         "line_strip_adjacency",     // PRIMITIVE_LINE_STRIP_ADJACENCY
2834*35238bceSAndroid Build Coastguard Worker         "triangles_adjacency",      // PRIMITIVE_TRIANGLES_ADJACENCY
2835*35238bceSAndroid Build Coastguard Worker         "triangle_strip_adjacency", // PRIMITIVE_TRIANGLE_STRIP_ADJACENCY
2836*35238bceSAndroid Build Coastguard Worker     };
2837*35238bceSAndroid Build Coastguard Worker 
2838*35238bceSAndroid Build Coastguard Worker     return de::getSizedArrayElement<DrawTestSpec::PRIMITIVE_LAST>(primitives, (int)primitive);
2839*35238bceSAndroid Build Coastguard Worker }
2840*35238bceSAndroid Build Coastguard Worker 
indexTypeToString(IndexType type)2841*35238bceSAndroid Build Coastguard Worker std::string DrawTestSpec::indexTypeToString(IndexType type)
2842*35238bceSAndroid Build Coastguard Worker {
2843*35238bceSAndroid Build Coastguard Worker     static const char *indexTypes[] = {
2844*35238bceSAndroid Build Coastguard Worker         "byte",  // INDEXTYPE_BYTE = 0,
2845*35238bceSAndroid Build Coastguard Worker         "short", // INDEXTYPE_SHORT,
2846*35238bceSAndroid Build Coastguard Worker         "int",   // INDEXTYPE_INT,
2847*35238bceSAndroid Build Coastguard Worker     };
2848*35238bceSAndroid Build Coastguard Worker 
2849*35238bceSAndroid Build Coastguard Worker     return de::getSizedArrayElement<DrawTestSpec::INDEXTYPE_LAST>(indexTypes, (int)type);
2850*35238bceSAndroid Build Coastguard Worker }
2851*35238bceSAndroid Build Coastguard Worker 
drawMethodToString(DrawTestSpec::DrawMethod method)2852*35238bceSAndroid Build Coastguard Worker std::string DrawTestSpec::drawMethodToString(DrawTestSpec::DrawMethod method)
2853*35238bceSAndroid Build Coastguard Worker {
2854*35238bceSAndroid Build Coastguard Worker     static const char *methods[] = {
2855*35238bceSAndroid Build Coastguard Worker         "draw_arrays",                         //!< DRAWMETHOD_DRAWARRAYS
2856*35238bceSAndroid Build Coastguard Worker         "draw_arrays_instanced",               //!< DRAWMETHOD_DRAWARRAYS_INSTANCED
2857*35238bceSAndroid Build Coastguard Worker         "draw_arrays_indirect",                //!< DRAWMETHOD_DRAWARRAYS_INDIRECT
2858*35238bceSAndroid Build Coastguard Worker         "draw_elements",                       //!< DRAWMETHOD_DRAWELEMENTS
2859*35238bceSAndroid Build Coastguard Worker         "draw_range_elements",                 //!< DRAWMETHOD_DRAWELEMENTS_RANGED
2860*35238bceSAndroid Build Coastguard Worker         "draw_elements_instanced",             //!< DRAWMETHOD_DRAWELEMENTS_INSTANCED
2861*35238bceSAndroid Build Coastguard Worker         "draw_elements_indirect",              //!< DRAWMETHOD_DRAWELEMENTS_INDIRECT
2862*35238bceSAndroid Build Coastguard Worker         "draw_elements_base_vertex",           //!< DRAWMETHOD_DRAWELEMENTS_BASEVERTEX,
2863*35238bceSAndroid Build Coastguard Worker         "draw_elements_instanced_base_vertex", //!< DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX,
2864*35238bceSAndroid Build Coastguard Worker         "draw_range_elements_base_vertex",     //!< DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX,
2865*35238bceSAndroid Build Coastguard Worker     };
2866*35238bceSAndroid Build Coastguard Worker 
2867*35238bceSAndroid Build Coastguard Worker     return de::getSizedArrayElement<DrawTestSpec::DRAWMETHOD_LAST>(methods, (int)method);
2868*35238bceSAndroid Build Coastguard Worker }
2869*35238bceSAndroid Build Coastguard Worker 
inputTypeSize(InputType type)2870*35238bceSAndroid Build Coastguard Worker int DrawTestSpec::inputTypeSize(InputType type)
2871*35238bceSAndroid Build Coastguard Worker {
2872*35238bceSAndroid Build Coastguard Worker     static const int size[] = {
2873*35238bceSAndroid Build Coastguard Worker         (int)sizeof(float),   // INPUTTYPE_FLOAT = 0,
2874*35238bceSAndroid Build Coastguard Worker         (int)sizeof(int32_t), // INPUTTYPE_FIXED,
2875*35238bceSAndroid Build Coastguard Worker         (int)sizeof(double),  // INPUTTYPE_DOUBLE
2876*35238bceSAndroid Build Coastguard Worker 
2877*35238bceSAndroid Build Coastguard Worker         (int)sizeof(int8_t),  // INPUTTYPE_BYTE,
2878*35238bceSAndroid Build Coastguard Worker         (int)sizeof(int16_t), // INPUTTYPE_SHORT,
2879*35238bceSAndroid Build Coastguard Worker 
2880*35238bceSAndroid Build Coastguard Worker         (int)sizeof(uint8_t),  // INPUTTYPE_UNSIGNED_BYTE,
2881*35238bceSAndroid Build Coastguard Worker         (int)sizeof(uint16_t), // INPUTTYPE_UNSIGNED_SHORT,
2882*35238bceSAndroid Build Coastguard Worker 
2883*35238bceSAndroid Build Coastguard Worker         (int)sizeof(int32_t),      // INPUTTYPE_INT,
2884*35238bceSAndroid Build Coastguard Worker         (int)sizeof(uint32_t),     // INPUTTYPE_UNSIGNED_INT,
2885*35238bceSAndroid Build Coastguard Worker         (int)sizeof(deFloat16),    // INPUTTYPE_HALF,
2886*35238bceSAndroid Build Coastguard Worker         (int)sizeof(uint32_t) / 4, // INPUTTYPE_UNSIGNED_INT_2_10_10_10,
2887*35238bceSAndroid Build Coastguard Worker         (int)sizeof(uint32_t) / 4  // INPUTTYPE_INT_2_10_10_10,
2888*35238bceSAndroid Build Coastguard Worker     };
2889*35238bceSAndroid Build Coastguard Worker 
2890*35238bceSAndroid Build Coastguard Worker     return de::getSizedArrayElement<DrawTestSpec::INPUTTYPE_LAST>(size, (int)type);
2891*35238bceSAndroid Build Coastguard Worker }
2892*35238bceSAndroid Build Coastguard Worker 
indexTypeSize(IndexType type)2893*35238bceSAndroid Build Coastguard Worker int DrawTestSpec::indexTypeSize(IndexType type)
2894*35238bceSAndroid Build Coastguard Worker {
2895*35238bceSAndroid Build Coastguard Worker     static const int size[] = {
2896*35238bceSAndroid Build Coastguard Worker         sizeof(uint8_t),  // INDEXTYPE_BYTE,
2897*35238bceSAndroid Build Coastguard Worker         sizeof(uint16_t), // INDEXTYPE_SHORT,
2898*35238bceSAndroid Build Coastguard Worker         sizeof(uint32_t), // INDEXTYPE_INT,
2899*35238bceSAndroid Build Coastguard Worker     };
2900*35238bceSAndroid Build Coastguard Worker 
2901*35238bceSAndroid Build Coastguard Worker     return de::getSizedArrayElement<DrawTestSpec::INDEXTYPE_LAST>(size, (int)type);
2902*35238bceSAndroid Build Coastguard Worker }
2903*35238bceSAndroid Build Coastguard Worker 
getName(void) const2904*35238bceSAndroid Build Coastguard Worker std::string DrawTestSpec::getName(void) const
2905*35238bceSAndroid Build Coastguard Worker {
2906*35238bceSAndroid Build Coastguard Worker     const MethodInfo methodInfo = getMethodInfo(drawMethod);
2907*35238bceSAndroid Build Coastguard Worker     const bool hasFirst         = methodInfo.first;
2908*35238bceSAndroid Build Coastguard Worker     const bool instanced        = methodInfo.instanced;
2909*35238bceSAndroid Build Coastguard Worker     const bool ranged           = methodInfo.ranged;
2910*35238bceSAndroid Build Coastguard Worker     const bool indexed          = methodInfo.indexed;
2911*35238bceSAndroid Build Coastguard Worker 
2912*35238bceSAndroid Build Coastguard Worker     std::stringstream name;
2913*35238bceSAndroid Build Coastguard Worker 
2914*35238bceSAndroid Build Coastguard Worker     for (size_t ndx = 0; ndx < attribs.size(); ++ndx)
2915*35238bceSAndroid Build Coastguard Worker     {
2916*35238bceSAndroid Build Coastguard Worker         const AttributeSpec &attrib = attribs[ndx];
2917*35238bceSAndroid Build Coastguard Worker 
2918*35238bceSAndroid Build Coastguard Worker         if (attribs.size() > 1)
2919*35238bceSAndroid Build Coastguard Worker             name << "attrib" << ndx << "_";
2920*35238bceSAndroid Build Coastguard Worker 
2921*35238bceSAndroid Build Coastguard Worker         if (ndx == 0 || attrib.additionalPositionAttribute)
2922*35238bceSAndroid Build Coastguard Worker             name << "pos_";
2923*35238bceSAndroid Build Coastguard Worker         else
2924*35238bceSAndroid Build Coastguard Worker             name << "col_";
2925*35238bceSAndroid Build Coastguard Worker 
2926*35238bceSAndroid Build Coastguard Worker         if (attrib.useDefaultAttribute)
2927*35238bceSAndroid Build Coastguard Worker         {
2928*35238bceSAndroid Build Coastguard Worker             name << "non_array_" << DrawTestSpec::inputTypeToString((DrawTestSpec::InputType)attrib.inputType) << "_"
2929*35238bceSAndroid Build Coastguard Worker                  << attrib.componentCount << "_" << DrawTestSpec::outputTypeToString(attrib.outputType) << "_";
2930*35238bceSAndroid Build Coastguard Worker         }
2931*35238bceSAndroid Build Coastguard Worker         else
2932*35238bceSAndroid Build Coastguard Worker         {
2933*35238bceSAndroid Build Coastguard Worker             name << DrawTestSpec::storageToString(attrib.storage) << "_" << attrib.offset << "_" << attrib.stride << "_"
2934*35238bceSAndroid Build Coastguard Worker                  << DrawTestSpec::inputTypeToString((DrawTestSpec::InputType)attrib.inputType);
2935*35238bceSAndroid Build Coastguard Worker             if (attrib.inputType != DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10 &&
2936*35238bceSAndroid Build Coastguard Worker                 attrib.inputType != DrawTestSpec::INPUTTYPE_INT_2_10_10_10)
2937*35238bceSAndroid Build Coastguard Worker                 name << attrib.componentCount;
2938*35238bceSAndroid Build Coastguard Worker             name << "_" << (attrib.normalize ? "normalized_" : "")
2939*35238bceSAndroid Build Coastguard Worker                  << DrawTestSpec::outputTypeToString(attrib.outputType) << "_"
2940*35238bceSAndroid Build Coastguard Worker                  << DrawTestSpec::usageTypeToString(attrib.usage) << "_" << attrib.instanceDivisor << "_";
2941*35238bceSAndroid Build Coastguard Worker         }
2942*35238bceSAndroid Build Coastguard Worker     }
2943*35238bceSAndroid Build Coastguard Worker 
2944*35238bceSAndroid Build Coastguard Worker     if (indexed)
2945*35238bceSAndroid Build Coastguard Worker         name << "index_" << DrawTestSpec::indexTypeToString(indexType) << "_"
2946*35238bceSAndroid Build Coastguard Worker              << DrawTestSpec::storageToString(indexStorage) << "_"
2947*35238bceSAndroid Build Coastguard Worker              << "offset" << indexPointerOffset << "_";
2948*35238bceSAndroid Build Coastguard Worker     if (hasFirst)
2949*35238bceSAndroid Build Coastguard Worker         name << "first" << first << "_";
2950*35238bceSAndroid Build Coastguard Worker     if (ranged)
2951*35238bceSAndroid Build Coastguard Worker         name << "ranged_" << indexMin << "_" << indexMax << "_";
2952*35238bceSAndroid Build Coastguard Worker     if (instanced)
2953*35238bceSAndroid Build Coastguard Worker         name << "instances" << instanceCount << "_";
2954*35238bceSAndroid Build Coastguard Worker 
2955*35238bceSAndroid Build Coastguard Worker     switch (primitive)
2956*35238bceSAndroid Build Coastguard Worker     {
2957*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_POINTS:
2958*35238bceSAndroid Build Coastguard Worker         name << "points_";
2959*35238bceSAndroid Build Coastguard Worker         break;
2960*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_TRIANGLES:
2961*35238bceSAndroid Build Coastguard Worker         name << "triangles_";
2962*35238bceSAndroid Build Coastguard Worker         break;
2963*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_TRIANGLE_FAN:
2964*35238bceSAndroid Build Coastguard Worker         name << "triangle_fan_";
2965*35238bceSAndroid Build Coastguard Worker         break;
2966*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP:
2967*35238bceSAndroid Build Coastguard Worker         name << "triangle_strip_";
2968*35238bceSAndroid Build Coastguard Worker         break;
2969*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_LINES:
2970*35238bceSAndroid Build Coastguard Worker         name << "lines_";
2971*35238bceSAndroid Build Coastguard Worker         break;
2972*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_LINE_STRIP:
2973*35238bceSAndroid Build Coastguard Worker         name << "line_strip_";
2974*35238bceSAndroid Build Coastguard Worker         break;
2975*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_LINE_LOOP:
2976*35238bceSAndroid Build Coastguard Worker         name << "line_loop_";
2977*35238bceSAndroid Build Coastguard Worker         break;
2978*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_LINES_ADJACENCY:
2979*35238bceSAndroid Build Coastguard Worker         name << "line_adjancency";
2980*35238bceSAndroid Build Coastguard Worker         break;
2981*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_LINE_STRIP_ADJACENCY:
2982*35238bceSAndroid Build Coastguard Worker         name << "line_strip_adjancency";
2983*35238bceSAndroid Build Coastguard Worker         break;
2984*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_TRIANGLES_ADJACENCY:
2985*35238bceSAndroid Build Coastguard Worker         name << "triangles_adjancency";
2986*35238bceSAndroid Build Coastguard Worker         break;
2987*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP_ADJACENCY:
2988*35238bceSAndroid Build Coastguard Worker         name << "triangle_strip_adjancency";
2989*35238bceSAndroid Build Coastguard Worker         break;
2990*35238bceSAndroid Build Coastguard Worker     default:
2991*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
2992*35238bceSAndroid Build Coastguard Worker         break;
2993*35238bceSAndroid Build Coastguard Worker     }
2994*35238bceSAndroid Build Coastguard Worker 
2995*35238bceSAndroid Build Coastguard Worker     name << primitiveCount;
2996*35238bceSAndroid Build Coastguard Worker 
2997*35238bceSAndroid Build Coastguard Worker     return name.str();
2998*35238bceSAndroid Build Coastguard Worker }
2999*35238bceSAndroid Build Coastguard Worker 
getDesc(void) const3000*35238bceSAndroid Build Coastguard Worker std::string DrawTestSpec::getDesc(void) const
3001*35238bceSAndroid Build Coastguard Worker {
3002*35238bceSAndroid Build Coastguard Worker     std::stringstream desc;
3003*35238bceSAndroid Build Coastguard Worker 
3004*35238bceSAndroid Build Coastguard Worker     for (size_t ndx = 0; ndx < attribs.size(); ++ndx)
3005*35238bceSAndroid Build Coastguard Worker     {
3006*35238bceSAndroid Build Coastguard Worker         const AttributeSpec &attrib = attribs[ndx];
3007*35238bceSAndroid Build Coastguard Worker 
3008*35238bceSAndroid Build Coastguard Worker         if (attrib.useDefaultAttribute)
3009*35238bceSAndroid Build Coastguard Worker         {
3010*35238bceSAndroid Build Coastguard Worker             desc << "Attribute " << ndx << ": default, "
3011*35238bceSAndroid Build Coastguard Worker                  << ((ndx == 0 || attrib.additionalPositionAttribute) ? ("position ,") : ("color ,"))
3012*35238bceSAndroid Build Coastguard Worker                  << "input datatype " << DrawTestSpec::inputTypeToString((DrawTestSpec::InputType)attrib.inputType)
3013*35238bceSAndroid Build Coastguard Worker                  << ", "
3014*35238bceSAndroid Build Coastguard Worker                  << "input component count " << attrib.componentCount << ", "
3015*35238bceSAndroid Build Coastguard Worker                  << "used as " << DrawTestSpec::outputTypeToString(attrib.outputType) << ", ";
3016*35238bceSAndroid Build Coastguard Worker         }
3017*35238bceSAndroid Build Coastguard Worker         else
3018*35238bceSAndroid Build Coastguard Worker         {
3019*35238bceSAndroid Build Coastguard Worker             desc << "Attribute " << ndx << ": "
3020*35238bceSAndroid Build Coastguard Worker                  << ((ndx == 0 || attrib.additionalPositionAttribute) ? ("position ,") : ("color ,")) << "Storage in "
3021*35238bceSAndroid Build Coastguard Worker                  << DrawTestSpec::storageToString(attrib.storage) << ", "
3022*35238bceSAndroid Build Coastguard Worker                  << "stride " << attrib.stride << ", "
3023*35238bceSAndroid Build Coastguard Worker                  << "input datatype " << DrawTestSpec::inputTypeToString((DrawTestSpec::InputType)attrib.inputType)
3024*35238bceSAndroid Build Coastguard Worker                  << ", "
3025*35238bceSAndroid Build Coastguard Worker                  << "input component count " << attrib.componentCount << ", "
3026*35238bceSAndroid Build Coastguard Worker                  << (attrib.normalize ? "normalized, " : "") << "used as "
3027*35238bceSAndroid Build Coastguard Worker                  << DrawTestSpec::outputTypeToString(attrib.outputType) << ", "
3028*35238bceSAndroid Build Coastguard Worker                  << "instance divisor " << attrib.instanceDivisor << ", ";
3029*35238bceSAndroid Build Coastguard Worker         }
3030*35238bceSAndroid Build Coastguard Worker     }
3031*35238bceSAndroid Build Coastguard Worker 
3032*35238bceSAndroid Build Coastguard Worker     if (drawMethod == DRAWMETHOD_DRAWARRAYS)
3033*35238bceSAndroid Build Coastguard Worker     {
3034*35238bceSAndroid Build Coastguard Worker         desc << "drawArrays(), "
3035*35238bceSAndroid Build Coastguard Worker              << "first " << first << ", ";
3036*35238bceSAndroid Build Coastguard Worker     }
3037*35238bceSAndroid Build Coastguard Worker     else if (drawMethod == DRAWMETHOD_DRAWARRAYS_INSTANCED)
3038*35238bceSAndroid Build Coastguard Worker     {
3039*35238bceSAndroid Build Coastguard Worker         desc << "drawArraysInstanced(), "
3040*35238bceSAndroid Build Coastguard Worker              << "first " << first << ", "
3041*35238bceSAndroid Build Coastguard Worker              << "instance count " << instanceCount << ", ";
3042*35238bceSAndroid Build Coastguard Worker     }
3043*35238bceSAndroid Build Coastguard Worker     else if (drawMethod == DRAWMETHOD_DRAWELEMENTS)
3044*35238bceSAndroid Build Coastguard Worker     {
3045*35238bceSAndroid Build Coastguard Worker         desc << "drawElements(), "
3046*35238bceSAndroid Build Coastguard Worker              << "index type " << DrawTestSpec::indexTypeToString(indexType) << ", "
3047*35238bceSAndroid Build Coastguard Worker              << "index storage in " << DrawTestSpec::storageToString(indexStorage) << ", "
3048*35238bceSAndroid Build Coastguard Worker              << "index offset " << indexPointerOffset << ", ";
3049*35238bceSAndroid Build Coastguard Worker     }
3050*35238bceSAndroid Build Coastguard Worker     else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_RANGED)
3051*35238bceSAndroid Build Coastguard Worker     {
3052*35238bceSAndroid Build Coastguard Worker         desc << "drawElementsRanged(), "
3053*35238bceSAndroid Build Coastguard Worker              << "index type " << DrawTestSpec::indexTypeToString(indexType) << ", "
3054*35238bceSAndroid Build Coastguard Worker              << "index storage in " << DrawTestSpec::storageToString(indexStorage) << ", "
3055*35238bceSAndroid Build Coastguard Worker              << "index offset " << indexPointerOffset << ", "
3056*35238bceSAndroid Build Coastguard Worker              << "range start " << indexMin << ", "
3057*35238bceSAndroid Build Coastguard Worker              << "range end " << indexMax << ", ";
3058*35238bceSAndroid Build Coastguard Worker     }
3059*35238bceSAndroid Build Coastguard Worker     else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_INSTANCED)
3060*35238bceSAndroid Build Coastguard Worker     {
3061*35238bceSAndroid Build Coastguard Worker         desc << "drawElementsInstanced(), "
3062*35238bceSAndroid Build Coastguard Worker              << "index type " << DrawTestSpec::indexTypeToString(indexType) << ", "
3063*35238bceSAndroid Build Coastguard Worker              << "index storage in " << DrawTestSpec::storageToString(indexStorage) << ", "
3064*35238bceSAndroid Build Coastguard Worker              << "index offset " << indexPointerOffset << ", "
3065*35238bceSAndroid Build Coastguard Worker              << "instance count " << instanceCount << ", ";
3066*35238bceSAndroid Build Coastguard Worker     }
3067*35238bceSAndroid Build Coastguard Worker     else if (drawMethod == DRAWMETHOD_DRAWARRAYS_INDIRECT)
3068*35238bceSAndroid Build Coastguard Worker     {
3069*35238bceSAndroid Build Coastguard Worker         desc << "drawArraysIndirect(), "
3070*35238bceSAndroid Build Coastguard Worker              << "first " << first << ", "
3071*35238bceSAndroid Build Coastguard Worker              << "instance count " << instanceCount << ", "
3072*35238bceSAndroid Build Coastguard Worker              << "indirect offset " << indirectOffset << ", ";
3073*35238bceSAndroid Build Coastguard Worker     }
3074*35238bceSAndroid Build Coastguard Worker     else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_INDIRECT)
3075*35238bceSAndroid Build Coastguard Worker     {
3076*35238bceSAndroid Build Coastguard Worker         desc << "drawElementsIndirect(), "
3077*35238bceSAndroid Build Coastguard Worker              << "index type " << DrawTestSpec::indexTypeToString(indexType) << ", "
3078*35238bceSAndroid Build Coastguard Worker              << "index storage in " << DrawTestSpec::storageToString(indexStorage) << ", "
3079*35238bceSAndroid Build Coastguard Worker              << "index offset " << indexPointerOffset << ", "
3080*35238bceSAndroid Build Coastguard Worker              << "instance count " << instanceCount << ", "
3081*35238bceSAndroid Build Coastguard Worker              << "indirect offset " << indirectOffset << ", "
3082*35238bceSAndroid Build Coastguard Worker              << "base vertex " << baseVertex << ", ";
3083*35238bceSAndroid Build Coastguard Worker     }
3084*35238bceSAndroid Build Coastguard Worker     else
3085*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
3086*35238bceSAndroid Build Coastguard Worker 
3087*35238bceSAndroid Build Coastguard Worker     desc << primitiveCount;
3088*35238bceSAndroid Build Coastguard Worker 
3089*35238bceSAndroid Build Coastguard Worker     switch (primitive)
3090*35238bceSAndroid Build Coastguard Worker     {
3091*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_POINTS:
3092*35238bceSAndroid Build Coastguard Worker         desc << "points";
3093*35238bceSAndroid Build Coastguard Worker         break;
3094*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_TRIANGLES:
3095*35238bceSAndroid Build Coastguard Worker         desc << "triangles";
3096*35238bceSAndroid Build Coastguard Worker         break;
3097*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_TRIANGLE_FAN:
3098*35238bceSAndroid Build Coastguard Worker         desc << "triangles (fan)";
3099*35238bceSAndroid Build Coastguard Worker         break;
3100*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP:
3101*35238bceSAndroid Build Coastguard Worker         desc << "triangles (strip)";
3102*35238bceSAndroid Build Coastguard Worker         break;
3103*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_LINES:
3104*35238bceSAndroid Build Coastguard Worker         desc << "lines";
3105*35238bceSAndroid Build Coastguard Worker         break;
3106*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_LINE_STRIP:
3107*35238bceSAndroid Build Coastguard Worker         desc << "lines (strip)";
3108*35238bceSAndroid Build Coastguard Worker         break;
3109*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_LINE_LOOP:
3110*35238bceSAndroid Build Coastguard Worker         desc << "lines (loop)";
3111*35238bceSAndroid Build Coastguard Worker         break;
3112*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_LINES_ADJACENCY:
3113*35238bceSAndroid Build Coastguard Worker         desc << "lines (adjancency)";
3114*35238bceSAndroid Build Coastguard Worker         break;
3115*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_LINE_STRIP_ADJACENCY:
3116*35238bceSAndroid Build Coastguard Worker         desc << "lines (strip, adjancency)";
3117*35238bceSAndroid Build Coastguard Worker         break;
3118*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_TRIANGLES_ADJACENCY:
3119*35238bceSAndroid Build Coastguard Worker         desc << "triangles (adjancency)";
3120*35238bceSAndroid Build Coastguard Worker         break;
3121*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP_ADJACENCY:
3122*35238bceSAndroid Build Coastguard Worker         desc << "triangles (strip, adjancency)";
3123*35238bceSAndroid Build Coastguard Worker         break;
3124*35238bceSAndroid Build Coastguard Worker     default:
3125*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
3126*35238bceSAndroid Build Coastguard Worker         break;
3127*35238bceSAndroid Build Coastguard Worker     }
3128*35238bceSAndroid Build Coastguard Worker 
3129*35238bceSAndroid Build Coastguard Worker     return desc.str();
3130*35238bceSAndroid Build Coastguard Worker }
3131*35238bceSAndroid Build Coastguard Worker 
getMultilineDesc(void) const3132*35238bceSAndroid Build Coastguard Worker std::string DrawTestSpec::getMultilineDesc(void) const
3133*35238bceSAndroid Build Coastguard Worker {
3134*35238bceSAndroid Build Coastguard Worker     std::stringstream desc;
3135*35238bceSAndroid Build Coastguard Worker 
3136*35238bceSAndroid Build Coastguard Worker     for (size_t ndx = 0; ndx < attribs.size(); ++ndx)
3137*35238bceSAndroid Build Coastguard Worker     {
3138*35238bceSAndroid Build Coastguard Worker         const AttributeSpec &attrib = attribs[ndx];
3139*35238bceSAndroid Build Coastguard Worker 
3140*35238bceSAndroid Build Coastguard Worker         if (attrib.useDefaultAttribute)
3141*35238bceSAndroid Build Coastguard Worker         {
3142*35238bceSAndroid Build Coastguard Worker             desc << "Attribute " << ndx << ": default, "
3143*35238bceSAndroid Build Coastguard Worker                  << ((ndx == 0 || attrib.additionalPositionAttribute) ? ("position\n") : ("color\n"))
3144*35238bceSAndroid Build Coastguard Worker                  << "\tinput datatype " << DrawTestSpec::inputTypeToString((DrawTestSpec::InputType)attrib.inputType)
3145*35238bceSAndroid Build Coastguard Worker                  << "\n"
3146*35238bceSAndroid Build Coastguard Worker                  << "\tinput component count " << attrib.componentCount << "\n"
3147*35238bceSAndroid Build Coastguard Worker                  << "\tused as " << DrawTestSpec::outputTypeToString(attrib.outputType) << "\n";
3148*35238bceSAndroid Build Coastguard Worker         }
3149*35238bceSAndroid Build Coastguard Worker         else
3150*35238bceSAndroid Build Coastguard Worker         {
3151*35238bceSAndroid Build Coastguard Worker             desc << "Attribute " << ndx << ": "
3152*35238bceSAndroid Build Coastguard Worker                  << ((ndx == 0 || attrib.additionalPositionAttribute) ? ("position\n") : ("color\n")) << "\tStorage in "
3153*35238bceSAndroid Build Coastguard Worker                  << DrawTestSpec::storageToString(attrib.storage) << "\n"
3154*35238bceSAndroid Build Coastguard Worker                  << "\tstride " << attrib.stride << "\n"
3155*35238bceSAndroid Build Coastguard Worker                  << "\tinput datatype " << DrawTestSpec::inputTypeToString((DrawTestSpec::InputType)attrib.inputType)
3156*35238bceSAndroid Build Coastguard Worker                  << "\n"
3157*35238bceSAndroid Build Coastguard Worker                  << "\tinput component count " << attrib.componentCount << "\n"
3158*35238bceSAndroid Build Coastguard Worker                  << (attrib.normalize ? "\tnormalized\n" : "") << "\tused as "
3159*35238bceSAndroid Build Coastguard Worker                  << DrawTestSpec::outputTypeToString(attrib.outputType) << "\n"
3160*35238bceSAndroid Build Coastguard Worker                  << "\tinstance divisor " << attrib.instanceDivisor << "\n";
3161*35238bceSAndroid Build Coastguard Worker         }
3162*35238bceSAndroid Build Coastguard Worker     }
3163*35238bceSAndroid Build Coastguard Worker 
3164*35238bceSAndroid Build Coastguard Worker     if (drawMethod == DRAWMETHOD_DRAWARRAYS)
3165*35238bceSAndroid Build Coastguard Worker     {
3166*35238bceSAndroid Build Coastguard Worker         desc << "drawArrays()\n"
3167*35238bceSAndroid Build Coastguard Worker              << "\tfirst " << first << "\n";
3168*35238bceSAndroid Build Coastguard Worker     }
3169*35238bceSAndroid Build Coastguard Worker     else if (drawMethod == DRAWMETHOD_DRAWARRAYS_INSTANCED)
3170*35238bceSAndroid Build Coastguard Worker     {
3171*35238bceSAndroid Build Coastguard Worker         desc << "drawArraysInstanced()\n"
3172*35238bceSAndroid Build Coastguard Worker              << "\tfirst " << first << "\n"
3173*35238bceSAndroid Build Coastguard Worker              << "\tinstance count " << instanceCount << "\n";
3174*35238bceSAndroid Build Coastguard Worker     }
3175*35238bceSAndroid Build Coastguard Worker     else if (drawMethod == DRAWMETHOD_DRAWELEMENTS)
3176*35238bceSAndroid Build Coastguard Worker     {
3177*35238bceSAndroid Build Coastguard Worker         desc << "drawElements()\n"
3178*35238bceSAndroid Build Coastguard Worker              << "\tindex type " << DrawTestSpec::indexTypeToString(indexType) << "\n"
3179*35238bceSAndroid Build Coastguard Worker              << "\tindex storage in " << DrawTestSpec::storageToString(indexStorage) << "\n"
3180*35238bceSAndroid Build Coastguard Worker              << "\tindex offset " << indexPointerOffset << "\n";
3181*35238bceSAndroid Build Coastguard Worker     }
3182*35238bceSAndroid Build Coastguard Worker     else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_RANGED)
3183*35238bceSAndroid Build Coastguard Worker     {
3184*35238bceSAndroid Build Coastguard Worker         desc << "drawElementsRanged()\n"
3185*35238bceSAndroid Build Coastguard Worker              << "\tindex type " << DrawTestSpec::indexTypeToString(indexType) << "\n"
3186*35238bceSAndroid Build Coastguard Worker              << "\tindex storage in " << DrawTestSpec::storageToString(indexStorage) << "\n"
3187*35238bceSAndroid Build Coastguard Worker              << "\tindex offset " << indexPointerOffset << "\n"
3188*35238bceSAndroid Build Coastguard Worker              << "\trange start " << indexMin << "\n"
3189*35238bceSAndroid Build Coastguard Worker              << "\trange end " << indexMax << "\n";
3190*35238bceSAndroid Build Coastguard Worker     }
3191*35238bceSAndroid Build Coastguard Worker     else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_INSTANCED)
3192*35238bceSAndroid Build Coastguard Worker     {
3193*35238bceSAndroid Build Coastguard Worker         desc << "drawElementsInstanced()\n"
3194*35238bceSAndroid Build Coastguard Worker              << "\tindex type " << DrawTestSpec::indexTypeToString(indexType) << "\n"
3195*35238bceSAndroid Build Coastguard Worker              << "\tindex storage in " << DrawTestSpec::storageToString(indexStorage) << "\n"
3196*35238bceSAndroid Build Coastguard Worker              << "\tindex offset " << indexPointerOffset << "\n"
3197*35238bceSAndroid Build Coastguard Worker              << "\tinstance count " << instanceCount << "\n";
3198*35238bceSAndroid Build Coastguard Worker     }
3199*35238bceSAndroid Build Coastguard Worker     else if (drawMethod == DRAWMETHOD_DRAWARRAYS_INDIRECT)
3200*35238bceSAndroid Build Coastguard Worker     {
3201*35238bceSAndroid Build Coastguard Worker         desc << "drawArraysIndirect()\n"
3202*35238bceSAndroid Build Coastguard Worker              << "\tfirst " << first << "\n"
3203*35238bceSAndroid Build Coastguard Worker              << "\tinstance count " << instanceCount << "\n"
3204*35238bceSAndroid Build Coastguard Worker              << "\tindirect offset " << indirectOffset << "\n";
3205*35238bceSAndroid Build Coastguard Worker     }
3206*35238bceSAndroid Build Coastguard Worker     else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_INDIRECT)
3207*35238bceSAndroid Build Coastguard Worker     {
3208*35238bceSAndroid Build Coastguard Worker         desc << "drawElementsIndirect()\n"
3209*35238bceSAndroid Build Coastguard Worker              << "\tindex type " << DrawTestSpec::indexTypeToString(indexType) << "\n"
3210*35238bceSAndroid Build Coastguard Worker              << "\tindex storage in " << DrawTestSpec::storageToString(indexStorage) << "\n"
3211*35238bceSAndroid Build Coastguard Worker              << "\tindex offset " << indexPointerOffset << "\n"
3212*35238bceSAndroid Build Coastguard Worker              << "\tinstance count " << instanceCount << "\n"
3213*35238bceSAndroid Build Coastguard Worker              << "\tindirect offset " << indirectOffset << "\n"
3214*35238bceSAndroid Build Coastguard Worker              << "\tbase vertex " << baseVertex << "\n";
3215*35238bceSAndroid Build Coastguard Worker     }
3216*35238bceSAndroid Build Coastguard Worker     else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_BASEVERTEX)
3217*35238bceSAndroid Build Coastguard Worker     {
3218*35238bceSAndroid Build Coastguard Worker         desc << "drawElementsBaseVertex()\n"
3219*35238bceSAndroid Build Coastguard Worker              << "\tindex type " << DrawTestSpec::indexTypeToString(indexType) << "\n"
3220*35238bceSAndroid Build Coastguard Worker              << "\tindex storage in " << DrawTestSpec::storageToString(indexStorage) << "\n"
3221*35238bceSAndroid Build Coastguard Worker              << "\tindex offset " << indexPointerOffset << "\n"
3222*35238bceSAndroid Build Coastguard Worker              << "\tbase vertex " << baseVertex << "\n";
3223*35238bceSAndroid Build Coastguard Worker     }
3224*35238bceSAndroid Build Coastguard Worker     else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX)
3225*35238bceSAndroid Build Coastguard Worker     {
3226*35238bceSAndroid Build Coastguard Worker         desc << "drawElementsInstancedBaseVertex()\n"
3227*35238bceSAndroid Build Coastguard Worker              << "\tindex type " << DrawTestSpec::indexTypeToString(indexType) << "\n"
3228*35238bceSAndroid Build Coastguard Worker              << "\tindex storage in " << DrawTestSpec::storageToString(indexStorage) << "\n"
3229*35238bceSAndroid Build Coastguard Worker              << "\tindex offset " << indexPointerOffset << "\n"
3230*35238bceSAndroid Build Coastguard Worker              << "\tinstance count " << instanceCount << "\n"
3231*35238bceSAndroid Build Coastguard Worker              << "\tbase vertex " << baseVertex << "\n";
3232*35238bceSAndroid Build Coastguard Worker     }
3233*35238bceSAndroid Build Coastguard Worker     else if (drawMethod == DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX)
3234*35238bceSAndroid Build Coastguard Worker     {
3235*35238bceSAndroid Build Coastguard Worker         desc << "drawRangeElementsBaseVertex()\n"
3236*35238bceSAndroid Build Coastguard Worker              << "\tindex type " << DrawTestSpec::indexTypeToString(indexType) << "\n"
3237*35238bceSAndroid Build Coastguard Worker              << "\tindex storage in " << DrawTestSpec::storageToString(indexStorage) << "\n"
3238*35238bceSAndroid Build Coastguard Worker              << "\tindex offset " << indexPointerOffset << "\n"
3239*35238bceSAndroid Build Coastguard Worker              << "\tbase vertex " << baseVertex << "\n"
3240*35238bceSAndroid Build Coastguard Worker              << "\trange start " << indexMin << "\n"
3241*35238bceSAndroid Build Coastguard Worker              << "\trange end " << indexMax << "\n";
3242*35238bceSAndroid Build Coastguard Worker     }
3243*35238bceSAndroid Build Coastguard Worker     else
3244*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
3245*35238bceSAndroid Build Coastguard Worker 
3246*35238bceSAndroid Build Coastguard Worker     desc << "\t" << primitiveCount << " ";
3247*35238bceSAndroid Build Coastguard Worker 
3248*35238bceSAndroid Build Coastguard Worker     switch (primitive)
3249*35238bceSAndroid Build Coastguard Worker     {
3250*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_POINTS:
3251*35238bceSAndroid Build Coastguard Worker         desc << "points";
3252*35238bceSAndroid Build Coastguard Worker         break;
3253*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_TRIANGLES:
3254*35238bceSAndroid Build Coastguard Worker         desc << "triangles";
3255*35238bceSAndroid Build Coastguard Worker         break;
3256*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_TRIANGLE_FAN:
3257*35238bceSAndroid Build Coastguard Worker         desc << "triangles (fan)";
3258*35238bceSAndroid Build Coastguard Worker         break;
3259*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP:
3260*35238bceSAndroid Build Coastguard Worker         desc << "triangles (strip)";
3261*35238bceSAndroid Build Coastguard Worker         break;
3262*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_LINES:
3263*35238bceSAndroid Build Coastguard Worker         desc << "lines";
3264*35238bceSAndroid Build Coastguard Worker         break;
3265*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_LINE_STRIP:
3266*35238bceSAndroid Build Coastguard Worker         desc << "lines (strip)";
3267*35238bceSAndroid Build Coastguard Worker         break;
3268*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_LINE_LOOP:
3269*35238bceSAndroid Build Coastguard Worker         desc << "lines (loop)";
3270*35238bceSAndroid Build Coastguard Worker         break;
3271*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_LINES_ADJACENCY:
3272*35238bceSAndroid Build Coastguard Worker         desc << "lines (adjancency)";
3273*35238bceSAndroid Build Coastguard Worker         break;
3274*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_LINE_STRIP_ADJACENCY:
3275*35238bceSAndroid Build Coastguard Worker         desc << "lines (strip, adjancency)";
3276*35238bceSAndroid Build Coastguard Worker         break;
3277*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_TRIANGLES_ADJACENCY:
3278*35238bceSAndroid Build Coastguard Worker         desc << "triangles (adjancency)";
3279*35238bceSAndroid Build Coastguard Worker         break;
3280*35238bceSAndroid Build Coastguard Worker     case DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP_ADJACENCY:
3281*35238bceSAndroid Build Coastguard Worker         desc << "triangles (strip, adjancency)";
3282*35238bceSAndroid Build Coastguard Worker         break;
3283*35238bceSAndroid Build Coastguard Worker     default:
3284*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
3285*35238bceSAndroid Build Coastguard Worker         break;
3286*35238bceSAndroid Build Coastguard Worker     }
3287*35238bceSAndroid Build Coastguard Worker 
3288*35238bceSAndroid Build Coastguard Worker     desc << "\n";
3289*35238bceSAndroid Build Coastguard Worker 
3290*35238bceSAndroid Build Coastguard Worker     return desc.str();
3291*35238bceSAndroid Build Coastguard Worker }
3292*35238bceSAndroid Build Coastguard Worker 
DrawTestSpec(void)3293*35238bceSAndroid Build Coastguard Worker DrawTestSpec::DrawTestSpec(void)
3294*35238bceSAndroid Build Coastguard Worker {
3295*35238bceSAndroid Build Coastguard Worker     primitive          = PRIMITIVE_LAST;
3296*35238bceSAndroid Build Coastguard Worker     primitiveCount     = 0;
3297*35238bceSAndroid Build Coastguard Worker     drawMethod         = DRAWMETHOD_LAST;
3298*35238bceSAndroid Build Coastguard Worker     indexType          = INDEXTYPE_LAST;
3299*35238bceSAndroid Build Coastguard Worker     indexPointerOffset = 0;
3300*35238bceSAndroid Build Coastguard Worker     indexStorage       = STORAGE_LAST;
3301*35238bceSAndroid Build Coastguard Worker     first              = 0;
3302*35238bceSAndroid Build Coastguard Worker     indexMin           = 0;
3303*35238bceSAndroid Build Coastguard Worker     indexMax           = 0;
3304*35238bceSAndroid Build Coastguard Worker     instanceCount      = 0;
3305*35238bceSAndroid Build Coastguard Worker     indirectOffset     = 0;
3306*35238bceSAndroid Build Coastguard Worker     baseVertex         = 0;
3307*35238bceSAndroid Build Coastguard Worker }
3308*35238bceSAndroid Build Coastguard Worker 
hash(void) const3309*35238bceSAndroid Build Coastguard Worker int DrawTestSpec::hash(void) const
3310*35238bceSAndroid Build Coastguard Worker {
3311*35238bceSAndroid Build Coastguard Worker     // Use only drawmode-relevant values in "hashing" as the unrelevant values might not be set (causing non-deterministic behavior).
3312*35238bceSAndroid Build Coastguard Worker     const MethodInfo methodInfo = getMethodInfo(drawMethod);
3313*35238bceSAndroid Build Coastguard Worker     const bool arrayed          = methodInfo.first;
3314*35238bceSAndroid Build Coastguard Worker     const bool instanced        = methodInfo.instanced;
3315*35238bceSAndroid Build Coastguard Worker     const bool ranged           = methodInfo.ranged;
3316*35238bceSAndroid Build Coastguard Worker     const bool indexed          = methodInfo.indexed;
3317*35238bceSAndroid Build Coastguard Worker     const bool indirect         = methodInfo.indirect;
3318*35238bceSAndroid Build Coastguard Worker     const bool hasBaseVtx       = methodInfo.baseVertex;
3319*35238bceSAndroid Build Coastguard Worker 
3320*35238bceSAndroid Build Coastguard Worker     const int indexHash      = (!indexed) ? (0) : (int(indexType) + 10 * indexPointerOffset + 100 * int(indexStorage));
3321*35238bceSAndroid Build Coastguard Worker     const int arrayHash      = (!arrayed) ? (0) : (first);
3322*35238bceSAndroid Build Coastguard Worker     const int indexRangeHash = (!ranged) ? (0) : (indexMin + 10 * indexMax);
3323*35238bceSAndroid Build Coastguard Worker     const int instanceHash   = (!instanced) ? (0) : (instanceCount);
3324*35238bceSAndroid Build Coastguard Worker     const int indirectHash   = (!indirect) ? (0) : (indirectOffset);
3325*35238bceSAndroid Build Coastguard Worker     const int baseVtxHash    = (!hasBaseVtx) ? (0) : (baseVertex);
3326*35238bceSAndroid Build Coastguard Worker     const int basicHash      = int(primitive) + 10 * primitiveCount + 100 * int(drawMethod);
3327*35238bceSAndroid Build Coastguard Worker 
3328*35238bceSAndroid Build Coastguard Worker     return indexHash + 3 * arrayHash + 5 * indexRangeHash + 7 * instanceHash + 13 * basicHash +
3329*35238bceSAndroid Build Coastguard Worker            17 * (int)attribs.size() + 19 * primitiveCount + 23 * indirectHash + 27 * baseVtxHash;
3330*35238bceSAndroid Build Coastguard Worker }
3331*35238bceSAndroid Build Coastguard Worker 
valid(void) const3332*35238bceSAndroid Build Coastguard Worker bool DrawTestSpec::valid(void) const
3333*35238bceSAndroid Build Coastguard Worker {
3334*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(apiType.getProfile() != glu::PROFILE_LAST);
3335*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(primitive != PRIMITIVE_LAST);
3336*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(drawMethod != DRAWMETHOD_LAST);
3337*35238bceSAndroid Build Coastguard Worker 
3338*35238bceSAndroid Build Coastguard Worker     const MethodInfo methodInfo = getMethodInfo(drawMethod);
3339*35238bceSAndroid Build Coastguard Worker 
3340*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < (int)attribs.size(); ++ndx)
3341*35238bceSAndroid Build Coastguard Worker         if (!attribs[ndx].valid(apiType))
3342*35238bceSAndroid Build Coastguard Worker             return false;
3343*35238bceSAndroid Build Coastguard Worker 
3344*35238bceSAndroid Build Coastguard Worker     if (methodInfo.ranged)
3345*35238bceSAndroid Build Coastguard Worker     {
3346*35238bceSAndroid Build Coastguard Worker         uint32_t maxIndexValue = 0;
3347*35238bceSAndroid Build Coastguard Worker         if (indexType == INDEXTYPE_BYTE)
3348*35238bceSAndroid Build Coastguard Worker             maxIndexValue = GLValue::getMaxValue(INPUTTYPE_UNSIGNED_BYTE).ub.getValue();
3349*35238bceSAndroid Build Coastguard Worker         else if (indexType == INDEXTYPE_SHORT)
3350*35238bceSAndroid Build Coastguard Worker             maxIndexValue = GLValue::getMaxValue(INPUTTYPE_UNSIGNED_SHORT).us.getValue();
3351*35238bceSAndroid Build Coastguard Worker         else if (indexType == INDEXTYPE_INT)
3352*35238bceSAndroid Build Coastguard Worker             maxIndexValue = GLValue::getMaxValue(INPUTTYPE_UNSIGNED_INT).ui.getValue();
3353*35238bceSAndroid Build Coastguard Worker         else
3354*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
3355*35238bceSAndroid Build Coastguard Worker 
3356*35238bceSAndroid Build Coastguard Worker         if (indexMin > indexMax)
3357*35238bceSAndroid Build Coastguard Worker             return false;
3358*35238bceSAndroid Build Coastguard Worker         if (indexMin < 0 || indexMax < 0)
3359*35238bceSAndroid Build Coastguard Worker             return false;
3360*35238bceSAndroid Build Coastguard Worker         if ((uint32_t)indexMin > maxIndexValue || (uint32_t)indexMax > maxIndexValue)
3361*35238bceSAndroid Build Coastguard Worker             return false;
3362*35238bceSAndroid Build Coastguard Worker     }
3363*35238bceSAndroid Build Coastguard Worker 
3364*35238bceSAndroid Build Coastguard Worker     if (methodInfo.first && first < 0)
3365*35238bceSAndroid Build Coastguard Worker         return false;
3366*35238bceSAndroid Build Coastguard Worker 
3367*35238bceSAndroid Build Coastguard Worker     // GLES2 limits
3368*35238bceSAndroid Build Coastguard Worker     if (apiType == glu::ApiType::es(2, 0))
3369*35238bceSAndroid Build Coastguard Worker     {
3370*35238bceSAndroid Build Coastguard Worker         if (drawMethod != gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS &&
3371*35238bceSAndroid Build Coastguard Worker             drawMethod != gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS)
3372*35238bceSAndroid Build Coastguard Worker             return false;
3373*35238bceSAndroid Build Coastguard Worker         if (drawMethod == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS &&
3374*35238bceSAndroid Build Coastguard Worker             (indexType != INDEXTYPE_BYTE && indexType != INDEXTYPE_SHORT))
3375*35238bceSAndroid Build Coastguard Worker             return false;
3376*35238bceSAndroid Build Coastguard Worker     }
3377*35238bceSAndroid Build Coastguard Worker 
3378*35238bceSAndroid Build Coastguard Worker     // Indirect limitations
3379*35238bceSAndroid Build Coastguard Worker     if (methodInfo.indirect)
3380*35238bceSAndroid Build Coastguard Worker     {
3381*35238bceSAndroid Build Coastguard Worker         // Indirect offset alignment
3382*35238bceSAndroid Build Coastguard Worker         if (indirectOffset % 4 != 0)
3383*35238bceSAndroid Build Coastguard Worker             return false;
3384*35238bceSAndroid Build Coastguard Worker 
3385*35238bceSAndroid Build Coastguard Worker         // All attribute arrays must be stored in a buffer
3386*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < (int)attribs.size(); ++ndx)
3387*35238bceSAndroid Build Coastguard Worker             if (!attribs[ndx].useDefaultAttribute && attribs[ndx].storage == gls::DrawTestSpec::STORAGE_USER)
3388*35238bceSAndroid Build Coastguard Worker                 return false;
3389*35238bceSAndroid Build Coastguard Worker     }
3390*35238bceSAndroid Build Coastguard Worker     if (drawMethod == DRAWMETHOD_DRAWELEMENTS_INDIRECT)
3391*35238bceSAndroid Build Coastguard Worker     {
3392*35238bceSAndroid Build Coastguard Worker         // index offset must be convertable to firstIndex
3393*35238bceSAndroid Build Coastguard Worker         if (indexPointerOffset % gls::DrawTestSpec::indexTypeSize(indexType) != 0)
3394*35238bceSAndroid Build Coastguard Worker             return false;
3395*35238bceSAndroid Build Coastguard Worker 
3396*35238bceSAndroid Build Coastguard Worker         // Indices must be in a buffer
3397*35238bceSAndroid Build Coastguard Worker         if (indexStorage != STORAGE_BUFFER)
3398*35238bceSAndroid Build Coastguard Worker             return false;
3399*35238bceSAndroid Build Coastguard Worker     }
3400*35238bceSAndroid Build Coastguard Worker 
3401*35238bceSAndroid Build Coastguard Worker     // Do not allow user pointer in GL core
3402*35238bceSAndroid Build Coastguard Worker     if (apiType.getProfile() == glu::PROFILE_CORE)
3403*35238bceSAndroid Build Coastguard Worker     {
3404*35238bceSAndroid Build Coastguard Worker         if (methodInfo.indexed && indexStorage == DrawTestSpec::STORAGE_USER)
3405*35238bceSAndroid Build Coastguard Worker             return false;
3406*35238bceSAndroid Build Coastguard Worker     }
3407*35238bceSAndroid Build Coastguard Worker 
3408*35238bceSAndroid Build Coastguard Worker     return true;
3409*35238bceSAndroid Build Coastguard Worker }
3410*35238bceSAndroid Build Coastguard Worker 
isCompatibilityTest(void) const3411*35238bceSAndroid Build Coastguard Worker DrawTestSpec::CompatibilityTestType DrawTestSpec::isCompatibilityTest(void) const
3412*35238bceSAndroid Build Coastguard Worker {
3413*35238bceSAndroid Build Coastguard Worker     const MethodInfo methodInfo = getMethodInfo(drawMethod);
3414*35238bceSAndroid Build Coastguard Worker 
3415*35238bceSAndroid Build Coastguard Worker     bool bufferAlignmentBad = false;
3416*35238bceSAndroid Build Coastguard Worker     bool strideAlignmentBad = false;
3417*35238bceSAndroid Build Coastguard Worker 
3418*35238bceSAndroid Build Coastguard Worker     // Attribute buffer alignment
3419*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < (int)attribs.size(); ++ndx)
3420*35238bceSAndroid Build Coastguard Worker         if (!attribs[ndx].isBufferAligned())
3421*35238bceSAndroid Build Coastguard Worker             bufferAlignmentBad = true;
3422*35238bceSAndroid Build Coastguard Worker 
3423*35238bceSAndroid Build Coastguard Worker     // Attribute stride alignment
3424*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < (int)attribs.size(); ++ndx)
3425*35238bceSAndroid Build Coastguard Worker         if (!attribs[ndx].isBufferStrideAligned())
3426*35238bceSAndroid Build Coastguard Worker             strideAlignmentBad = true;
3427*35238bceSAndroid Build Coastguard Worker 
3428*35238bceSAndroid Build Coastguard Worker     // Index buffer alignment
3429*35238bceSAndroid Build Coastguard Worker     if (methodInfo.indexed)
3430*35238bceSAndroid Build Coastguard Worker     {
3431*35238bceSAndroid Build Coastguard Worker         if (indexStorage == STORAGE_BUFFER)
3432*35238bceSAndroid Build Coastguard Worker         {
3433*35238bceSAndroid Build Coastguard Worker             int indexSize = 0;
3434*35238bceSAndroid Build Coastguard Worker             if (indexType == INDEXTYPE_BYTE)
3435*35238bceSAndroid Build Coastguard Worker                 indexSize = 1;
3436*35238bceSAndroid Build Coastguard Worker             else if (indexType == INDEXTYPE_SHORT)
3437*35238bceSAndroid Build Coastguard Worker                 indexSize = 2;
3438*35238bceSAndroid Build Coastguard Worker             else if (indexType == INDEXTYPE_INT)
3439*35238bceSAndroid Build Coastguard Worker                 indexSize = 4;
3440*35238bceSAndroid Build Coastguard Worker             else
3441*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(false);
3442*35238bceSAndroid Build Coastguard Worker 
3443*35238bceSAndroid Build Coastguard Worker             if (indexPointerOffset % indexSize != 0)
3444*35238bceSAndroid Build Coastguard Worker                 bufferAlignmentBad = true;
3445*35238bceSAndroid Build Coastguard Worker         }
3446*35238bceSAndroid Build Coastguard Worker     }
3447*35238bceSAndroid Build Coastguard Worker 
3448*35238bceSAndroid Build Coastguard Worker     // \note combination bad alignment & stride is treated as bad offset
3449*35238bceSAndroid Build Coastguard Worker     if (bufferAlignmentBad)
3450*35238bceSAndroid Build Coastguard Worker         return COMPATIBILITY_UNALIGNED_OFFSET;
3451*35238bceSAndroid Build Coastguard Worker     else if (strideAlignmentBad)
3452*35238bceSAndroid Build Coastguard Worker         return COMPATIBILITY_UNALIGNED_STRIDE;
3453*35238bceSAndroid Build Coastguard Worker     else
3454*35238bceSAndroid Build Coastguard Worker         return COMPATIBILITY_NONE;
3455*35238bceSAndroid Build Coastguard Worker }
3456*35238bceSAndroid Build Coastguard Worker 
3457*35238bceSAndroid Build Coastguard Worker enum PrimitiveClass
3458*35238bceSAndroid Build Coastguard Worker {
3459*35238bceSAndroid Build Coastguard Worker     PRIMITIVECLASS_POINT = 0,
3460*35238bceSAndroid Build Coastguard Worker     PRIMITIVECLASS_LINE,
3461*35238bceSAndroid Build Coastguard Worker     PRIMITIVECLASS_TRIANGLE,
3462*35238bceSAndroid Build Coastguard Worker 
3463*35238bceSAndroid Build Coastguard Worker     PRIMITIVECLASS_LAST
3464*35238bceSAndroid Build Coastguard Worker };
3465*35238bceSAndroid Build Coastguard Worker 
getDrawPrimitiveClass(gls::DrawTestSpec::Primitive primitiveType)3466*35238bceSAndroid Build Coastguard Worker static PrimitiveClass getDrawPrimitiveClass(gls::DrawTestSpec::Primitive primitiveType)
3467*35238bceSAndroid Build Coastguard Worker {
3468*35238bceSAndroid Build Coastguard Worker     switch (primitiveType)
3469*35238bceSAndroid Build Coastguard Worker     {
3470*35238bceSAndroid Build Coastguard Worker     case gls::DrawTestSpec::PRIMITIVE_POINTS:
3471*35238bceSAndroid Build Coastguard Worker         return PRIMITIVECLASS_POINT;
3472*35238bceSAndroid Build Coastguard Worker 
3473*35238bceSAndroid Build Coastguard Worker     case gls::DrawTestSpec::PRIMITIVE_LINES:
3474*35238bceSAndroid Build Coastguard Worker     case gls::DrawTestSpec::PRIMITIVE_LINE_STRIP:
3475*35238bceSAndroid Build Coastguard Worker     case gls::DrawTestSpec::PRIMITIVE_LINE_LOOP:
3476*35238bceSAndroid Build Coastguard Worker     case gls::DrawTestSpec::PRIMITIVE_LINES_ADJACENCY:
3477*35238bceSAndroid Build Coastguard Worker     case gls::DrawTestSpec::PRIMITIVE_LINE_STRIP_ADJACENCY:
3478*35238bceSAndroid Build Coastguard Worker         return PRIMITIVECLASS_LINE;
3479*35238bceSAndroid Build Coastguard Worker 
3480*35238bceSAndroid Build Coastguard Worker     case gls::DrawTestSpec::PRIMITIVE_TRIANGLES:
3481*35238bceSAndroid Build Coastguard Worker     case gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN:
3482*35238bceSAndroid Build Coastguard Worker     case gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP:
3483*35238bceSAndroid Build Coastguard Worker     case gls::DrawTestSpec::PRIMITIVE_TRIANGLES_ADJACENCY:
3484*35238bceSAndroid Build Coastguard Worker     case gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP_ADJACENCY:
3485*35238bceSAndroid Build Coastguard Worker         return PRIMITIVECLASS_TRIANGLE;
3486*35238bceSAndroid Build Coastguard Worker 
3487*35238bceSAndroid Build Coastguard Worker     default:
3488*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
3489*35238bceSAndroid Build Coastguard Worker         return PRIMITIVECLASS_LAST;
3490*35238bceSAndroid Build Coastguard Worker     }
3491*35238bceSAndroid Build Coastguard Worker }
3492*35238bceSAndroid Build Coastguard Worker 
containsLineCases(const std::vector<DrawTestSpec> & m_specs)3493*35238bceSAndroid Build Coastguard Worker static bool containsLineCases(const std::vector<DrawTestSpec> &m_specs)
3494*35238bceSAndroid Build Coastguard Worker {
3495*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < (int)m_specs.size(); ++ndx)
3496*35238bceSAndroid Build Coastguard Worker     {
3497*35238bceSAndroid Build Coastguard Worker         if (getDrawPrimitiveClass(m_specs[ndx].primitive) == PRIMITIVECLASS_LINE)
3498*35238bceSAndroid Build Coastguard Worker             return true;
3499*35238bceSAndroid Build Coastguard Worker     }
3500*35238bceSAndroid Build Coastguard Worker     return false;
3501*35238bceSAndroid Build Coastguard Worker }
3502*35238bceSAndroid Build Coastguard Worker 
3503*35238bceSAndroid Build Coastguard Worker // DrawTest
3504*35238bceSAndroid Build Coastguard Worker 
DrawTest(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const DrawTestSpec & spec,const char * name,const char * desc)3505*35238bceSAndroid Build Coastguard Worker DrawTest::DrawTest(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const DrawTestSpec &spec, const char *name,
3506*35238bceSAndroid Build Coastguard Worker                    const char *desc)
3507*35238bceSAndroid Build Coastguard Worker     : TestCase(testCtx, name, desc)
3508*35238bceSAndroid Build Coastguard Worker     , m_renderCtx(renderCtx)
3509*35238bceSAndroid Build Coastguard Worker     , m_contextInfo(DE_NULL)
3510*35238bceSAndroid Build Coastguard Worker     , m_refBuffers(DE_NULL)
3511*35238bceSAndroid Build Coastguard Worker     , m_refContext(DE_NULL)
3512*35238bceSAndroid Build Coastguard Worker     , m_glesContext(DE_NULL)
3513*35238bceSAndroid Build Coastguard Worker     , m_glArrayPack(DE_NULL)
3514*35238bceSAndroid Build Coastguard Worker     , m_rrArrayPack(DE_NULL)
3515*35238bceSAndroid Build Coastguard Worker     , m_maxDiffRed(-1)
3516*35238bceSAndroid Build Coastguard Worker     , m_maxDiffGreen(-1)
3517*35238bceSAndroid Build Coastguard Worker     , m_maxDiffBlue(-1)
3518*35238bceSAndroid Build Coastguard Worker     , m_iteration(0)
3519*35238bceSAndroid Build Coastguard Worker     , m_result() // \note no per-iteration result logging (only one iteration)
3520*35238bceSAndroid Build Coastguard Worker {
3521*35238bceSAndroid Build Coastguard Worker     addIteration(spec);
3522*35238bceSAndroid Build Coastguard Worker }
3523*35238bceSAndroid Build Coastguard Worker 
DrawTest(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * desc)3524*35238bceSAndroid Build Coastguard Worker DrawTest::DrawTest(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const char *name, const char *desc)
3525*35238bceSAndroid Build Coastguard Worker     : TestCase(testCtx, name, desc)
3526*35238bceSAndroid Build Coastguard Worker     , m_renderCtx(renderCtx)
3527*35238bceSAndroid Build Coastguard Worker     , m_contextInfo(DE_NULL)
3528*35238bceSAndroid Build Coastguard Worker     , m_refBuffers(DE_NULL)
3529*35238bceSAndroid Build Coastguard Worker     , m_refContext(DE_NULL)
3530*35238bceSAndroid Build Coastguard Worker     , m_glesContext(DE_NULL)
3531*35238bceSAndroid Build Coastguard Worker     , m_glArrayPack(DE_NULL)
3532*35238bceSAndroid Build Coastguard Worker     , m_rrArrayPack(DE_NULL)
3533*35238bceSAndroid Build Coastguard Worker     , m_maxDiffRed(-1)
3534*35238bceSAndroid Build Coastguard Worker     , m_maxDiffGreen(-1)
3535*35238bceSAndroid Build Coastguard Worker     , m_maxDiffBlue(-1)
3536*35238bceSAndroid Build Coastguard Worker     , m_iteration(0)
3537*35238bceSAndroid Build Coastguard Worker     , m_result(testCtx.getLog(), "Iteration result: ")
3538*35238bceSAndroid Build Coastguard Worker {
3539*35238bceSAndroid Build Coastguard Worker }
3540*35238bceSAndroid Build Coastguard Worker 
~DrawTest(void)3541*35238bceSAndroid Build Coastguard Worker DrawTest::~DrawTest(void)
3542*35238bceSAndroid Build Coastguard Worker {
3543*35238bceSAndroid Build Coastguard Worker     deinit();
3544*35238bceSAndroid Build Coastguard Worker }
3545*35238bceSAndroid Build Coastguard Worker 
addIteration(const DrawTestSpec & spec,const char * description)3546*35238bceSAndroid Build Coastguard Worker void DrawTest::addIteration(const DrawTestSpec &spec, const char *description)
3547*35238bceSAndroid Build Coastguard Worker {
3548*35238bceSAndroid Build Coastguard Worker     // Validate spec
3549*35238bceSAndroid Build Coastguard Worker     const bool validSpec = spec.valid();
3550*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(validSpec);
3551*35238bceSAndroid Build Coastguard Worker 
3552*35238bceSAndroid Build Coastguard Worker     if (!validSpec)
3553*35238bceSAndroid Build Coastguard Worker         return;
3554*35238bceSAndroid Build Coastguard Worker 
3555*35238bceSAndroid Build Coastguard Worker     // Check the context type is the same with other iterations
3556*35238bceSAndroid Build Coastguard Worker     if (!m_specs.empty())
3557*35238bceSAndroid Build Coastguard Worker     {
3558*35238bceSAndroid Build Coastguard Worker         const bool validContext = m_specs[0].apiType == spec.apiType;
3559*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(validContext);
3560*35238bceSAndroid Build Coastguard Worker 
3561*35238bceSAndroid Build Coastguard Worker         if (!validContext)
3562*35238bceSAndroid Build Coastguard Worker             return;
3563*35238bceSAndroid Build Coastguard Worker     }
3564*35238bceSAndroid Build Coastguard Worker 
3565*35238bceSAndroid Build Coastguard Worker     m_specs.push_back(spec);
3566*35238bceSAndroid Build Coastguard Worker 
3567*35238bceSAndroid Build Coastguard Worker     if (description)
3568*35238bceSAndroid Build Coastguard Worker         m_iteration_descriptions.push_back(std::string(description));
3569*35238bceSAndroid Build Coastguard Worker     else
3570*35238bceSAndroid Build Coastguard Worker         m_iteration_descriptions.push_back(std::string());
3571*35238bceSAndroid Build Coastguard Worker }
3572*35238bceSAndroid Build Coastguard Worker 
init(void)3573*35238bceSAndroid Build Coastguard Worker void DrawTest::init(void)
3574*35238bceSAndroid Build Coastguard Worker {
3575*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!m_specs.empty());
3576*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(contextSupports(m_renderCtx.getType(), m_specs[0].apiType));
3577*35238bceSAndroid Build Coastguard Worker 
3578*35238bceSAndroid Build Coastguard Worker     const int renderTargetWidth  = de::min(MAX_RENDER_TARGET_SIZE, m_renderCtx.getRenderTarget().getWidth());
3579*35238bceSAndroid Build Coastguard Worker     const int renderTargetHeight = de::min(MAX_RENDER_TARGET_SIZE, m_renderCtx.getRenderTarget().getHeight());
3580*35238bceSAndroid Build Coastguard Worker 
3581*35238bceSAndroid Build Coastguard Worker     // lines have significantly different rasterization in MSAA mode
3582*35238bceSAndroid Build Coastguard Worker     const bool isLineCase         = containsLineCases(m_specs);
3583*35238bceSAndroid Build Coastguard Worker     const bool isMSAACase         = m_renderCtx.getRenderTarget().getNumSamples() > 1;
3584*35238bceSAndroid Build Coastguard Worker     const int renderTargetSamples = (isMSAACase && isLineCase) ? (4) : (1);
3585*35238bceSAndroid Build Coastguard Worker 
3586*35238bceSAndroid Build Coastguard Worker     sglr::ReferenceContextLimits limits(m_renderCtx);
3587*35238bceSAndroid Build Coastguard Worker     bool useVao = false;
3588*35238bceSAndroid Build Coastguard Worker 
3589*35238bceSAndroid Build Coastguard Worker     m_glesContext =
3590*35238bceSAndroid Build Coastguard Worker         new sglr::GLContext(m_renderCtx, m_testCtx.getLog(), sglr::GLCONTEXT_LOG_CALLS | sglr::GLCONTEXT_LOG_PROGRAMS,
3591*35238bceSAndroid Build Coastguard Worker                             tcu::IVec4(0, 0, renderTargetWidth, renderTargetHeight));
3592*35238bceSAndroid Build Coastguard Worker 
3593*35238bceSAndroid Build Coastguard Worker     if (m_renderCtx.getType().getAPI() == glu::ApiType::es(2, 0) ||
3594*35238bceSAndroid Build Coastguard Worker         m_renderCtx.getType().getAPI() == glu::ApiType::es(3, 0))
3595*35238bceSAndroid Build Coastguard Worker         useVao = false;
3596*35238bceSAndroid Build Coastguard Worker     else if (contextSupports(m_renderCtx.getType(), glu::ApiType::es(3, 1)) ||
3597*35238bceSAndroid Build Coastguard Worker              glu::isContextTypeGLCore(m_renderCtx.getType()))
3598*35238bceSAndroid Build Coastguard Worker         useVao = true;
3599*35238bceSAndroid Build Coastguard Worker     else
3600*35238bceSAndroid Build Coastguard Worker         DE_FATAL("Unknown context type");
3601*35238bceSAndroid Build Coastguard Worker 
3602*35238bceSAndroid Build Coastguard Worker     m_refBuffers = new sglr::ReferenceContextBuffers(m_renderCtx.getRenderTarget().getPixelFormat(), 0, 0,
3603*35238bceSAndroid Build Coastguard Worker                                                      renderTargetWidth, renderTargetHeight, renderTargetSamples);
3604*35238bceSAndroid Build Coastguard Worker     m_refContext = new sglr::ReferenceContext(limits, m_refBuffers->getColorbuffer(), m_refBuffers->getDepthbuffer(),
3605*35238bceSAndroid Build Coastguard Worker                                               m_refBuffers->getStencilbuffer());
3606*35238bceSAndroid Build Coastguard Worker 
3607*35238bceSAndroid Build Coastguard Worker     m_glArrayPack = new AttributePack(m_testCtx, m_renderCtx, *m_glesContext,
3608*35238bceSAndroid Build Coastguard Worker                                       tcu::UVec2(renderTargetWidth, renderTargetHeight), useVao, true);
3609*35238bceSAndroid Build Coastguard Worker     m_rrArrayPack = new AttributePack(m_testCtx, m_renderCtx, *m_refContext,
3610*35238bceSAndroid Build Coastguard Worker                                       tcu::UVec2(renderTargetWidth, renderTargetHeight), useVao, false);
3611*35238bceSAndroid Build Coastguard Worker 
3612*35238bceSAndroid Build Coastguard Worker     m_maxDiffRed =
3613*35238bceSAndroid Build Coastguard Worker         deCeilFloatToInt32(256.0f * (6.0f / (float)(1 << m_renderCtx.getRenderTarget().getPixelFormat().redBits)));
3614*35238bceSAndroid Build Coastguard Worker     m_maxDiffGreen =
3615*35238bceSAndroid Build Coastguard Worker         deCeilFloatToInt32(256.0f * (6.0f / (float)(1 << m_renderCtx.getRenderTarget().getPixelFormat().greenBits)));
3616*35238bceSAndroid Build Coastguard Worker     m_maxDiffBlue =
3617*35238bceSAndroid Build Coastguard Worker         deCeilFloatToInt32(256.0f * (6.0f / (float)(1 << m_renderCtx.getRenderTarget().getPixelFormat().blueBits)));
3618*35238bceSAndroid Build Coastguard Worker     m_contextInfo = glu::ContextInfo::create(m_renderCtx);
3619*35238bceSAndroid Build Coastguard Worker }
3620*35238bceSAndroid Build Coastguard Worker 
deinit(void)3621*35238bceSAndroid Build Coastguard Worker void DrawTest::deinit(void)
3622*35238bceSAndroid Build Coastguard Worker {
3623*35238bceSAndroid Build Coastguard Worker     delete m_glArrayPack;
3624*35238bceSAndroid Build Coastguard Worker     delete m_rrArrayPack;
3625*35238bceSAndroid Build Coastguard Worker     delete m_refBuffers;
3626*35238bceSAndroid Build Coastguard Worker     delete m_refContext;
3627*35238bceSAndroid Build Coastguard Worker     delete m_glesContext;
3628*35238bceSAndroid Build Coastguard Worker     delete m_contextInfo;
3629*35238bceSAndroid Build Coastguard Worker 
3630*35238bceSAndroid Build Coastguard Worker     m_glArrayPack = DE_NULL;
3631*35238bceSAndroid Build Coastguard Worker     m_rrArrayPack = DE_NULL;
3632*35238bceSAndroid Build Coastguard Worker     m_refBuffers  = DE_NULL;
3633*35238bceSAndroid Build Coastguard Worker     m_refContext  = DE_NULL;
3634*35238bceSAndroid Build Coastguard Worker     m_glesContext = DE_NULL;
3635*35238bceSAndroid Build Coastguard Worker     m_contextInfo = DE_NULL;
3636*35238bceSAndroid Build Coastguard Worker }
3637*35238bceSAndroid Build Coastguard Worker 
iterate(void)3638*35238bceSAndroid Build Coastguard Worker DrawTest::IterateResult DrawTest::iterate(void)
3639*35238bceSAndroid Build Coastguard Worker {
3640*35238bceSAndroid Build Coastguard Worker     const int specNdx        = (m_iteration / 2);
3641*35238bceSAndroid Build Coastguard Worker     const DrawTestSpec &spec = m_specs[specNdx];
3642*35238bceSAndroid Build Coastguard Worker 
3643*35238bceSAndroid Build Coastguard Worker     if (spec.drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_BASEVERTEX ||
3644*35238bceSAndroid Build Coastguard Worker         spec.drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX ||
3645*35238bceSAndroid Build Coastguard Worker         spec.drawMethod == DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX)
3646*35238bceSAndroid Build Coastguard Worker     {
3647*35238bceSAndroid Build Coastguard Worker         const bool supportsES32orGL45 = contextSupports(m_renderCtx.getType(), glu::ApiType::es(3, 2)) ||
3648*35238bceSAndroid Build Coastguard Worker                                         contextSupports(m_renderCtx.getType(), glu::ApiType::core(4, 5));
3649*35238bceSAndroid Build Coastguard Worker         TCU_CHECK_AND_THROW(NotSupportedError,
3650*35238bceSAndroid Build Coastguard Worker                             supportsES32orGL45 ||
3651*35238bceSAndroid Build Coastguard Worker                                 m_contextInfo->isExtensionSupported("GL_EXT_draw_elements_base_vertex"),
3652*35238bceSAndroid Build Coastguard Worker                             "GL_EXT_draw_elements_base_vertex is not supported.");
3653*35238bceSAndroid Build Coastguard Worker     }
3654*35238bceSAndroid Build Coastguard Worker 
3655*35238bceSAndroid Build Coastguard Worker     const bool drawStep               = (m_iteration % 2) == 0;
3656*35238bceSAndroid Build Coastguard Worker     const bool compareStep            = (m_iteration % 2) == 1;
3657*35238bceSAndroid Build Coastguard Worker     const IterateResult iterateResult = ((size_t)m_iteration + 1 == m_specs.size() * 2) ? (STOP) : (CONTINUE);
3658*35238bceSAndroid Build Coastguard Worker     const bool updateProgram =
3659*35238bceSAndroid Build Coastguard Worker         (m_iteration == 0) ||
3660*35238bceSAndroid Build Coastguard Worker         (drawStep && !checkSpecsShaderCompatible(m_specs[specNdx],
3661*35238bceSAndroid Build Coastguard Worker                                                  m_specs[specNdx - 1])); // try to use the same shader in all iterations
3662*35238bceSAndroid Build Coastguard Worker     IterationLogSectionEmitter sectionEmitter(m_testCtx.getLog(), specNdx, m_specs.size(),
3663*35238bceSAndroid Build Coastguard Worker                                               m_iteration_descriptions[specNdx], drawStep && m_specs.size() != 1);
3664*35238bceSAndroid Build Coastguard Worker 
3665*35238bceSAndroid Build Coastguard Worker     if (drawStep)
3666*35238bceSAndroid Build Coastguard Worker     {
3667*35238bceSAndroid Build Coastguard Worker         const MethodInfo methodInfo = getMethodInfo(spec.drawMethod);
3668*35238bceSAndroid Build Coastguard Worker         const bool indexed          = methodInfo.indexed;
3669*35238bceSAndroid Build Coastguard Worker         const bool instanced        = methodInfo.instanced;
3670*35238bceSAndroid Build Coastguard Worker         const bool ranged           = methodInfo.ranged;
3671*35238bceSAndroid Build Coastguard Worker         const bool hasFirst         = methodInfo.first;
3672*35238bceSAndroid Build Coastguard Worker         const bool hasBaseVtx       = methodInfo.baseVertex;
3673*35238bceSAndroid Build Coastguard Worker 
3674*35238bceSAndroid Build Coastguard Worker         const size_t primitiveElementCount =
3675*35238bceSAndroid Build Coastguard Worker             getElementCount(spec.primitive, spec.primitiveCount); // !< elements to be drawn
3676*35238bceSAndroid Build Coastguard Worker         const int indexMin           = (ranged) ? (spec.indexMin) : (0);
3677*35238bceSAndroid Build Coastguard Worker         const int firstAddition      = (hasFirst) ? (spec.first) : (0);
3678*35238bceSAndroid Build Coastguard Worker         const int baseVertexAddition = (hasBaseVtx && spec.baseVertex > 0) ?
3679*35238bceSAndroid Build Coastguard Worker                                            (spec.baseVertex) :
3680*35238bceSAndroid Build Coastguard Worker                                            (0); // spec.baseVertex > 0 => Create bigger attribute buffer
3681*35238bceSAndroid Build Coastguard Worker         const int indexBase          = (hasBaseVtx && spec.baseVertex < 0) ? (-spec.baseVertex) :
3682*35238bceSAndroid Build Coastguard Worker                                                                              (0); // spec.baseVertex < 0 => Create bigger indices
3683*35238bceSAndroid Build Coastguard Worker         const size_t elementCount =
3684*35238bceSAndroid Build Coastguard Worker             primitiveElementCount + indexMin + firstAddition +
3685*35238bceSAndroid Build Coastguard Worker             baseVertexAddition; // !< elements in buffer (buffer should have at least primitiveElementCount ACCESSIBLE (index range, first) elements)
3686*35238bceSAndroid Build Coastguard Worker         const int maxElementIndex = (int)primitiveElementCount + indexMin + firstAddition - 1;
3687*35238bceSAndroid Build Coastguard Worker         const int indexMax =
3688*35238bceSAndroid Build Coastguard Worker             de::max(0, (ranged) ? (de::clamp<int>(spec.indexMax, 0, maxElementIndex)) : (maxElementIndex));
3689*35238bceSAndroid Build Coastguard Worker         float coordScale = getCoordScale(spec);
3690*35238bceSAndroid Build Coastguard Worker         float colorScale = getColorScale(spec);
3691*35238bceSAndroid Build Coastguard Worker 
3692*35238bceSAndroid Build Coastguard Worker         rr::GenericVec4 nullAttribValue;
3693*35238bceSAndroid Build Coastguard Worker 
3694*35238bceSAndroid Build Coastguard Worker         // Log info
3695*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Message << spec.getMultilineDesc() << TestLog::EndMessage;
3696*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Message << TestLog::EndMessage; // extra line for clarity
3697*35238bceSAndroid Build Coastguard Worker 
3698*35238bceSAndroid Build Coastguard Worker         // Data
3699*35238bceSAndroid Build Coastguard Worker 
3700*35238bceSAndroid Build Coastguard Worker         m_glArrayPack->clearArrays();
3701*35238bceSAndroid Build Coastguard Worker         m_rrArrayPack->clearArrays();
3702*35238bceSAndroid Build Coastguard Worker 
3703*35238bceSAndroid Build Coastguard Worker         for (int attribNdx = 0; attribNdx < (int)spec.attribs.size(); attribNdx++)
3704*35238bceSAndroid Build Coastguard Worker         {
3705*35238bceSAndroid Build Coastguard Worker             DrawTestSpec::AttributeSpec attribSpec = spec.attribs[attribNdx];
3706*35238bceSAndroid Build Coastguard Worker             const bool isPositionAttr              = (attribNdx == 0) || (attribSpec.additionalPositionAttribute);
3707*35238bceSAndroid Build Coastguard Worker 
3708*35238bceSAndroid Build Coastguard Worker             if (attribSpec.useDefaultAttribute)
3709*35238bceSAndroid Build Coastguard Worker             {
3710*35238bceSAndroid Build Coastguard Worker                 const int seed              = 10 * attribSpec.hash() + 100 * spec.hash() + attribNdx;
3711*35238bceSAndroid Build Coastguard Worker                 rr::GenericVec4 attribValue = RandomArrayGenerator::generateAttributeValue(seed, attribSpec.inputType);
3712*35238bceSAndroid Build Coastguard Worker 
3713*35238bceSAndroid Build Coastguard Worker                 m_glArrayPack->newArray(DrawTestSpec::STORAGE_USER);
3714*35238bceSAndroid Build Coastguard Worker                 m_rrArrayPack->newArray(DrawTestSpec::STORAGE_USER);
3715*35238bceSAndroid Build Coastguard Worker 
3716*35238bceSAndroid Build Coastguard Worker                 m_glArrayPack->getArray(attribNdx)->setupArray(false, 0, attribSpec.componentCount,
3717*35238bceSAndroid Build Coastguard Worker                                                                attribSpec.inputType, attribSpec.outputType, false, 0, 0,
3718*35238bceSAndroid Build Coastguard Worker                                                                attribValue, isPositionAttr, false);
3719*35238bceSAndroid Build Coastguard Worker                 m_rrArrayPack->getArray(attribNdx)->setupArray(false, 0, attribSpec.componentCount,
3720*35238bceSAndroid Build Coastguard Worker                                                                attribSpec.inputType, attribSpec.outputType, false, 0, 0,
3721*35238bceSAndroid Build Coastguard Worker                                                                attribValue, isPositionAttr, false);
3722*35238bceSAndroid Build Coastguard Worker             }
3723*35238bceSAndroid Build Coastguard Worker             else
3724*35238bceSAndroid Build Coastguard Worker             {
3725*35238bceSAndroid Build Coastguard Worker                 const int seed = attribSpec.hash() + 100 * spec.hash() + attribNdx;
3726*35238bceSAndroid Build Coastguard Worker                 const size_t elementSize =
3727*35238bceSAndroid Build Coastguard Worker                     attribSpec.componentCount * DrawTestSpec::inputTypeSize(attribSpec.inputType);
3728*35238bceSAndroid Build Coastguard Worker                 const size_t stride                = (attribSpec.stride == 0) ? (elementSize) : (attribSpec.stride);
3729*35238bceSAndroid Build Coastguard Worker                 const size_t evaluatedElementCount = (instanced && attribSpec.instanceDivisor > 0) ?
3730*35238bceSAndroid Build Coastguard Worker                                                          (spec.instanceCount / attribSpec.instanceDivisor + 1) :
3731*35238bceSAndroid Build Coastguard Worker                                                          (elementCount);
3732*35238bceSAndroid Build Coastguard Worker                 const size_t referencedElementCount =
3733*35238bceSAndroid Build Coastguard Worker                     (ranged) ? (de::max<size_t>(evaluatedElementCount, spec.indexMax + 1)) : (evaluatedElementCount);
3734*35238bceSAndroid Build Coastguard Worker                 const size_t bufferSize = attribSpec.offset + stride * (referencedElementCount - 1) + elementSize;
3735*35238bceSAndroid Build Coastguard Worker                 const char *data =
3736*35238bceSAndroid Build Coastguard Worker                     RandomArrayGenerator::generateArray(seed, (int)referencedElementCount, attribSpec.componentCount,
3737*35238bceSAndroid Build Coastguard Worker                                                         attribSpec.offset, (int)stride, attribSpec.inputType);
3738*35238bceSAndroid Build Coastguard Worker 
3739*35238bceSAndroid Build Coastguard Worker                 try
3740*35238bceSAndroid Build Coastguard Worker                 {
3741*35238bceSAndroid Build Coastguard Worker                     m_glArrayPack->newArray(attribSpec.storage);
3742*35238bceSAndroid Build Coastguard Worker                     m_rrArrayPack->newArray(attribSpec.storage);
3743*35238bceSAndroid Build Coastguard Worker 
3744*35238bceSAndroid Build Coastguard Worker                     m_glArrayPack->getArray(attribNdx)->data(DrawTestSpec::TARGET_ARRAY, bufferSize, data,
3745*35238bceSAndroid Build Coastguard Worker                                                              attribSpec.usage);
3746*35238bceSAndroid Build Coastguard Worker                     m_rrArrayPack->getArray(attribNdx)->data(DrawTestSpec::TARGET_ARRAY, bufferSize, data,
3747*35238bceSAndroid Build Coastguard Worker                                                              attribSpec.usage);
3748*35238bceSAndroid Build Coastguard Worker 
3749*35238bceSAndroid Build Coastguard Worker                     m_glArrayPack->getArray(attribNdx)->setupArray(
3750*35238bceSAndroid Build Coastguard Worker                         true, attribSpec.offset, attribSpec.componentCount, attribSpec.inputType, attribSpec.outputType,
3751*35238bceSAndroid Build Coastguard Worker                         attribSpec.normalize, attribSpec.stride, attribSpec.instanceDivisor, nullAttribValue,
3752*35238bceSAndroid Build Coastguard Worker                         isPositionAttr, attribSpec.bgraComponentOrder);
3753*35238bceSAndroid Build Coastguard Worker                     m_rrArrayPack->getArray(attribNdx)->setupArray(
3754*35238bceSAndroid Build Coastguard Worker                         true, attribSpec.offset, attribSpec.componentCount, attribSpec.inputType, attribSpec.outputType,
3755*35238bceSAndroid Build Coastguard Worker                         attribSpec.normalize, attribSpec.stride, attribSpec.instanceDivisor, nullAttribValue,
3756*35238bceSAndroid Build Coastguard Worker                         isPositionAttr, attribSpec.bgraComponentOrder);
3757*35238bceSAndroid Build Coastguard Worker 
3758*35238bceSAndroid Build Coastguard Worker                     delete[] data;
3759*35238bceSAndroid Build Coastguard Worker                     data = NULL;
3760*35238bceSAndroid Build Coastguard Worker                 }
3761*35238bceSAndroid Build Coastguard Worker                 catch (...)
3762*35238bceSAndroid Build Coastguard Worker                 {
3763*35238bceSAndroid Build Coastguard Worker                     delete[] data;
3764*35238bceSAndroid Build Coastguard Worker                     throw;
3765*35238bceSAndroid Build Coastguard Worker                 }
3766*35238bceSAndroid Build Coastguard Worker             }
3767*35238bceSAndroid Build Coastguard Worker         }
3768*35238bceSAndroid Build Coastguard Worker 
3769*35238bceSAndroid Build Coastguard Worker         // Shader program
3770*35238bceSAndroid Build Coastguard Worker         if (updateProgram)
3771*35238bceSAndroid Build Coastguard Worker         {
3772*35238bceSAndroid Build Coastguard Worker             m_glArrayPack->updateProgram();
3773*35238bceSAndroid Build Coastguard Worker             m_rrArrayPack->updateProgram();
3774*35238bceSAndroid Build Coastguard Worker         }
3775*35238bceSAndroid Build Coastguard Worker 
3776*35238bceSAndroid Build Coastguard Worker         // Draw
3777*35238bceSAndroid Build Coastguard Worker         try
3778*35238bceSAndroid Build Coastguard Worker         {
3779*35238bceSAndroid Build Coastguard Worker             // indices
3780*35238bceSAndroid Build Coastguard Worker             if (indexed)
3781*35238bceSAndroid Build Coastguard Worker             {
3782*35238bceSAndroid Build Coastguard Worker                 const int seed                = spec.hash();
3783*35238bceSAndroid Build Coastguard Worker                 const size_t indexElementSize = DrawTestSpec::indexTypeSize(spec.indexType);
3784*35238bceSAndroid Build Coastguard Worker                 const size_t indexArraySize   = spec.indexPointerOffset + indexElementSize * elementCount;
3785*35238bceSAndroid Build Coastguard Worker                 const char *indexArray        = RandomArrayGenerator::generateIndices(
3786*35238bceSAndroid Build Coastguard Worker                     seed, (int)elementCount, spec.indexType, spec.indexPointerOffset, indexMin, indexMax, indexBase);
3787*35238bceSAndroid Build Coastguard Worker                 const char *indexPointerBase =
3788*35238bceSAndroid Build Coastguard Worker                     (spec.indexStorage == DrawTestSpec::STORAGE_USER) ? (indexArray) : ((char *)DE_NULL);
3789*35238bceSAndroid Build Coastguard Worker                 const char *indexPointer = indexPointerBase + spec.indexPointerOffset;
3790*35238bceSAndroid Build Coastguard Worker 
3791*35238bceSAndroid Build Coastguard Worker                 de::UniquePtr<AttributeArray> glArray(new AttributeArray(spec.indexStorage, *m_glesContext));
3792*35238bceSAndroid Build Coastguard Worker                 de::UniquePtr<AttributeArray> rrArray(new AttributeArray(spec.indexStorage, *m_refContext));
3793*35238bceSAndroid Build Coastguard Worker 
3794*35238bceSAndroid Build Coastguard Worker                 try
3795*35238bceSAndroid Build Coastguard Worker                 {
3796*35238bceSAndroid Build Coastguard Worker                     glArray->data(DrawTestSpec::TARGET_ELEMENT_ARRAY, indexArraySize, indexArray,
3797*35238bceSAndroid Build Coastguard Worker                                   DrawTestSpec::USAGE_STATIC_DRAW);
3798*35238bceSAndroid Build Coastguard Worker                     rrArray->data(DrawTestSpec::TARGET_ELEMENT_ARRAY, indexArraySize, indexArray,
3799*35238bceSAndroid Build Coastguard Worker                                   DrawTestSpec::USAGE_STATIC_DRAW);
3800*35238bceSAndroid Build Coastguard Worker 
3801*35238bceSAndroid Build Coastguard Worker                     m_glArrayPack->render(spec.primitive, spec.drawMethod, 0, (int)primitiveElementCount,
3802*35238bceSAndroid Build Coastguard Worker                                           spec.indexType, indexPointer, spec.indexMin, spec.indexMax,
3803*35238bceSAndroid Build Coastguard Worker                                           spec.instanceCount, spec.indirectOffset, spec.baseVertex, coordScale,
3804*35238bceSAndroid Build Coastguard Worker                                           colorScale, glArray.get());
3805*35238bceSAndroid Build Coastguard Worker                     m_rrArrayPack->render(spec.primitive, spec.drawMethod, 0, (int)primitiveElementCount,
3806*35238bceSAndroid Build Coastguard Worker                                           spec.indexType, indexPointer, spec.indexMin, spec.indexMax,
3807*35238bceSAndroid Build Coastguard Worker                                           spec.instanceCount, spec.indirectOffset, spec.baseVertex, coordScale,
3808*35238bceSAndroid Build Coastguard Worker                                           colorScale, rrArray.get());
3809*35238bceSAndroid Build Coastguard Worker 
3810*35238bceSAndroid Build Coastguard Worker                     delete[] indexArray;
3811*35238bceSAndroid Build Coastguard Worker                     indexArray = NULL;
3812*35238bceSAndroid Build Coastguard Worker                 }
3813*35238bceSAndroid Build Coastguard Worker                 catch (...)
3814*35238bceSAndroid Build Coastguard Worker                 {
3815*35238bceSAndroid Build Coastguard Worker                     delete[] indexArray;
3816*35238bceSAndroid Build Coastguard Worker                     throw;
3817*35238bceSAndroid Build Coastguard Worker                 }
3818*35238bceSAndroid Build Coastguard Worker             }
3819*35238bceSAndroid Build Coastguard Worker             else
3820*35238bceSAndroid Build Coastguard Worker             {
3821*35238bceSAndroid Build Coastguard Worker                 m_glArrayPack->render(spec.primitive, spec.drawMethod, spec.first, (int)primitiveElementCount,
3822*35238bceSAndroid Build Coastguard Worker                                       DrawTestSpec::INDEXTYPE_LAST, DE_NULL, 0, 0, spec.instanceCount,
3823*35238bceSAndroid Build Coastguard Worker                                       spec.indirectOffset, 0, coordScale, colorScale, DE_NULL);
3824*35238bceSAndroid Build Coastguard Worker                 m_testCtx.touchWatchdog();
3825*35238bceSAndroid Build Coastguard Worker                 m_rrArrayPack->render(spec.primitive, spec.drawMethod, spec.first, (int)primitiveElementCount,
3826*35238bceSAndroid Build Coastguard Worker                                       DrawTestSpec::INDEXTYPE_LAST, DE_NULL, 0, 0, spec.instanceCount,
3827*35238bceSAndroid Build Coastguard Worker                                       spec.indirectOffset, 0, coordScale, colorScale, DE_NULL);
3828*35238bceSAndroid Build Coastguard Worker             }
3829*35238bceSAndroid Build Coastguard Worker         }
3830*35238bceSAndroid Build Coastguard Worker         catch (glu::Error &err)
3831*35238bceSAndroid Build Coastguard Worker         {
3832*35238bceSAndroid Build Coastguard Worker             // GL Errors are ok if the mode is not properly aligned
3833*35238bceSAndroid Build Coastguard Worker 
3834*35238bceSAndroid Build Coastguard Worker             const DrawTestSpec::CompatibilityTestType ctype = spec.isCompatibilityTest();
3835*35238bceSAndroid Build Coastguard Worker 
3836*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << TestLog::Message << "Got error: " << err.what() << TestLog::EndMessage;
3837*35238bceSAndroid Build Coastguard Worker 
3838*35238bceSAndroid Build Coastguard Worker             if (ctype == DrawTestSpec::COMPATIBILITY_UNALIGNED_OFFSET)
3839*35238bceSAndroid Build Coastguard Worker                 m_result.addResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Failed to draw with unaligned buffers.");
3840*35238bceSAndroid Build Coastguard Worker             else if (ctype == DrawTestSpec::COMPATIBILITY_UNALIGNED_STRIDE)
3841*35238bceSAndroid Build Coastguard Worker                 m_result.addResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Failed to draw with unaligned stride.");
3842*35238bceSAndroid Build Coastguard Worker             else
3843*35238bceSAndroid Build Coastguard Worker                 throw;
3844*35238bceSAndroid Build Coastguard Worker         }
3845*35238bceSAndroid Build Coastguard Worker     }
3846*35238bceSAndroid Build Coastguard Worker     else if (compareStep)
3847*35238bceSAndroid Build Coastguard Worker     {
3848*35238bceSAndroid Build Coastguard Worker         if (!compare(spec.primitive))
3849*35238bceSAndroid Build Coastguard Worker         {
3850*35238bceSAndroid Build Coastguard Worker             const DrawTestSpec::CompatibilityTestType ctype = spec.isCompatibilityTest();
3851*35238bceSAndroid Build Coastguard Worker 
3852*35238bceSAndroid Build Coastguard Worker             if (ctype == DrawTestSpec::COMPATIBILITY_UNALIGNED_OFFSET)
3853*35238bceSAndroid Build Coastguard Worker                 m_result.addResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Failed to draw with unaligned buffers.");
3854*35238bceSAndroid Build Coastguard Worker             else if (ctype == DrawTestSpec::COMPATIBILITY_UNALIGNED_STRIDE)
3855*35238bceSAndroid Build Coastguard Worker                 m_result.addResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Failed to draw with unaligned stride.");
3856*35238bceSAndroid Build Coastguard Worker             else
3857*35238bceSAndroid Build Coastguard Worker                 m_result.addResult(QP_TEST_RESULT_FAIL, "Image comparison failed.");
3858*35238bceSAndroid Build Coastguard Worker         }
3859*35238bceSAndroid Build Coastguard Worker     }
3860*35238bceSAndroid Build Coastguard Worker     else
3861*35238bceSAndroid Build Coastguard Worker     {
3862*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
3863*35238bceSAndroid Build Coastguard Worker         return STOP;
3864*35238bceSAndroid Build Coastguard Worker     }
3865*35238bceSAndroid Build Coastguard Worker 
3866*35238bceSAndroid Build Coastguard Worker     m_result.setTestContextResult(m_testCtx);
3867*35238bceSAndroid Build Coastguard Worker 
3868*35238bceSAndroid Build Coastguard Worker     m_iteration++;
3869*35238bceSAndroid Build Coastguard Worker     return iterateResult;
3870*35238bceSAndroid Build Coastguard Worker }
3871*35238bceSAndroid Build Coastguard Worker 
isBlack(const tcu::RGBA & c)3872*35238bceSAndroid Build Coastguard Worker static bool isBlack(const tcu::RGBA &c)
3873*35238bceSAndroid Build Coastguard Worker {
3874*35238bceSAndroid Build Coastguard Worker     // ignore alpha channel
3875*35238bceSAndroid Build Coastguard Worker     return c.getRed() == 0 && c.getGreen() == 0 && c.getBlue() == 0;
3876*35238bceSAndroid Build Coastguard Worker }
3877*35238bceSAndroid Build Coastguard Worker 
isEdgeTripletComponent(int c1,int c2,int c3,int renderTargetDifference)3878*35238bceSAndroid Build Coastguard Worker static bool isEdgeTripletComponent(int c1, int c2, int c3, int renderTargetDifference)
3879*35238bceSAndroid Build Coastguard Worker {
3880*35238bceSAndroid Build Coastguard Worker     const int roundingDifference = 2 * renderTargetDifference; // src and dst pixels rounded to different directions
3881*35238bceSAndroid Build Coastguard Worker     const int d1                 = c2 - c1;
3882*35238bceSAndroid Build Coastguard Worker     const int d2                 = c3 - c2;
3883*35238bceSAndroid Build Coastguard Worker     const int rampDiff           = de::abs(d2 - d1);
3884*35238bceSAndroid Build Coastguard Worker 
3885*35238bceSAndroid Build Coastguard Worker     return rampDiff > roundingDifference;
3886*35238bceSAndroid Build Coastguard Worker }
3887*35238bceSAndroid Build Coastguard Worker 
isEdgeTriplet(const tcu::RGBA & c1,const tcu::RGBA & c2,const tcu::RGBA & c3,const tcu::IVec3 & renderTargetThreshold)3888*35238bceSAndroid Build Coastguard Worker static bool isEdgeTriplet(const tcu::RGBA &c1, const tcu::RGBA &c2, const tcu::RGBA &c3,
3889*35238bceSAndroid Build Coastguard Worker                           const tcu::IVec3 &renderTargetThreshold)
3890*35238bceSAndroid Build Coastguard Worker {
3891*35238bceSAndroid Build Coastguard Worker     // black (background color) and non-black is always an edge
3892*35238bceSAndroid Build Coastguard Worker     {
3893*35238bceSAndroid Build Coastguard Worker         const bool b1 = isBlack(c1);
3894*35238bceSAndroid Build Coastguard Worker         const bool b2 = isBlack(c2);
3895*35238bceSAndroid Build Coastguard Worker         const bool b3 = isBlack(c3);
3896*35238bceSAndroid Build Coastguard Worker 
3897*35238bceSAndroid Build Coastguard Worker         // both pixels with coverage and pixels without coverage
3898*35238bceSAndroid Build Coastguard Worker         if ((b1 && b2 && b3) == false && (b1 || b2 || b3) == true)
3899*35238bceSAndroid Build Coastguard Worker             return true;
3900*35238bceSAndroid Build Coastguard Worker         // all black
3901*35238bceSAndroid Build Coastguard Worker         if (b1 && b2 && b3)
3902*35238bceSAndroid Build Coastguard Worker             return false;
3903*35238bceSAndroid Build Coastguard Worker         // all with coverage
3904*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(!b1 && !b2 && !b3);
3905*35238bceSAndroid Build Coastguard Worker     }
3906*35238bceSAndroid Build Coastguard Worker 
3907*35238bceSAndroid Build Coastguard Worker     // Color is always linearly interpolated => component values change nearly linearly
3908*35238bceSAndroid Build Coastguard Worker     // in any constant direction on triangle hull. (df/dx ~= C).
3909*35238bceSAndroid Build Coastguard Worker 
3910*35238bceSAndroid Build Coastguard Worker     // Edge detection (this function) is run against the reference image
3911*35238bceSAndroid Build Coastguard Worker     // => no dithering to worry about
3912*35238bceSAndroid Build Coastguard Worker 
3913*35238bceSAndroid Build Coastguard Worker     return isEdgeTripletComponent(c1.getRed(), c2.getRed(), c3.getRed(), renderTargetThreshold.x()) ||
3914*35238bceSAndroid Build Coastguard Worker            isEdgeTripletComponent(c1.getGreen(), c2.getGreen(), c3.getGreen(), renderTargetThreshold.y()) ||
3915*35238bceSAndroid Build Coastguard Worker            isEdgeTripletComponent(c1.getBlue(), c2.getBlue(), c3.getBlue(), renderTargetThreshold.z());
3916*35238bceSAndroid Build Coastguard Worker }
3917*35238bceSAndroid Build Coastguard Worker 
pixelNearEdge(int x,int y,const tcu::Surface & ref,const tcu::IVec3 & renderTargetThreshold)3918*35238bceSAndroid Build Coastguard Worker static bool pixelNearEdge(int x, int y, const tcu::Surface &ref, const tcu::IVec3 &renderTargetThreshold)
3919*35238bceSAndroid Build Coastguard Worker {
3920*35238bceSAndroid Build Coastguard Worker     // should not be called for edge pixels
3921*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(x >= 1 && x <= ref.getWidth() - 2);
3922*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(y >= 1 && y <= ref.getHeight() - 2);
3923*35238bceSAndroid Build Coastguard Worker 
3924*35238bceSAndroid Build Coastguard Worker     // horizontal
3925*35238bceSAndroid Build Coastguard Worker 
3926*35238bceSAndroid Build Coastguard Worker     for (int dy = -1; dy < 2; ++dy)
3927*35238bceSAndroid Build Coastguard Worker     {
3928*35238bceSAndroid Build Coastguard Worker         const tcu::RGBA c1 = ref.getPixel(x - 1, y + dy);
3929*35238bceSAndroid Build Coastguard Worker         const tcu::RGBA c2 = ref.getPixel(x, y + dy);
3930*35238bceSAndroid Build Coastguard Worker         const tcu::RGBA c3 = ref.getPixel(x + 1, y + dy);
3931*35238bceSAndroid Build Coastguard Worker         if (isEdgeTriplet(c1, c2, c3, renderTargetThreshold))
3932*35238bceSAndroid Build Coastguard Worker             return true;
3933*35238bceSAndroid Build Coastguard Worker     }
3934*35238bceSAndroid Build Coastguard Worker 
3935*35238bceSAndroid Build Coastguard Worker     // vertical
3936*35238bceSAndroid Build Coastguard Worker 
3937*35238bceSAndroid Build Coastguard Worker     for (int dx = -1; dx < 2; ++dx)
3938*35238bceSAndroid Build Coastguard Worker     {
3939*35238bceSAndroid Build Coastguard Worker         const tcu::RGBA c1 = ref.getPixel(x + dx, y - 1);
3940*35238bceSAndroid Build Coastguard Worker         const tcu::RGBA c2 = ref.getPixel(x + dx, y);
3941*35238bceSAndroid Build Coastguard Worker         const tcu::RGBA c3 = ref.getPixel(x + dx, y + 1);
3942*35238bceSAndroid Build Coastguard Worker         if (isEdgeTriplet(c1, c2, c3, renderTargetThreshold))
3943*35238bceSAndroid Build Coastguard Worker             return true;
3944*35238bceSAndroid Build Coastguard Worker     }
3945*35238bceSAndroid Build Coastguard Worker 
3946*35238bceSAndroid Build Coastguard Worker     return false;
3947*35238bceSAndroid Build Coastguard Worker }
3948*35238bceSAndroid Build Coastguard Worker 
getVisualizationGrayscaleColor(const tcu::RGBA & c)3949*35238bceSAndroid Build Coastguard Worker static uint32_t getVisualizationGrayscaleColor(const tcu::RGBA &c)
3950*35238bceSAndroid Build Coastguard Worker {
3951*35238bceSAndroid Build Coastguard Worker     // make triangle coverage and error pixels obvious by converting coverage to grayscale
3952*35238bceSAndroid Build Coastguard Worker     if (isBlack(c))
3953*35238bceSAndroid Build Coastguard Worker         return 0;
3954*35238bceSAndroid Build Coastguard Worker     else
3955*35238bceSAndroid Build Coastguard Worker         return 50u + (uint32_t)(c.getRed() + c.getBlue() + c.getGreen()) / 8u;
3956*35238bceSAndroid Build Coastguard Worker }
3957*35238bceSAndroid Build Coastguard Worker 
pixelNearLineIntersection(int x,int y,const tcu::Surface & target)3958*35238bceSAndroid Build Coastguard Worker static bool pixelNearLineIntersection(int x, int y, const tcu::Surface &target)
3959*35238bceSAndroid Build Coastguard Worker {
3960*35238bceSAndroid Build Coastguard Worker     // should not be called for edge pixels
3961*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(x >= 1 && x <= target.getWidth() - 2);
3962*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(y >= 1 && y <= target.getHeight() - 2);
3963*35238bceSAndroid Build Coastguard Worker 
3964*35238bceSAndroid Build Coastguard Worker     int coveredPixels = 0;
3965*35238bceSAndroid Build Coastguard Worker 
3966*35238bceSAndroid Build Coastguard Worker     for (int dy = -1; dy < 2; dy++)
3967*35238bceSAndroid Build Coastguard Worker         for (int dx = -1; dx < 2; dx++)
3968*35238bceSAndroid Build Coastguard Worker         {
3969*35238bceSAndroid Build Coastguard Worker             const bool targetCoverage = !isBlack(target.getPixel(x + dx, y + dy));
3970*35238bceSAndroid Build Coastguard Worker             if (targetCoverage)
3971*35238bceSAndroid Build Coastguard Worker             {
3972*35238bceSAndroid Build Coastguard Worker                 ++coveredPixels;
3973*35238bceSAndroid Build Coastguard Worker 
3974*35238bceSAndroid Build Coastguard Worker                 // A single thin line cannot have more than 3 covered pixels in a 3x3 area
3975*35238bceSAndroid Build Coastguard Worker                 if (coveredPixels >= 4)
3976*35238bceSAndroid Build Coastguard Worker                     return true;
3977*35238bceSAndroid Build Coastguard Worker             }
3978*35238bceSAndroid Build Coastguard Worker         }
3979*35238bceSAndroid Build Coastguard Worker 
3980*35238bceSAndroid Build Coastguard Worker     return false;
3981*35238bceSAndroid Build Coastguard Worker }
3982*35238bceSAndroid Build Coastguard Worker 
colorsEqual(const tcu::RGBA & colorA,const tcu::RGBA & colorB,const tcu::IVec3 & compareThreshold)3983*35238bceSAndroid Build Coastguard Worker static inline bool colorsEqual(const tcu::RGBA &colorA, const tcu::RGBA &colorB, const tcu::IVec3 &compareThreshold)
3984*35238bceSAndroid Build Coastguard Worker {
3985*35238bceSAndroid Build Coastguard Worker     enum
3986*35238bceSAndroid Build Coastguard Worker     {
3987*35238bceSAndroid Build Coastguard Worker         TCU_RGBA_RGB_MASK = tcu::RGBA::RED_MASK | tcu::RGBA::GREEN_MASK | tcu::RGBA::BLUE_MASK
3988*35238bceSAndroid Build Coastguard Worker     };
3989*35238bceSAndroid Build Coastguard Worker 
3990*35238bceSAndroid Build Coastguard Worker     return tcu::compareThresholdMasked(colorA, colorB,
3991*35238bceSAndroid Build Coastguard Worker                                        tcu::RGBA(compareThreshold.x(), compareThreshold.y(), compareThreshold.z(), 0),
3992*35238bceSAndroid Build Coastguard Worker                                        TCU_RGBA_RGB_MASK);
3993*35238bceSAndroid Build Coastguard Worker }
3994*35238bceSAndroid Build Coastguard Worker 
3995*35238bceSAndroid Build Coastguard Worker // search 3x3 are for matching color
pixelNeighborhoodContainsColor(const tcu::Surface & target,int x,int y,const tcu::RGBA & color,const tcu::IVec3 & compareThreshold)3996*35238bceSAndroid Build Coastguard Worker static bool pixelNeighborhoodContainsColor(const tcu::Surface &target, int x, int y, const tcu::RGBA &color,
3997*35238bceSAndroid Build Coastguard Worker                                            const tcu::IVec3 &compareThreshold)
3998*35238bceSAndroid Build Coastguard Worker {
3999*35238bceSAndroid Build Coastguard Worker     // should not be called for edge pixels
4000*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(x >= 1 && x <= target.getWidth() - 2);
4001*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(y >= 1 && y <= target.getHeight() - 2);
4002*35238bceSAndroid Build Coastguard Worker 
4003*35238bceSAndroid Build Coastguard Worker     for (int dy = -1; dy < 2; dy++)
4004*35238bceSAndroid Build Coastguard Worker         for (int dx = -1; dx < 2; dx++)
4005*35238bceSAndroid Build Coastguard Worker         {
4006*35238bceSAndroid Build Coastguard Worker             const tcu::RGBA targetCmpPixel = target.getPixel(x + dx, y + dy);
4007*35238bceSAndroid Build Coastguard Worker             if (colorsEqual(color, targetCmpPixel, compareThreshold))
4008*35238bceSAndroid Build Coastguard Worker                 return true;
4009*35238bceSAndroid Build Coastguard Worker         }
4010*35238bceSAndroid Build Coastguard Worker 
4011*35238bceSAndroid Build Coastguard Worker     return false;
4012*35238bceSAndroid Build Coastguard Worker }
4013*35238bceSAndroid Build Coastguard Worker 
4014*35238bceSAndroid Build Coastguard Worker // search 3x3 are for matching coverage (coverage == (color != background color))
pixelNeighborhoodContainsCoverage(const tcu::Surface & target,int x,int y,bool coverage)4015*35238bceSAndroid Build Coastguard Worker static bool pixelNeighborhoodContainsCoverage(const tcu::Surface &target, int x, int y, bool coverage)
4016*35238bceSAndroid Build Coastguard Worker {
4017*35238bceSAndroid Build Coastguard Worker     // should not be called for edge pixels
4018*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(x >= 1 && x <= target.getWidth() - 2);
4019*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(y >= 1 && y <= target.getHeight() - 2);
4020*35238bceSAndroid Build Coastguard Worker 
4021*35238bceSAndroid Build Coastguard Worker     for (int dy = -1; dy < 2; dy++)
4022*35238bceSAndroid Build Coastguard Worker         for (int dx = -1; dx < 2; dx++)
4023*35238bceSAndroid Build Coastguard Worker         {
4024*35238bceSAndroid Build Coastguard Worker             const bool targetCmpCoverage = !isBlack(target.getPixel(x + dx, y + dy));
4025*35238bceSAndroid Build Coastguard Worker             if (targetCmpCoverage == coverage)
4026*35238bceSAndroid Build Coastguard Worker                 return true;
4027*35238bceSAndroid Build Coastguard Worker         }
4028*35238bceSAndroid Build Coastguard Worker 
4029*35238bceSAndroid Build Coastguard Worker     return false;
4030*35238bceSAndroid Build Coastguard Worker }
4031*35238bceSAndroid Build Coastguard Worker 
edgeRelaxedImageCompare(tcu::TestLog & log,const char * imageSetName,const char * imageSetDesc,const tcu::Surface & reference,const tcu::Surface & result,const tcu::IVec3 & compareThreshold,const tcu::IVec3 & renderTargetThreshold,int maxAllowedInvalidPixels)4032*35238bceSAndroid Build Coastguard Worker static bool edgeRelaxedImageCompare(tcu::TestLog &log, const char *imageSetName, const char *imageSetDesc,
4033*35238bceSAndroid Build Coastguard Worker                                     const tcu::Surface &reference, const tcu::Surface &result,
4034*35238bceSAndroid Build Coastguard Worker                                     const tcu::IVec3 &compareThreshold, const tcu::IVec3 &renderTargetThreshold,
4035*35238bceSAndroid Build Coastguard Worker                                     int maxAllowedInvalidPixels)
4036*35238bceSAndroid Build Coastguard Worker {
4037*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());
4038*35238bceSAndroid Build Coastguard Worker 
4039*35238bceSAndroid Build Coastguard Worker     const tcu::IVec4 green(0, 255, 0, 255);
4040*35238bceSAndroid Build Coastguard Worker     const tcu::IVec4 red(255, 0, 0, 255);
4041*35238bceSAndroid Build Coastguard Worker     const int width  = reference.getWidth();
4042*35238bceSAndroid Build Coastguard Worker     const int height = reference.getHeight();
4043*35238bceSAndroid Build Coastguard Worker     tcu::TextureLevel errorMask(tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), width,
4044*35238bceSAndroid Build Coastguard Worker                                 height);
4045*35238bceSAndroid Build Coastguard Worker     const tcu::PixelBufferAccess errorAccess = errorMask.getAccess();
4046*35238bceSAndroid Build Coastguard Worker     int numFailingPixels                     = 0;
4047*35238bceSAndroid Build Coastguard Worker 
4048*35238bceSAndroid Build Coastguard Worker     // clear errormask edges which would otherwise be transparent
4049*35238bceSAndroid Build Coastguard Worker 
4050*35238bceSAndroid Build Coastguard Worker     tcu::clear(tcu::getSubregion(errorAccess, 0, 0, width, 1), green);
4051*35238bceSAndroid Build Coastguard Worker     tcu::clear(tcu::getSubregion(errorAccess, 0, height - 1, width, 1), green);
4052*35238bceSAndroid Build Coastguard Worker     tcu::clear(tcu::getSubregion(errorAccess, 0, 0, 1, height), green);
4053*35238bceSAndroid Build Coastguard Worker     tcu::clear(tcu::getSubregion(errorAccess, width - 1, 0, 1, height), green);
4054*35238bceSAndroid Build Coastguard Worker 
4055*35238bceSAndroid Build Coastguard Worker     // skip edge pixels since coverage on edge cannot be verified
4056*35238bceSAndroid Build Coastguard Worker 
4057*35238bceSAndroid Build Coastguard Worker     for (int y = 1; y < height - 1; ++y)
4058*35238bceSAndroid Build Coastguard Worker         for (int x = 1; x < width - 1; ++x)
4059*35238bceSAndroid Build Coastguard Worker         {
4060*35238bceSAndroid Build Coastguard Worker             const tcu::RGBA refPixel    = reference.getPixel(x, y);
4061*35238bceSAndroid Build Coastguard Worker             const tcu::RGBA screenPixel = result.getPixel(x, y);
4062*35238bceSAndroid Build Coastguard Worker             const bool directMatch      = colorsEqual(refPixel, screenPixel, compareThreshold);
4063*35238bceSAndroid Build Coastguard Worker             const bool isOkReferencePixel =
4064*35238bceSAndroid Build Coastguard Worker                 directMatch ||
4065*35238bceSAndroid Build Coastguard Worker                 pixelNeighborhoodContainsColor(
4066*35238bceSAndroid Build Coastguard Worker                     result, x, y, refPixel,
4067*35238bceSAndroid Build Coastguard Worker                     compareThreshold); // screen image has a matching pixel nearby (~= If something is drawn on reference, it must be drawn to screen too.)
4068*35238bceSAndroid Build Coastguard Worker             const bool isOkScreenPixel =
4069*35238bceSAndroid Build Coastguard Worker                 directMatch ||
4070*35238bceSAndroid Build Coastguard Worker                 pixelNeighborhoodContainsColor(
4071*35238bceSAndroid Build Coastguard Worker                     reference, x, y, screenPixel,
4072*35238bceSAndroid Build Coastguard Worker                     compareThreshold); // reference image has a matching pixel nearby (~= If something is drawn on screen, it must be drawn to reference too.)
4073*35238bceSAndroid Build Coastguard Worker 
4074*35238bceSAndroid Build Coastguard Worker             if (isOkScreenPixel && isOkReferencePixel)
4075*35238bceSAndroid Build Coastguard Worker             {
4076*35238bceSAndroid Build Coastguard Worker                 // pixel valid, write greenish pixels to make the result image easier to read
4077*35238bceSAndroid Build Coastguard Worker                 const uint32_t grayscaleValue = getVisualizationGrayscaleColor(screenPixel);
4078*35238bceSAndroid Build Coastguard Worker                 errorAccess.setPixel(tcu::UVec4(grayscaleValue, 255, grayscaleValue, 255), x, y);
4079*35238bceSAndroid Build Coastguard Worker             }
4080*35238bceSAndroid Build Coastguard Worker             else if (!pixelNearEdge(x, y, reference, renderTargetThreshold))
4081*35238bceSAndroid Build Coastguard Worker             {
4082*35238bceSAndroid Build Coastguard Worker                 // non-edge pixel values must be within threshold of the reference values
4083*35238bceSAndroid Build Coastguard Worker                 errorAccess.setPixel(red, x, y);
4084*35238bceSAndroid Build Coastguard Worker                 ++numFailingPixels;
4085*35238bceSAndroid Build Coastguard Worker             }
4086*35238bceSAndroid Build Coastguard Worker             else
4087*35238bceSAndroid Build Coastguard Worker             {
4088*35238bceSAndroid Build Coastguard Worker                 // we are on/near an edge, verify only coverage (coverage == not background colored)
4089*35238bceSAndroid Build Coastguard Worker                 const bool referenceCoverage     = !isBlack(refPixel);
4090*35238bceSAndroid Build Coastguard Worker                 const bool screenCoverage        = !isBlack(screenPixel);
4091*35238bceSAndroid Build Coastguard Worker                 const bool isOkReferenceCoverage = pixelNeighborhoodContainsCoverage(
4092*35238bceSAndroid Build Coastguard Worker                     result, x, y, referenceCoverage); // Check reference pixel against screen pixel
4093*35238bceSAndroid Build Coastguard Worker                 const bool isOkScreenCoverage = pixelNeighborhoodContainsCoverage(
4094*35238bceSAndroid Build Coastguard Worker                     reference, x, y, screenCoverage); // Check screen pixels against reference pixel
4095*35238bceSAndroid Build Coastguard Worker 
4096*35238bceSAndroid Build Coastguard Worker                 if (isOkScreenCoverage && isOkReferenceCoverage)
4097*35238bceSAndroid Build Coastguard Worker                 {
4098*35238bceSAndroid Build Coastguard Worker                     // pixel valid, write greenish pixels to make the result image easier to read
4099*35238bceSAndroid Build Coastguard Worker                     const uint32_t grayscaleValue = getVisualizationGrayscaleColor(screenPixel);
4100*35238bceSAndroid Build Coastguard Worker                     errorAccess.setPixel(tcu::UVec4(grayscaleValue, 255, grayscaleValue, 255), x, y);
4101*35238bceSAndroid Build Coastguard Worker                 }
4102*35238bceSAndroid Build Coastguard Worker                 else
4103*35238bceSAndroid Build Coastguard Worker                 {
4104*35238bceSAndroid Build Coastguard Worker                     // coverage does not match
4105*35238bceSAndroid Build Coastguard Worker                     errorAccess.setPixel(red, x, y);
4106*35238bceSAndroid Build Coastguard Worker                     ++numFailingPixels;
4107*35238bceSAndroid Build Coastguard Worker                 }
4108*35238bceSAndroid Build Coastguard Worker             }
4109*35238bceSAndroid Build Coastguard Worker         }
4110*35238bceSAndroid Build Coastguard Worker 
4111*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message << "Comparing images:\n"
4112*35238bceSAndroid Build Coastguard Worker         << "\tallowed deviation in pixel positions = 1\n"
4113*35238bceSAndroid Build Coastguard Worker         << "\tnumber of allowed invalid pixels = " << maxAllowedInvalidPixels << "\n"
4114*35238bceSAndroid Build Coastguard Worker         << "\tnumber of invalid pixels = " << numFailingPixels << TestLog::EndMessage;
4115*35238bceSAndroid Build Coastguard Worker 
4116*35238bceSAndroid Build Coastguard Worker     if (numFailingPixels > maxAllowedInvalidPixels)
4117*35238bceSAndroid Build Coastguard Worker     {
4118*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "Image comparison failed. Color threshold = (" << compareThreshold.x() << ", "
4119*35238bceSAndroid Build Coastguard Worker             << compareThreshold.y() << ", " << compareThreshold.z() << ")" << TestLog::EndMessage
4120*35238bceSAndroid Build Coastguard Worker             << TestLog::ImageSet(imageSetName, imageSetDesc) << TestLog::Image("Result", "Result", result)
4121*35238bceSAndroid Build Coastguard Worker             << TestLog::Image("Reference", "Reference", reference)
4122*35238bceSAndroid Build Coastguard Worker             << TestLog::Image("ErrorMask", "Error mask", errorMask) << TestLog::EndImageSet;
4123*35238bceSAndroid Build Coastguard Worker 
4124*35238bceSAndroid Build Coastguard Worker         return false;
4125*35238bceSAndroid Build Coastguard Worker     }
4126*35238bceSAndroid Build Coastguard Worker     else
4127*35238bceSAndroid Build Coastguard Worker     {
4128*35238bceSAndroid Build Coastguard Worker         log << TestLog::ImageSet(imageSetName, imageSetDesc) << TestLog::Image("Result", "Result", result)
4129*35238bceSAndroid Build Coastguard Worker             << TestLog::EndImageSet;
4130*35238bceSAndroid Build Coastguard Worker 
4131*35238bceSAndroid Build Coastguard Worker         return true;
4132*35238bceSAndroid Build Coastguard Worker     }
4133*35238bceSAndroid Build Coastguard Worker }
4134*35238bceSAndroid Build Coastguard Worker 
intersectionRelaxedLineImageCompare(tcu::TestLog & log,const char * imageSetName,const char * imageSetDesc,const tcu::Surface & reference,const tcu::Surface & result,const tcu::IVec3 & compareThreshold,int maxAllowedInvalidPixels)4135*35238bceSAndroid Build Coastguard Worker static bool intersectionRelaxedLineImageCompare(tcu::TestLog &log, const char *imageSetName, const char *imageSetDesc,
4136*35238bceSAndroid Build Coastguard Worker                                                 const tcu::Surface &reference, const tcu::Surface &result,
4137*35238bceSAndroid Build Coastguard Worker                                                 const tcu::IVec3 &compareThreshold, int maxAllowedInvalidPixels)
4138*35238bceSAndroid Build Coastguard Worker {
4139*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());
4140*35238bceSAndroid Build Coastguard Worker 
4141*35238bceSAndroid Build Coastguard Worker     const tcu::IVec4 green(0, 255, 0, 255);
4142*35238bceSAndroid Build Coastguard Worker     const tcu::IVec4 red(255, 0, 0, 255);
4143*35238bceSAndroid Build Coastguard Worker     const int width  = reference.getWidth();
4144*35238bceSAndroid Build Coastguard Worker     const int height = reference.getHeight();
4145*35238bceSAndroid Build Coastguard Worker     tcu::TextureLevel errorMask(tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), width,
4146*35238bceSAndroid Build Coastguard Worker                                 height);
4147*35238bceSAndroid Build Coastguard Worker     const tcu::PixelBufferAccess errorAccess = errorMask.getAccess();
4148*35238bceSAndroid Build Coastguard Worker     int numFailingPixels                     = 0;
4149*35238bceSAndroid Build Coastguard Worker 
4150*35238bceSAndroid Build Coastguard Worker     // clear errormask edges which would otherwise be transparent
4151*35238bceSAndroid Build Coastguard Worker 
4152*35238bceSAndroid Build Coastguard Worker     tcu::clear(tcu::getSubregion(errorAccess, 0, 0, width, 1), green);
4153*35238bceSAndroid Build Coastguard Worker     tcu::clear(tcu::getSubregion(errorAccess, 0, height - 1, width, 1), green);
4154*35238bceSAndroid Build Coastguard Worker     tcu::clear(tcu::getSubregion(errorAccess, 0, 0, 1, height), green);
4155*35238bceSAndroid Build Coastguard Worker     tcu::clear(tcu::getSubregion(errorAccess, width - 1, 0, 1, height), green);
4156*35238bceSAndroid Build Coastguard Worker 
4157*35238bceSAndroid Build Coastguard Worker     // skip edge pixels since coverage on edge cannot be verified
4158*35238bceSAndroid Build Coastguard Worker 
4159*35238bceSAndroid Build Coastguard Worker     for (int y = 1; y < height - 1; ++y)
4160*35238bceSAndroid Build Coastguard Worker         for (int x = 1; x < width - 1; ++x)
4161*35238bceSAndroid Build Coastguard Worker         {
4162*35238bceSAndroid Build Coastguard Worker             const tcu::RGBA refPixel    = reference.getPixel(x, y);
4163*35238bceSAndroid Build Coastguard Worker             const tcu::RGBA screenPixel = result.getPixel(x, y);
4164*35238bceSAndroid Build Coastguard Worker             const bool directMatch      = colorsEqual(refPixel, screenPixel, compareThreshold);
4165*35238bceSAndroid Build Coastguard Worker             const bool isOkScreenPixel =
4166*35238bceSAndroid Build Coastguard Worker                 directMatch ||
4167*35238bceSAndroid Build Coastguard Worker                 pixelNeighborhoodContainsColor(
4168*35238bceSAndroid Build Coastguard Worker                     reference, x, y, screenPixel,
4169*35238bceSAndroid Build Coastguard Worker                     compareThreshold); // reference image has a matching pixel nearby (~= If something is drawn on screen, it must be drawn to reference too.)
4170*35238bceSAndroid Build Coastguard Worker             const bool isOkReferencePixel =
4171*35238bceSAndroid Build Coastguard Worker                 directMatch ||
4172*35238bceSAndroid Build Coastguard Worker                 pixelNeighborhoodContainsColor(
4173*35238bceSAndroid Build Coastguard Worker                     result, x, y, refPixel,
4174*35238bceSAndroid Build Coastguard Worker                     compareThreshold); // screen image has a matching pixel nearby (~= If something is drawn on reference, it must be drawn to screen too.)
4175*35238bceSAndroid Build Coastguard Worker 
4176*35238bceSAndroid Build Coastguard Worker             if (isOkScreenPixel && isOkReferencePixel)
4177*35238bceSAndroid Build Coastguard Worker             {
4178*35238bceSAndroid Build Coastguard Worker                 // pixel valid, write greenish pixels to make the result image easier to read
4179*35238bceSAndroid Build Coastguard Worker                 const uint32_t grayscaleValue = getVisualizationGrayscaleColor(screenPixel);
4180*35238bceSAndroid Build Coastguard Worker                 errorAccess.setPixel(tcu::UVec4(grayscaleValue, 255, grayscaleValue, 255), x, y);
4181*35238bceSAndroid Build Coastguard Worker             }
4182*35238bceSAndroid Build Coastguard Worker             else if (!pixelNearLineIntersection(x, y, reference) && !pixelNearLineIntersection(x, y, result))
4183*35238bceSAndroid Build Coastguard Worker             {
4184*35238bceSAndroid Build Coastguard Worker                 // non-intersection pixel values must be within threshold of the reference values
4185*35238bceSAndroid Build Coastguard Worker                 errorAccess.setPixel(red, x, y);
4186*35238bceSAndroid Build Coastguard Worker                 ++numFailingPixels;
4187*35238bceSAndroid Build Coastguard Worker             }
4188*35238bceSAndroid Build Coastguard Worker             else
4189*35238bceSAndroid Build Coastguard Worker             {
4190*35238bceSAndroid Build Coastguard Worker                 // pixel is near a line intersection
4191*35238bceSAndroid Build Coastguard Worker                 // we are on/near an edge, verify only coverage (coverage == not background colored)
4192*35238bceSAndroid Build Coastguard Worker                 const bool referenceCoverage  = !isBlack(refPixel);
4193*35238bceSAndroid Build Coastguard Worker                 const bool screenCoverage     = !isBlack(screenPixel);
4194*35238bceSAndroid Build Coastguard Worker                 const bool isOkScreenCoverage = pixelNeighborhoodContainsCoverage(
4195*35238bceSAndroid Build Coastguard Worker                     reference, x, y, screenCoverage); // Check screen pixels against reference pixel
4196*35238bceSAndroid Build Coastguard Worker                 const bool isOkReferenceCoverage = pixelNeighborhoodContainsCoverage(
4197*35238bceSAndroid Build Coastguard Worker                     result, x, y, referenceCoverage); // Check reference pixel against screen pixel
4198*35238bceSAndroid Build Coastguard Worker 
4199*35238bceSAndroid Build Coastguard Worker                 if (isOkScreenCoverage && isOkReferenceCoverage)
4200*35238bceSAndroid Build Coastguard Worker                 {
4201*35238bceSAndroid Build Coastguard Worker                     // pixel valid, write greenish pixels to make the result image easier to read
4202*35238bceSAndroid Build Coastguard Worker                     const uint32_t grayscaleValue = getVisualizationGrayscaleColor(screenPixel);
4203*35238bceSAndroid Build Coastguard Worker                     errorAccess.setPixel(tcu::UVec4(grayscaleValue, 255, grayscaleValue, 255), x, y);
4204*35238bceSAndroid Build Coastguard Worker                 }
4205*35238bceSAndroid Build Coastguard Worker                 else
4206*35238bceSAndroid Build Coastguard Worker                 {
4207*35238bceSAndroid Build Coastguard Worker                     // coverage does not match
4208*35238bceSAndroid Build Coastguard Worker                     errorAccess.setPixel(red, x, y);
4209*35238bceSAndroid Build Coastguard Worker                     ++numFailingPixels;
4210*35238bceSAndroid Build Coastguard Worker                 }
4211*35238bceSAndroid Build Coastguard Worker             }
4212*35238bceSAndroid Build Coastguard Worker         }
4213*35238bceSAndroid Build Coastguard Worker 
4214*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message << "Comparing images:\n"
4215*35238bceSAndroid Build Coastguard Worker         << "\tallowed deviation in pixel positions = 1\n"
4216*35238bceSAndroid Build Coastguard Worker         << "\tnumber of allowed invalid pixels = " << maxAllowedInvalidPixels << "\n"
4217*35238bceSAndroid Build Coastguard Worker         << "\tnumber of invalid pixels = " << numFailingPixels << TestLog::EndMessage;
4218*35238bceSAndroid Build Coastguard Worker 
4219*35238bceSAndroid Build Coastguard Worker     if (numFailingPixels > maxAllowedInvalidPixels)
4220*35238bceSAndroid Build Coastguard Worker     {
4221*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "Image comparison failed. Color threshold = (" << compareThreshold.x() << ", "
4222*35238bceSAndroid Build Coastguard Worker             << compareThreshold.y() << ", " << compareThreshold.z() << ")" << TestLog::EndMessage
4223*35238bceSAndroid Build Coastguard Worker             << TestLog::ImageSet(imageSetName, imageSetDesc) << TestLog::Image("Result", "Result", result)
4224*35238bceSAndroid Build Coastguard Worker             << TestLog::Image("Reference", "Reference", reference)
4225*35238bceSAndroid Build Coastguard Worker             << TestLog::Image("ErrorMask", "Error mask", errorMask) << TestLog::EndImageSet;
4226*35238bceSAndroid Build Coastguard Worker 
4227*35238bceSAndroid Build Coastguard Worker         return false;
4228*35238bceSAndroid Build Coastguard Worker     }
4229*35238bceSAndroid Build Coastguard Worker     else
4230*35238bceSAndroid Build Coastguard Worker     {
4231*35238bceSAndroid Build Coastguard Worker         log << TestLog::ImageSet(imageSetName, imageSetDesc) << TestLog::Image("Result", "Result", result)
4232*35238bceSAndroid Build Coastguard Worker             << TestLog::EndImageSet;
4233*35238bceSAndroid Build Coastguard Worker 
4234*35238bceSAndroid Build Coastguard Worker         return true;
4235*35238bceSAndroid Build Coastguard Worker     }
4236*35238bceSAndroid Build Coastguard Worker }
4237*35238bceSAndroid Build Coastguard Worker 
compare(gls::DrawTestSpec::Primitive primitiveType)4238*35238bceSAndroid Build Coastguard Worker bool DrawTest::compare(gls::DrawTestSpec::Primitive primitiveType)
4239*35238bceSAndroid Build Coastguard Worker {
4240*35238bceSAndroid Build Coastguard Worker     const tcu::Surface &ref    = m_rrArrayPack->getSurface();
4241*35238bceSAndroid Build Coastguard Worker     const tcu::Surface &screen = m_glArrayPack->getSurface();
4242*35238bceSAndroid Build Coastguard Worker 
4243*35238bceSAndroid Build Coastguard Worker     if (m_renderCtx.getRenderTarget().getNumSamples() > 1)
4244*35238bceSAndroid Build Coastguard Worker     {
4245*35238bceSAndroid Build Coastguard Worker         // \todo [mika] Improve compare when using multisampling
4246*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message
4247*35238bceSAndroid Build Coastguard Worker                            << "Warning: Comparision of result from multisample render targets are not as stricts as "
4248*35238bceSAndroid Build Coastguard Worker                               "without multisampling. Might produce false positives!"
4249*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
4250*35238bceSAndroid Build Coastguard Worker         return tcu::fuzzyCompare(m_testCtx.getLog(), "Compare Results", "Compare Results", ref.getAccess(),
4251*35238bceSAndroid Build Coastguard Worker                                  screen.getAccess(), 0.3f, tcu::COMPARE_LOG_RESULT);
4252*35238bceSAndroid Build Coastguard Worker     }
4253*35238bceSAndroid Build Coastguard Worker     else
4254*35238bceSAndroid Build Coastguard Worker     {
4255*35238bceSAndroid Build Coastguard Worker         const PrimitiveClass primitiveClass            = getDrawPrimitiveClass(primitiveType);
4256*35238bceSAndroid Build Coastguard Worker         const int maxAllowedInvalidPixelsWithPoints    = 0; //!< points are unlikely to have overlapping fragments
4257*35238bceSAndroid Build Coastguard Worker         const int maxAllowedInvalidPixelsWithLines     = 5; //!< line are allowed to have a few bad pixels
4258*35238bceSAndroid Build Coastguard Worker         const int maxAllowedInvalidPixelsWithTriangles = 10;
4259*35238bceSAndroid Build Coastguard Worker 
4260*35238bceSAndroid Build Coastguard Worker         switch (primitiveClass)
4261*35238bceSAndroid Build Coastguard Worker         {
4262*35238bceSAndroid Build Coastguard Worker         case PRIMITIVECLASS_POINT:
4263*35238bceSAndroid Build Coastguard Worker         {
4264*35238bceSAndroid Build Coastguard Worker             // Point are extremely unlikely to have overlapping regions, don't allow any no extra / missing pixels
4265*35238bceSAndroid Build Coastguard Worker             return tcu::intThresholdPositionDeviationErrorThresholdCompare(
4266*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog(), "CompareResult", "Result of rendering", ref.getAccess(), screen.getAccess(),
4267*35238bceSAndroid Build Coastguard Worker                 tcu::UVec4(m_maxDiffRed, m_maxDiffGreen, m_maxDiffBlue, 256),
4268*35238bceSAndroid Build Coastguard Worker                 tcu::IVec3(1, 1, 0),               //!< 3x3 search kernel
4269*35238bceSAndroid Build Coastguard Worker                 true,                              //!< relax comparison on the image boundary
4270*35238bceSAndroid Build Coastguard Worker                 maxAllowedInvalidPixelsWithPoints, //!< error threshold
4271*35238bceSAndroid Build Coastguard Worker                 tcu::COMPARE_LOG_RESULT);
4272*35238bceSAndroid Build Coastguard Worker         }
4273*35238bceSAndroid Build Coastguard Worker 
4274*35238bceSAndroid Build Coastguard Worker         case PRIMITIVECLASS_LINE:
4275*35238bceSAndroid Build Coastguard Worker         {
4276*35238bceSAndroid Build Coastguard Worker             // Lines can potentially have a large number of overlapping pixels. Pixel comparison may potentially produce
4277*35238bceSAndroid Build Coastguard Worker             // false negatives in such pixels if for example the pixel in question is overdrawn by another line in the
4278*35238bceSAndroid Build Coastguard Worker             // reference image but not in the resultin image. Relax comparison near line intersection points (areas) and
4279*35238bceSAndroid Build Coastguard Worker             // compare only coverage, not color, in such pixels
4280*35238bceSAndroid Build Coastguard Worker             return intersectionRelaxedLineImageCompare(m_testCtx.getLog(), "CompareResult", "Result of rendering", ref,
4281*35238bceSAndroid Build Coastguard Worker                                                        screen, tcu::IVec3(m_maxDiffRed, m_maxDiffGreen, m_maxDiffBlue),
4282*35238bceSAndroid Build Coastguard Worker                                                        maxAllowedInvalidPixelsWithLines);
4283*35238bceSAndroid Build Coastguard Worker         }
4284*35238bceSAndroid Build Coastguard Worker 
4285*35238bceSAndroid Build Coastguard Worker         case PRIMITIVECLASS_TRIANGLE:
4286*35238bceSAndroid Build Coastguard Worker         {
4287*35238bceSAndroid Build Coastguard Worker             // Triangles are likely to partially or fully overlap. Pixel difference comparison is fragile in pixels
4288*35238bceSAndroid Build Coastguard Worker             // where there could be potential overlapping since the  pixels might be covered by one triangle in the
4289*35238bceSAndroid Build Coastguard Worker             // reference image and by the other in the result image. Relax comparsion near primitive edges and
4290*35238bceSAndroid Build Coastguard Worker             // compare only coverage, not color, in such pixels.
4291*35238bceSAndroid Build Coastguard Worker             const tcu::IVec3 renderTargetThreshold =
4292*35238bceSAndroid Build Coastguard Worker                 m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold().toIVec().xyz();
4293*35238bceSAndroid Build Coastguard Worker 
4294*35238bceSAndroid Build Coastguard Worker             return edgeRelaxedImageCompare(m_testCtx.getLog(), "CompareResult", "Result of rendering", ref, screen,
4295*35238bceSAndroid Build Coastguard Worker                                            tcu::IVec3(m_maxDiffRed, m_maxDiffGreen, m_maxDiffBlue),
4296*35238bceSAndroid Build Coastguard Worker                                            renderTargetThreshold, maxAllowedInvalidPixelsWithTriangles);
4297*35238bceSAndroid Build Coastguard Worker         }
4298*35238bceSAndroid Build Coastguard Worker 
4299*35238bceSAndroid Build Coastguard Worker         default:
4300*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
4301*35238bceSAndroid Build Coastguard Worker             return false;
4302*35238bceSAndroid Build Coastguard Worker         }
4303*35238bceSAndroid Build Coastguard Worker     }
4304*35238bceSAndroid Build Coastguard Worker }
4305*35238bceSAndroid Build Coastguard Worker 
getCoordScale(const DrawTestSpec & spec) const4306*35238bceSAndroid Build Coastguard Worker float DrawTest::getCoordScale(const DrawTestSpec &spec) const
4307*35238bceSAndroid Build Coastguard Worker {
4308*35238bceSAndroid Build Coastguard Worker     float maxValue = 1.0f;
4309*35238bceSAndroid Build Coastguard Worker 
4310*35238bceSAndroid Build Coastguard Worker     for (int arrayNdx = 0; arrayNdx < (int)spec.attribs.size(); arrayNdx++)
4311*35238bceSAndroid Build Coastguard Worker     {
4312*35238bceSAndroid Build Coastguard Worker         DrawTestSpec::AttributeSpec attribSpec = spec.attribs[arrayNdx];
4313*35238bceSAndroid Build Coastguard Worker         const bool isPositionAttr              = (arrayNdx == 0) || (attribSpec.additionalPositionAttribute);
4314*35238bceSAndroid Build Coastguard Worker         float attrMaxValue                     = 0;
4315*35238bceSAndroid Build Coastguard Worker 
4316*35238bceSAndroid Build Coastguard Worker         if (!isPositionAttr)
4317*35238bceSAndroid Build Coastguard Worker             continue;
4318*35238bceSAndroid Build Coastguard Worker 
4319*35238bceSAndroid Build Coastguard Worker         if (attribSpec.inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10)
4320*35238bceSAndroid Build Coastguard Worker         {
4321*35238bceSAndroid Build Coastguard Worker             if (attribSpec.normalize)
4322*35238bceSAndroid Build Coastguard Worker                 attrMaxValue += 1.0f;
4323*35238bceSAndroid Build Coastguard Worker             else
4324*35238bceSAndroid Build Coastguard Worker                 attrMaxValue += 1024.0f;
4325*35238bceSAndroid Build Coastguard Worker         }
4326*35238bceSAndroid Build Coastguard Worker         else if (attribSpec.inputType == DrawTestSpec::INPUTTYPE_INT_2_10_10_10)
4327*35238bceSAndroid Build Coastguard Worker         {
4328*35238bceSAndroid Build Coastguard Worker             if (attribSpec.normalize)
4329*35238bceSAndroid Build Coastguard Worker                 attrMaxValue += 1.0f;
4330*35238bceSAndroid Build Coastguard Worker             else
4331*35238bceSAndroid Build Coastguard Worker                 attrMaxValue += 512.0f;
4332*35238bceSAndroid Build Coastguard Worker         }
4333*35238bceSAndroid Build Coastguard Worker         else
4334*35238bceSAndroid Build Coastguard Worker         {
4335*35238bceSAndroid Build Coastguard Worker             const float max = GLValue::getMaxValue(attribSpec.inputType).toFloat();
4336*35238bceSAndroid Build Coastguard Worker 
4337*35238bceSAndroid Build Coastguard Worker             attrMaxValue +=
4338*35238bceSAndroid Build Coastguard Worker                 (attribSpec.normalize && !inputTypeIsFloatType(attribSpec.inputType)) ? (1.0f) : (max * 1.1f);
4339*35238bceSAndroid Build Coastguard Worker         }
4340*35238bceSAndroid Build Coastguard Worker 
4341*35238bceSAndroid Build Coastguard Worker         if (attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_VEC3 ||
4342*35238bceSAndroid Build Coastguard Worker             attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_VEC4 ||
4343*35238bceSAndroid Build Coastguard Worker             attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_IVEC3 ||
4344*35238bceSAndroid Build Coastguard Worker             attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_IVEC4 ||
4345*35238bceSAndroid Build Coastguard Worker             attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_UVEC3 ||
4346*35238bceSAndroid Build Coastguard Worker             attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_UVEC4)
4347*35238bceSAndroid Build Coastguard Worker             attrMaxValue *= 2;
4348*35238bceSAndroid Build Coastguard Worker 
4349*35238bceSAndroid Build Coastguard Worker         maxValue += attrMaxValue;
4350*35238bceSAndroid Build Coastguard Worker     }
4351*35238bceSAndroid Build Coastguard Worker 
4352*35238bceSAndroid Build Coastguard Worker     return 1.0f / maxValue;
4353*35238bceSAndroid Build Coastguard Worker }
4354*35238bceSAndroid Build Coastguard Worker 
getColorScale(const DrawTestSpec & spec) const4355*35238bceSAndroid Build Coastguard Worker float DrawTest::getColorScale(const DrawTestSpec &spec) const
4356*35238bceSAndroid Build Coastguard Worker {
4357*35238bceSAndroid Build Coastguard Worker     float colorScale = 1.0f;
4358*35238bceSAndroid Build Coastguard Worker 
4359*35238bceSAndroid Build Coastguard Worker     for (int arrayNdx = 1; arrayNdx < (int)spec.attribs.size(); arrayNdx++)
4360*35238bceSAndroid Build Coastguard Worker     {
4361*35238bceSAndroid Build Coastguard Worker         DrawTestSpec::AttributeSpec attribSpec = spec.attribs[arrayNdx];
4362*35238bceSAndroid Build Coastguard Worker         const bool isPositionAttr              = (arrayNdx == 0) || (attribSpec.additionalPositionAttribute);
4363*35238bceSAndroid Build Coastguard Worker 
4364*35238bceSAndroid Build Coastguard Worker         if (isPositionAttr)
4365*35238bceSAndroid Build Coastguard Worker             continue;
4366*35238bceSAndroid Build Coastguard Worker 
4367*35238bceSAndroid Build Coastguard Worker         if (attribSpec.inputType == DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10)
4368*35238bceSAndroid Build Coastguard Worker         {
4369*35238bceSAndroid Build Coastguard Worker             if (!attribSpec.normalize)
4370*35238bceSAndroid Build Coastguard Worker                 colorScale *= 1.0f / 1024.0f;
4371*35238bceSAndroid Build Coastguard Worker         }
4372*35238bceSAndroid Build Coastguard Worker         else if (attribSpec.inputType == DrawTestSpec::INPUTTYPE_INT_2_10_10_10)
4373*35238bceSAndroid Build Coastguard Worker         {
4374*35238bceSAndroid Build Coastguard Worker             if (!attribSpec.normalize)
4375*35238bceSAndroid Build Coastguard Worker                 colorScale *= 1.0f / 512.0f;
4376*35238bceSAndroid Build Coastguard Worker         }
4377*35238bceSAndroid Build Coastguard Worker         else
4378*35238bceSAndroid Build Coastguard Worker         {
4379*35238bceSAndroid Build Coastguard Worker             const float max = GLValue::getMaxValue(attribSpec.inputType).toFloat();
4380*35238bceSAndroid Build Coastguard Worker 
4381*35238bceSAndroid Build Coastguard Worker             colorScale *=
4382*35238bceSAndroid Build Coastguard Worker                 (attribSpec.normalize && !inputTypeIsFloatType(attribSpec.inputType) ? 1.0f : float(1.0 / double(max)));
4383*35238bceSAndroid Build Coastguard Worker             if (attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_VEC4 ||
4384*35238bceSAndroid Build Coastguard Worker                 attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_UVEC4 ||
4385*35238bceSAndroid Build Coastguard Worker                 attribSpec.outputType == DrawTestSpec::OUTPUTTYPE_IVEC4)
4386*35238bceSAndroid Build Coastguard Worker                 colorScale *=
4387*35238bceSAndroid Build Coastguard Worker                     (attribSpec.normalize && !inputTypeIsFloatType(attribSpec.inputType) ? 1.0f :
4388*35238bceSAndroid Build Coastguard Worker                                                                                            float(1.0 / double(max)));
4389*35238bceSAndroid Build Coastguard Worker         }
4390*35238bceSAndroid Build Coastguard Worker     }
4391*35238bceSAndroid Build Coastguard Worker 
4392*35238bceSAndroid Build Coastguard Worker     return colorScale;
4393*35238bceSAndroid Build Coastguard Worker }
4394*35238bceSAndroid Build Coastguard Worker 
4395*35238bceSAndroid Build Coastguard Worker } // namespace gls
4396*35238bceSAndroid Build Coastguard Worker } // namespace deqp
4397