xref: /aosp_15_r20/external/deqp/external/openglcts/modules/common/glcShaderLibraryCase.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * OpenGL Conformance Test Suite
3*35238bceSAndroid Build Coastguard Worker  * -----------------------------
4*35238bceSAndroid Build Coastguard Worker  *
5*35238bceSAndroid Build Coastguard Worker  * Copyright (c) 2016 Google Inc.
6*35238bceSAndroid Build Coastguard Worker  * Copyright (c) 2016 The Khronos Group Inc.
7*35238bceSAndroid Build Coastguard Worker  *
8*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
9*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
10*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
11*35238bceSAndroid Build Coastguard Worker  *
12*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
13*35238bceSAndroid Build Coastguard Worker  *
14*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
15*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
16*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
18*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
19*35238bceSAndroid Build Coastguard Worker  *
20*35238bceSAndroid Build Coastguard Worker  */ /*!
21*35238bceSAndroid Build Coastguard Worker  * \file
22*35238bceSAndroid Build Coastguard Worker  * \brief Compiler test case.
23*35238bceSAndroid Build Coastguard Worker  */ /*-------------------------------------------------------------------*/
24*35238bceSAndroid Build Coastguard Worker 
25*35238bceSAndroid Build Coastguard Worker #include "glcShaderLibraryCase.hpp"
26*35238bceSAndroid Build Coastguard Worker 
27*35238bceSAndroid Build Coastguard Worker #include "tcuRenderTarget.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
29*35238bceSAndroid Build Coastguard Worker 
30*35238bceSAndroid Build Coastguard Worker #include "gluDrawUtil.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "gluPixelTransfer.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "gluShaderProgram.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "tcuStringTemplate.hpp"
34*35238bceSAndroid Build Coastguard Worker 
35*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
36*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
37*35238bceSAndroid Build Coastguard Worker 
38*35238bceSAndroid Build Coastguard Worker #include "deInt32.h"
39*35238bceSAndroid Build Coastguard Worker #include "deMath.h"
40*35238bceSAndroid Build Coastguard Worker #include "deRandom.hpp"
41*35238bceSAndroid Build Coastguard Worker #include "deString.h"
42*35238bceSAndroid Build Coastguard Worker 
43*35238bceSAndroid Build Coastguard Worker #include <map>
44*35238bceSAndroid Build Coastguard Worker #include <sstream>
45*35238bceSAndroid Build Coastguard Worker #include <string>
46*35238bceSAndroid Build Coastguard Worker #include <vector>
47*35238bceSAndroid Build Coastguard Worker 
48*35238bceSAndroid Build Coastguard Worker using namespace std;
49*35238bceSAndroid Build Coastguard Worker using namespace tcu;
50*35238bceSAndroid Build Coastguard Worker using namespace glu;
51*35238bceSAndroid Build Coastguard Worker 
52*35238bceSAndroid Build Coastguard Worker namespace deqp
53*35238bceSAndroid Build Coastguard Worker {
54*35238bceSAndroid Build Coastguard Worker namespace sl
55*35238bceSAndroid Build Coastguard Worker {
56*35238bceSAndroid Build Coastguard Worker 
57*35238bceSAndroid Build Coastguard Worker enum
58*35238bceSAndroid Build Coastguard Worker {
59*35238bceSAndroid Build Coastguard Worker     VIEWPORT_WIDTH  = 128,
60*35238bceSAndroid Build Coastguard Worker     VIEWPORT_HEIGHT = 128
61*35238bceSAndroid Build Coastguard Worker };
62*35238bceSAndroid Build Coastguard Worker 
usesShaderInoutQualifiers(glu::GLSLVersion version)63*35238bceSAndroid Build Coastguard Worker static inline bool usesShaderInoutQualifiers(glu::GLSLVersion version)
64*35238bceSAndroid Build Coastguard Worker {
65*35238bceSAndroid Build Coastguard Worker     switch (version)
66*35238bceSAndroid Build Coastguard Worker     {
67*35238bceSAndroid Build Coastguard Worker     case glu::GLSL_VERSION_100_ES:
68*35238bceSAndroid Build Coastguard Worker     case glu::GLSL_VERSION_130:
69*35238bceSAndroid Build Coastguard Worker     case glu::GLSL_VERSION_140:
70*35238bceSAndroid Build Coastguard Worker     case glu::GLSL_VERSION_150:
71*35238bceSAndroid Build Coastguard Worker         return false;
72*35238bceSAndroid Build Coastguard Worker 
73*35238bceSAndroid Build Coastguard Worker     default:
74*35238bceSAndroid Build Coastguard Worker         return true;
75*35238bceSAndroid Build Coastguard Worker     }
76*35238bceSAndroid Build Coastguard Worker }
77*35238bceSAndroid Build Coastguard Worker 
78*35238bceSAndroid Build Coastguard Worker // ShaderCase.
79*35238bceSAndroid Build Coastguard Worker 
ShaderCase(tcu::TestContext & testCtx,RenderContext & renderCtx,const char * name,const char * description,ExpectResult expectResult,const std::vector<ValueBlock> & valueBlocks,GLSLVersion targetVersion,const char * vertexSource,const char * fragmentSource)80*35238bceSAndroid Build Coastguard Worker ShaderCase::ShaderCase(tcu::TestContext &testCtx, RenderContext &renderCtx, const char *name, const char *description,
81*35238bceSAndroid Build Coastguard Worker                        ExpectResult expectResult, const std::vector<ValueBlock> &valueBlocks, GLSLVersion targetVersion,
82*35238bceSAndroid Build Coastguard Worker                        const char *vertexSource, const char *fragmentSource)
83*35238bceSAndroid Build Coastguard Worker     : tcu::TestCase(testCtx, name, description)
84*35238bceSAndroid Build Coastguard Worker     , m_renderCtx(renderCtx)
85*35238bceSAndroid Build Coastguard Worker     , m_expectResult(expectResult)
86*35238bceSAndroid Build Coastguard Worker     , m_valueBlocks(valueBlocks)
87*35238bceSAndroid Build Coastguard Worker     , m_targetVersion(targetVersion)
88*35238bceSAndroid Build Coastguard Worker {
89*35238bceSAndroid Build Coastguard Worker     // If no value blocks given, use an empty one.
90*35238bceSAndroid Build Coastguard Worker     if (m_valueBlocks.size() == 0)
91*35238bceSAndroid Build Coastguard Worker         m_valueBlocks.push_back(ValueBlock());
92*35238bceSAndroid Build Coastguard Worker 
93*35238bceSAndroid Build Coastguard Worker     // Use first value block to specialize shaders.
94*35238bceSAndroid Build Coastguard Worker     const ValueBlock &valueBlock = m_valueBlocks[0];
95*35238bceSAndroid Build Coastguard Worker 
96*35238bceSAndroid Build Coastguard Worker     // \todo [2010-04-01 petri] Check that all value blocks have matching values.
97*35238bceSAndroid Build Coastguard Worker 
98*35238bceSAndroid Build Coastguard Worker     // Generate specialized shader sources.
99*35238bceSAndroid Build Coastguard Worker     if (vertexSource && fragmentSource)
100*35238bceSAndroid Build Coastguard Worker     {
101*35238bceSAndroid Build Coastguard Worker         m_caseType = CASETYPE_COMPLETE;
102*35238bceSAndroid Build Coastguard Worker         specializeShaders(vertexSource, fragmentSource, m_vertexSource, m_fragmentSource, valueBlock);
103*35238bceSAndroid Build Coastguard Worker     }
104*35238bceSAndroid Build Coastguard Worker     else if (vertexSource)
105*35238bceSAndroid Build Coastguard Worker     {
106*35238bceSAndroid Build Coastguard Worker         m_caseType       = CASETYPE_VERTEX_ONLY;
107*35238bceSAndroid Build Coastguard Worker         m_vertexSource   = specializeVertexShader(vertexSource, valueBlock);
108*35238bceSAndroid Build Coastguard Worker         m_fragmentSource = genFragmentShader(valueBlock);
109*35238bceSAndroid Build Coastguard Worker     }
110*35238bceSAndroid Build Coastguard Worker     else
111*35238bceSAndroid Build Coastguard Worker     {
112*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(fragmentSource);
113*35238bceSAndroid Build Coastguard Worker         m_caseType       = CASETYPE_FRAGMENT_ONLY;
114*35238bceSAndroid Build Coastguard Worker         m_vertexSource   = genVertexShader(valueBlock);
115*35238bceSAndroid Build Coastguard Worker         m_fragmentSource = specializeFragmentShader(fragmentSource, valueBlock);
116*35238bceSAndroid Build Coastguard Worker     }
117*35238bceSAndroid Build Coastguard Worker }
118*35238bceSAndroid Build Coastguard Worker 
~ShaderCase(void)119*35238bceSAndroid Build Coastguard Worker ShaderCase::~ShaderCase(void)
120*35238bceSAndroid Build Coastguard Worker {
121*35238bceSAndroid Build Coastguard Worker }
122*35238bceSAndroid Build Coastguard Worker 
setUniformValue(const glw::Functions & gl,uint32_t programID,const std::string & name,const ShaderCase::Value & val,int arrayNdx)123*35238bceSAndroid Build Coastguard Worker static void setUniformValue(const glw::Functions &gl, uint32_t programID, const std::string &name,
124*35238bceSAndroid Build Coastguard Worker                             const ShaderCase::Value &val, int arrayNdx)
125*35238bceSAndroid Build Coastguard Worker {
126*35238bceSAndroid Build Coastguard Worker     int scalarSize = getDataTypeScalarSize(val.dataType);
127*35238bceSAndroid Build Coastguard Worker     int loc        = gl.getUniformLocation(programID, name.c_str());
128*35238bceSAndroid Build Coastguard Worker 
129*35238bceSAndroid Build Coastguard Worker     TCU_CHECK_MSG(loc != -1, "uniform location not found");
130*35238bceSAndroid Build Coastguard Worker 
131*35238bceSAndroid Build Coastguard Worker     DE_STATIC_ASSERT(sizeof(ShaderCase::Value::Element) == sizeof(glw::GLfloat));
132*35238bceSAndroid Build Coastguard Worker     DE_STATIC_ASSERT(sizeof(ShaderCase::Value::Element) == sizeof(glw::GLint));
133*35238bceSAndroid Build Coastguard Worker 
134*35238bceSAndroid Build Coastguard Worker     int elemNdx = (val.arrayLength == 1) ? 0 : (arrayNdx * scalarSize);
135*35238bceSAndroid Build Coastguard Worker 
136*35238bceSAndroid Build Coastguard Worker     switch (val.dataType)
137*35238bceSAndroid Build Coastguard Worker     {
138*35238bceSAndroid Build Coastguard Worker     case TYPE_FLOAT:
139*35238bceSAndroid Build Coastguard Worker         gl.uniform1fv(loc, 1, &val.elements[elemNdx].float32);
140*35238bceSAndroid Build Coastguard Worker         break;
141*35238bceSAndroid Build Coastguard Worker     case TYPE_FLOAT_VEC2:
142*35238bceSAndroid Build Coastguard Worker         gl.uniform2fv(loc, 1, &val.elements[elemNdx].float32);
143*35238bceSAndroid Build Coastguard Worker         break;
144*35238bceSAndroid Build Coastguard Worker     case TYPE_FLOAT_VEC3:
145*35238bceSAndroid Build Coastguard Worker         gl.uniform3fv(loc, 1, &val.elements[elemNdx].float32);
146*35238bceSAndroid Build Coastguard Worker         break;
147*35238bceSAndroid Build Coastguard Worker     case TYPE_FLOAT_VEC4:
148*35238bceSAndroid Build Coastguard Worker         gl.uniform4fv(loc, 1, &val.elements[elemNdx].float32);
149*35238bceSAndroid Build Coastguard Worker         break;
150*35238bceSAndroid Build Coastguard Worker     case TYPE_FLOAT_MAT2:
151*35238bceSAndroid Build Coastguard Worker         gl.uniformMatrix2fv(loc, 1, GL_FALSE, &val.elements[elemNdx].float32);
152*35238bceSAndroid Build Coastguard Worker         break;
153*35238bceSAndroid Build Coastguard Worker     case TYPE_FLOAT_MAT3:
154*35238bceSAndroid Build Coastguard Worker         gl.uniformMatrix3fv(loc, 1, GL_FALSE, &val.elements[elemNdx].float32);
155*35238bceSAndroid Build Coastguard Worker         break;
156*35238bceSAndroid Build Coastguard Worker     case TYPE_FLOAT_MAT4:
157*35238bceSAndroid Build Coastguard Worker         gl.uniformMatrix4fv(loc, 1, GL_FALSE, &val.elements[elemNdx].float32);
158*35238bceSAndroid Build Coastguard Worker         break;
159*35238bceSAndroid Build Coastguard Worker     case TYPE_INT:
160*35238bceSAndroid Build Coastguard Worker         gl.uniform1iv(loc, 1, &val.elements[elemNdx].int32);
161*35238bceSAndroid Build Coastguard Worker         break;
162*35238bceSAndroid Build Coastguard Worker     case TYPE_INT_VEC2:
163*35238bceSAndroid Build Coastguard Worker         gl.uniform2iv(loc, 1, &val.elements[elemNdx].int32);
164*35238bceSAndroid Build Coastguard Worker         break;
165*35238bceSAndroid Build Coastguard Worker     case TYPE_INT_VEC3:
166*35238bceSAndroid Build Coastguard Worker         gl.uniform3iv(loc, 1, &val.elements[elemNdx].int32);
167*35238bceSAndroid Build Coastguard Worker         break;
168*35238bceSAndroid Build Coastguard Worker     case TYPE_INT_VEC4:
169*35238bceSAndroid Build Coastguard Worker         gl.uniform4iv(loc, 1, &val.elements[elemNdx].int32);
170*35238bceSAndroid Build Coastguard Worker         break;
171*35238bceSAndroid Build Coastguard Worker     case TYPE_BOOL:
172*35238bceSAndroid Build Coastguard Worker         gl.uniform1iv(loc, 1, &val.elements[elemNdx].int32);
173*35238bceSAndroid Build Coastguard Worker         break;
174*35238bceSAndroid Build Coastguard Worker     case TYPE_BOOL_VEC2:
175*35238bceSAndroid Build Coastguard Worker         gl.uniform2iv(loc, 1, &val.elements[elemNdx].int32);
176*35238bceSAndroid Build Coastguard Worker         break;
177*35238bceSAndroid Build Coastguard Worker     case TYPE_BOOL_VEC3:
178*35238bceSAndroid Build Coastguard Worker         gl.uniform3iv(loc, 1, &val.elements[elemNdx].int32);
179*35238bceSAndroid Build Coastguard Worker         break;
180*35238bceSAndroid Build Coastguard Worker     case TYPE_BOOL_VEC4:
181*35238bceSAndroid Build Coastguard Worker         gl.uniform4iv(loc, 1, &val.elements[elemNdx].int32);
182*35238bceSAndroid Build Coastguard Worker         break;
183*35238bceSAndroid Build Coastguard Worker     case TYPE_UINT:
184*35238bceSAndroid Build Coastguard Worker         gl.uniform1uiv(loc, 1, (const uint32_t *)&val.elements[elemNdx].int32);
185*35238bceSAndroid Build Coastguard Worker         break;
186*35238bceSAndroid Build Coastguard Worker     case TYPE_UINT_VEC2:
187*35238bceSAndroid Build Coastguard Worker         gl.uniform2uiv(loc, 1, (const uint32_t *)&val.elements[elemNdx].int32);
188*35238bceSAndroid Build Coastguard Worker         break;
189*35238bceSAndroid Build Coastguard Worker     case TYPE_UINT_VEC3:
190*35238bceSAndroid Build Coastguard Worker         gl.uniform3uiv(loc, 1, (const uint32_t *)&val.elements[elemNdx].int32);
191*35238bceSAndroid Build Coastguard Worker         break;
192*35238bceSAndroid Build Coastguard Worker     case TYPE_UINT_VEC4:
193*35238bceSAndroid Build Coastguard Worker         gl.uniform4uiv(loc, 1, (const uint32_t *)&val.elements[elemNdx].int32);
194*35238bceSAndroid Build Coastguard Worker         break;
195*35238bceSAndroid Build Coastguard Worker     case TYPE_FLOAT_MAT2X3:
196*35238bceSAndroid Build Coastguard Worker         gl.uniformMatrix2x3fv(loc, 1, GL_FALSE, &val.elements[elemNdx].float32);
197*35238bceSAndroid Build Coastguard Worker         break;
198*35238bceSAndroid Build Coastguard Worker     case TYPE_FLOAT_MAT2X4:
199*35238bceSAndroid Build Coastguard Worker         gl.uniformMatrix2x4fv(loc, 1, GL_FALSE, &val.elements[elemNdx].float32);
200*35238bceSAndroid Build Coastguard Worker         break;
201*35238bceSAndroid Build Coastguard Worker     case TYPE_FLOAT_MAT3X2:
202*35238bceSAndroid Build Coastguard Worker         gl.uniformMatrix3x2fv(loc, 1, GL_FALSE, &val.elements[elemNdx].float32);
203*35238bceSAndroid Build Coastguard Worker         break;
204*35238bceSAndroid Build Coastguard Worker     case TYPE_FLOAT_MAT3X4:
205*35238bceSAndroid Build Coastguard Worker         gl.uniformMatrix3x4fv(loc, 1, GL_FALSE, &val.elements[elemNdx].float32);
206*35238bceSAndroid Build Coastguard Worker         break;
207*35238bceSAndroid Build Coastguard Worker     case TYPE_FLOAT_MAT4X2:
208*35238bceSAndroid Build Coastguard Worker         gl.uniformMatrix4x2fv(loc, 1, GL_FALSE, &val.elements[elemNdx].float32);
209*35238bceSAndroid Build Coastguard Worker         break;
210*35238bceSAndroid Build Coastguard Worker     case TYPE_FLOAT_MAT4X3:
211*35238bceSAndroid Build Coastguard Worker         gl.uniformMatrix4x3fv(loc, 1, GL_FALSE, &val.elements[elemNdx].float32);
212*35238bceSAndroid Build Coastguard Worker         break;
213*35238bceSAndroid Build Coastguard Worker 
214*35238bceSAndroid Build Coastguard Worker     case TYPE_SAMPLER_2D:
215*35238bceSAndroid Build Coastguard Worker     case TYPE_SAMPLER_CUBE:
216*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false && "implement!");
217*35238bceSAndroid Build Coastguard Worker         break;
218*35238bceSAndroid Build Coastguard Worker 
219*35238bceSAndroid Build Coastguard Worker     default:
220*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
221*35238bceSAndroid Build Coastguard Worker     }
222*35238bceSAndroid Build Coastguard Worker }
223*35238bceSAndroid Build Coastguard Worker 
checkPixels(Surface & surface,int minX,int maxX,int minY,int maxY)224*35238bceSAndroid Build Coastguard Worker bool ShaderCase::checkPixels(Surface &surface, int minX, int maxX, int minY, int maxY)
225*35238bceSAndroid Build Coastguard Worker {
226*35238bceSAndroid Build Coastguard Worker     TestLog &log       = m_testCtx.getLog();
227*35238bceSAndroid Build Coastguard Worker     bool allWhite      = true;
228*35238bceSAndroid Build Coastguard Worker     bool allBlack      = true;
229*35238bceSAndroid Build Coastguard Worker     bool anyUnexpected = false;
230*35238bceSAndroid Build Coastguard Worker 
231*35238bceSAndroid Build Coastguard Worker     DE_ASSERT((maxX > minX) && (maxY > minY));
232*35238bceSAndroid Build Coastguard Worker 
233*35238bceSAndroid Build Coastguard Worker     for (int y = minY; y <= maxY; y++)
234*35238bceSAndroid Build Coastguard Worker     {
235*35238bceSAndroid Build Coastguard Worker         for (int x = minX; x <= maxX; x++)
236*35238bceSAndroid Build Coastguard Worker         {
237*35238bceSAndroid Build Coastguard Worker             RGBA pixel = surface.getPixel(x, y);
238*35238bceSAndroid Build Coastguard Worker             // Note: we really do not want to involve alpha in the check comparison
239*35238bceSAndroid Build Coastguard Worker             // \todo [2010-09-22 kalle] Do we know that alpha would be one? If yes, could use color constants white and black.
240*35238bceSAndroid Build Coastguard Worker             bool isWhite = (pixel.getRed() == 255) && (pixel.getGreen() == 255) && (pixel.getBlue() == 255);
241*35238bceSAndroid Build Coastguard Worker             bool isBlack = (pixel.getRed() == 0) && (pixel.getGreen() == 0) && (pixel.getBlue() == 0);
242*35238bceSAndroid Build Coastguard Worker 
243*35238bceSAndroid Build Coastguard Worker             allWhite      = allWhite && isWhite;
244*35238bceSAndroid Build Coastguard Worker             allBlack      = allBlack && isBlack;
245*35238bceSAndroid Build Coastguard Worker             anyUnexpected = anyUnexpected || (!isWhite && !isBlack);
246*35238bceSAndroid Build Coastguard Worker         }
247*35238bceSAndroid Build Coastguard Worker     }
248*35238bceSAndroid Build Coastguard Worker 
249*35238bceSAndroid Build Coastguard Worker     if (!allWhite)
250*35238bceSAndroid Build Coastguard Worker     {
251*35238bceSAndroid Build Coastguard Worker         if (anyUnexpected)
252*35238bceSAndroid Build Coastguard Worker             log << TestLog::Message
253*35238bceSAndroid Build Coastguard Worker                 << "WARNING: expecting all rendered pixels to be white or black, but got other colors as well!"
254*35238bceSAndroid Build Coastguard Worker                 << TestLog::EndMessage;
255*35238bceSAndroid Build Coastguard Worker         else if (!allBlack)
256*35238bceSAndroid Build Coastguard Worker             log << TestLog::Message
257*35238bceSAndroid Build Coastguard Worker                 << "WARNING: got inconsistent results over the image, when all pixels should be the same color!"
258*35238bceSAndroid Build Coastguard Worker                 << TestLog::EndMessage;
259*35238bceSAndroid Build Coastguard Worker 
260*35238bceSAndroid Build Coastguard Worker         return false;
261*35238bceSAndroid Build Coastguard Worker     }
262*35238bceSAndroid Build Coastguard Worker     return true;
263*35238bceSAndroid Build Coastguard Worker }
264*35238bceSAndroid Build Coastguard Worker 
execute(void)265*35238bceSAndroid Build Coastguard Worker bool ShaderCase::execute(void)
266*35238bceSAndroid Build Coastguard Worker {
267*35238bceSAndroid Build Coastguard Worker     TestLog &log             = m_testCtx.getLog();
268*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_renderCtx.getFunctions();
269*35238bceSAndroid Build Coastguard Worker 
270*35238bceSAndroid Build Coastguard Worker     // Compute viewport.
271*35238bceSAndroid Build Coastguard Worker     const tcu::RenderTarget &renderTarget = m_renderCtx.getRenderTarget();
272*35238bceSAndroid Build Coastguard Worker     de::Random rnd(deStringHash(getName()));
273*35238bceSAndroid Build Coastguard Worker     int width                    = deMin32(renderTarget.getWidth(), VIEWPORT_WIDTH);
274*35238bceSAndroid Build Coastguard Worker     int height                   = deMin32(renderTarget.getHeight(), VIEWPORT_HEIGHT);
275*35238bceSAndroid Build Coastguard Worker     int viewportX                = rnd.getInt(0, renderTarget.getWidth() - width);
276*35238bceSAndroid Build Coastguard Worker     int viewportY                = rnd.getInt(0, renderTarget.getHeight() - height);
277*35238bceSAndroid Build Coastguard Worker     const int numVerticesPerDraw = 4;
278*35238bceSAndroid Build Coastguard Worker 
279*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderCase::execute(): start");
280*35238bceSAndroid Build Coastguard Worker 
281*35238bceSAndroid Build Coastguard Worker     // Setup viewport.
282*35238bceSAndroid Build Coastguard Worker     gl.viewport(viewportX, viewportY, width, height);
283*35238bceSAndroid Build Coastguard Worker 
284*35238bceSAndroid Build Coastguard Worker     const float quadSize                  = 1.0f;
285*35238bceSAndroid Build Coastguard Worker     static const float s_positions[4 * 4] = {-quadSize, -quadSize, 0.0f, 1.0f, -quadSize, +quadSize, 0.0f, 1.0f,
286*35238bceSAndroid Build Coastguard Worker                                              +quadSize, -quadSize, 0.0f, 1.0f, +quadSize, +quadSize, 0.0f, 1.0f};
287*35238bceSAndroid Build Coastguard Worker 
288*35238bceSAndroid Build Coastguard Worker     static const uint16_t s_indices[2 * 3] = {0, 1, 2, 1, 3, 2};
289*35238bceSAndroid Build Coastguard Worker 
290*35238bceSAndroid Build Coastguard Worker     // Setup program.
291*35238bceSAndroid Build Coastguard Worker     glu::ShaderProgram program(m_renderCtx, glu::makeVtxFragSources(m_vertexSource.c_str(), m_fragmentSource.c_str()));
292*35238bceSAndroid Build Coastguard Worker 
293*35238bceSAndroid Build Coastguard Worker     // Check that compile/link results are what we expect.
294*35238bceSAndroid Build Coastguard Worker     bool vertexOk          = program.getShaderInfo(SHADERTYPE_VERTEX).compileOk;
295*35238bceSAndroid Build Coastguard Worker     bool fragmentOk        = program.getShaderInfo(SHADERTYPE_FRAGMENT).compileOk;
296*35238bceSAndroid Build Coastguard Worker     bool linkOk            = program.getProgramInfo().linkOk;
297*35238bceSAndroid Build Coastguard Worker     const char *failReason = DE_NULL;
298*35238bceSAndroid Build Coastguard Worker 
299*35238bceSAndroid Build Coastguard Worker     log << program;
300*35238bceSAndroid Build Coastguard Worker 
301*35238bceSAndroid Build Coastguard Worker     switch (m_expectResult)
302*35238bceSAndroid Build Coastguard Worker     {
303*35238bceSAndroid Build Coastguard Worker     case EXPECT_PASS:
304*35238bceSAndroid Build Coastguard Worker         if (!vertexOk || !fragmentOk)
305*35238bceSAndroid Build Coastguard Worker             failReason = "expected shaders to compile and link properly, but failed to compile.";
306*35238bceSAndroid Build Coastguard Worker         else if (!linkOk)
307*35238bceSAndroid Build Coastguard Worker             failReason = "expected shaders to compile and link properly, but failed to link.";
308*35238bceSAndroid Build Coastguard Worker         break;
309*35238bceSAndroid Build Coastguard Worker 
310*35238bceSAndroid Build Coastguard Worker     case EXPECT_COMPILE_FAIL:
311*35238bceSAndroid Build Coastguard Worker         if (vertexOk && fragmentOk && !linkOk)
312*35238bceSAndroid Build Coastguard Worker             failReason = "expected compilation to fail, but both shaders compiled and link failed.";
313*35238bceSAndroid Build Coastguard Worker         else if (vertexOk && fragmentOk)
314*35238bceSAndroid Build Coastguard Worker             failReason = "expected compilation to fail, but both shaders compiled correctly.";
315*35238bceSAndroid Build Coastguard Worker         break;
316*35238bceSAndroid Build Coastguard Worker 
317*35238bceSAndroid Build Coastguard Worker     case EXPECT_LINK_FAIL:
318*35238bceSAndroid Build Coastguard Worker         if (!vertexOk || !fragmentOk)
319*35238bceSAndroid Build Coastguard Worker             failReason = "expected linking to fail, but unable to compile.";
320*35238bceSAndroid Build Coastguard Worker         else if (linkOk)
321*35238bceSAndroid Build Coastguard Worker             failReason = "expected linking to fail, but passed.";
322*35238bceSAndroid Build Coastguard Worker         break;
323*35238bceSAndroid Build Coastguard Worker 
324*35238bceSAndroid Build Coastguard Worker     default:
325*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
326*35238bceSAndroid Build Coastguard Worker         return false;
327*35238bceSAndroid Build Coastguard Worker     }
328*35238bceSAndroid Build Coastguard Worker 
329*35238bceSAndroid Build Coastguard Worker     if (failReason != DE_NULL)
330*35238bceSAndroid Build Coastguard Worker     {
331*35238bceSAndroid Build Coastguard Worker         // \todo [2010-06-07 petri] These should be handled in the test case?
332*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "ERROR: " << failReason << TestLog::EndMessage;
333*35238bceSAndroid Build Coastguard Worker 
334*35238bceSAndroid Build Coastguard Worker         // If implementation parses shader at link time, report it as quality warning.
335*35238bceSAndroid Build Coastguard Worker         if (m_expectResult == EXPECT_COMPILE_FAIL && vertexOk && fragmentOk && !linkOk)
336*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, failReason);
337*35238bceSAndroid Build Coastguard Worker         else
338*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, failReason);
339*35238bceSAndroid Build Coastguard Worker         return false;
340*35238bceSAndroid Build Coastguard Worker     }
341*35238bceSAndroid Build Coastguard Worker 
342*35238bceSAndroid Build Coastguard Worker     // Return if compile/link expected to fail.
343*35238bceSAndroid Build Coastguard Worker     if (m_expectResult != EXPECT_PASS)
344*35238bceSAndroid Build Coastguard Worker         return (failReason == DE_NULL);
345*35238bceSAndroid Build Coastguard Worker 
346*35238bceSAndroid Build Coastguard Worker     // Start using program.
347*35238bceSAndroid Build Coastguard Worker     uint32_t programID = program.getProgram();
348*35238bceSAndroid Build Coastguard Worker     gl.useProgram(programID);
349*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
350*35238bceSAndroid Build Coastguard Worker 
351*35238bceSAndroid Build Coastguard Worker     // Fetch location for positions positions.
352*35238bceSAndroid Build Coastguard Worker     int positionLoc = gl.getAttribLocation(programID, "dEQP_Position");
353*35238bceSAndroid Build Coastguard Worker     if (positionLoc == -1)
354*35238bceSAndroid Build Coastguard Worker     {
355*35238bceSAndroid Build Coastguard Worker         string errStr = string("no location found for attribute 'dEQP_Position'");
356*35238bceSAndroid Build Coastguard Worker         TCU_FAIL(errStr.c_str());
357*35238bceSAndroid Build Coastguard Worker     }
358*35238bceSAndroid Build Coastguard Worker 
359*35238bceSAndroid Build Coastguard Worker     // Iterate all value blocks.
360*35238bceSAndroid Build Coastguard Worker     for (int blockNdx = 0; blockNdx < (int)m_valueBlocks.size(); blockNdx++)
361*35238bceSAndroid Build Coastguard Worker     {
362*35238bceSAndroid Build Coastguard Worker         const ValueBlock &valueBlock = m_valueBlocks[blockNdx];
363*35238bceSAndroid Build Coastguard Worker 
364*35238bceSAndroid Build Coastguard Worker         // Iterate all array sub-cases.
365*35238bceSAndroid Build Coastguard Worker         for (int arrayNdx = 0; arrayNdx < valueBlock.arrayLength; arrayNdx++)
366*35238bceSAndroid Build Coastguard Worker         {
367*35238bceSAndroid Build Coastguard Worker             int numValues = (int)valueBlock.values.size();
368*35238bceSAndroid Build Coastguard Worker             vector<VertexArrayBinding> vertexArrays;
369*35238bceSAndroid Build Coastguard Worker 
370*35238bceSAndroid Build Coastguard Worker             int attribValueNdx = 0;
371*35238bceSAndroid Build Coastguard Worker             vector<vector<float>> attribValues(numValues);
372*35238bceSAndroid Build Coastguard Worker 
373*35238bceSAndroid Build Coastguard Worker             vertexArrays.push_back(va::Float(positionLoc, 4, numVerticesPerDraw, 0, &s_positions[0]));
374*35238bceSAndroid Build Coastguard Worker 
375*35238bceSAndroid Build Coastguard Worker             // Collect VA pointer for inputs and set uniform values for outputs (refs).
376*35238bceSAndroid Build Coastguard Worker             for (int valNdx = 0; valNdx < numValues; valNdx++)
377*35238bceSAndroid Build Coastguard Worker             {
378*35238bceSAndroid Build Coastguard Worker                 const ShaderCase::Value &val = valueBlock.values[valNdx];
379*35238bceSAndroid Build Coastguard Worker                 const char *valueName        = val.valueName.c_str();
380*35238bceSAndroid Build Coastguard Worker                 DataType dataType            = val.dataType;
381*35238bceSAndroid Build Coastguard Worker                 int scalarSize               = getDataTypeScalarSize(val.dataType);
382*35238bceSAndroid Build Coastguard Worker 
383*35238bceSAndroid Build Coastguard Worker                 GLU_EXPECT_NO_ERROR(gl.getError(), "before set uniforms");
384*35238bceSAndroid Build Coastguard Worker 
385*35238bceSAndroid Build Coastguard Worker                 if (val.storageType == ShaderCase::Value::STORAGE_INPUT)
386*35238bceSAndroid Build Coastguard Worker                 {
387*35238bceSAndroid Build Coastguard Worker                     // Replicate values four times.
388*35238bceSAndroid Build Coastguard Worker                     std::vector<float> &scalars = attribValues[attribValueNdx++];
389*35238bceSAndroid Build Coastguard Worker                     scalars.resize(numVerticesPerDraw * scalarSize);
390*35238bceSAndroid Build Coastguard Worker                     if (isDataTypeFloatOrVec(dataType) || isDataTypeMatrix(dataType))
391*35238bceSAndroid Build Coastguard Worker                     {
392*35238bceSAndroid Build Coastguard Worker                         for (int repNdx = 0; repNdx < numVerticesPerDraw; repNdx++)
393*35238bceSAndroid Build Coastguard Worker                             for (int ndx = 0; ndx < scalarSize; ndx++)
394*35238bceSAndroid Build Coastguard Worker                                 scalars[repNdx * scalarSize + ndx] = val.elements[arrayNdx * scalarSize + ndx].float32;
395*35238bceSAndroid Build Coastguard Worker                     }
396*35238bceSAndroid Build Coastguard Worker                     else
397*35238bceSAndroid Build Coastguard Worker                     {
398*35238bceSAndroid Build Coastguard Worker                         // convert to floats.
399*35238bceSAndroid Build Coastguard Worker                         for (int repNdx = 0; repNdx < numVerticesPerDraw; repNdx++)
400*35238bceSAndroid Build Coastguard Worker                         {
401*35238bceSAndroid Build Coastguard Worker                             for (int ndx = 0; ndx < scalarSize; ndx++)
402*35238bceSAndroid Build Coastguard Worker                             {
403*35238bceSAndroid Build Coastguard Worker                                 float v = (float)val.elements[arrayNdx * scalarSize + ndx].int32;
404*35238bceSAndroid Build Coastguard Worker                                 DE_ASSERT(val.elements[arrayNdx * scalarSize + ndx].int32 == (int)v);
405*35238bceSAndroid Build Coastguard Worker                                 scalars[repNdx * scalarSize + ndx] = v;
406*35238bceSAndroid Build Coastguard Worker                             }
407*35238bceSAndroid Build Coastguard Worker                         }
408*35238bceSAndroid Build Coastguard Worker                     }
409*35238bceSAndroid Build Coastguard Worker 
410*35238bceSAndroid Build Coastguard Worker                     // Attribute name prefix.
411*35238bceSAndroid Build Coastguard Worker                     string attribPrefix = "";
412*35238bceSAndroid Build Coastguard Worker                     // \todo [2010-05-27 petri] Should latter condition only apply for vertex cases (or actually non-fragment cases)?
413*35238bceSAndroid Build Coastguard Worker                     if ((m_caseType == CASETYPE_FRAGMENT_ONLY) || (getDataTypeScalarType(dataType) != TYPE_FLOAT))
414*35238bceSAndroid Build Coastguard Worker                         attribPrefix = "a_";
415*35238bceSAndroid Build Coastguard Worker 
416*35238bceSAndroid Build Coastguard Worker                     // Input always given as attribute.
417*35238bceSAndroid Build Coastguard Worker                     string attribName = attribPrefix + valueName;
418*35238bceSAndroid Build Coastguard Worker                     int attribLoc     = gl.getAttribLocation(programID, attribName.c_str());
419*35238bceSAndroid Build Coastguard Worker                     if (attribLoc == -1)
420*35238bceSAndroid Build Coastguard Worker                     {
421*35238bceSAndroid Build Coastguard Worker                         log << TestLog::Message << "Warning: no location found for attribute '" << attribName << "'"
422*35238bceSAndroid Build Coastguard Worker                             << TestLog::EndMessage;
423*35238bceSAndroid Build Coastguard Worker                         continue;
424*35238bceSAndroid Build Coastguard Worker                     }
425*35238bceSAndroid Build Coastguard Worker 
426*35238bceSAndroid Build Coastguard Worker                     if (isDataTypeMatrix(dataType))
427*35238bceSAndroid Build Coastguard Worker                     {
428*35238bceSAndroid Build Coastguard Worker                         int numCols = getDataTypeMatrixNumColumns(dataType);
429*35238bceSAndroid Build Coastguard Worker                         int numRows = getDataTypeMatrixNumRows(dataType);
430*35238bceSAndroid Build Coastguard Worker                         DE_ASSERT(scalarSize == numCols * numRows);
431*35238bceSAndroid Build Coastguard Worker 
432*35238bceSAndroid Build Coastguard Worker                         for (int i = 0; i < numCols; i++)
433*35238bceSAndroid Build Coastguard Worker                             vertexArrays.push_back(va::Float(attribLoc + i, numRows, numVerticesPerDraw,
434*35238bceSAndroid Build Coastguard Worker                                                              static_cast<int>(scalarSize * sizeof(float)),
435*35238bceSAndroid Build Coastguard Worker                                                              &scalars[i * numRows]));
436*35238bceSAndroid Build Coastguard Worker                     }
437*35238bceSAndroid Build Coastguard Worker                     else
438*35238bceSAndroid Build Coastguard Worker                     {
439*35238bceSAndroid Build Coastguard Worker                         DE_ASSERT(isDataTypeFloatOrVec(dataType) || isDataTypeIntOrIVec(dataType) ||
440*35238bceSAndroid Build Coastguard Worker                                   isDataTypeUintOrUVec(dataType) || isDataTypeBoolOrBVec(dataType));
441*35238bceSAndroid Build Coastguard Worker                         vertexArrays.push_back(va::Float(attribLoc, scalarSize, numVerticesPerDraw, 0, &scalars[0]));
442*35238bceSAndroid Build Coastguard Worker                     }
443*35238bceSAndroid Build Coastguard Worker 
444*35238bceSAndroid Build Coastguard Worker                     GLU_EXPECT_NO_ERROR(gl.getError(), "set vertex attrib array");
445*35238bceSAndroid Build Coastguard Worker                 }
446*35238bceSAndroid Build Coastguard Worker                 else if (val.storageType == ShaderCase::Value::STORAGE_OUTPUT)
447*35238bceSAndroid Build Coastguard Worker                 {
448*35238bceSAndroid Build Coastguard Worker                     // Set reference value.
449*35238bceSAndroid Build Coastguard Worker                     string refName = string("ref_") + valueName;
450*35238bceSAndroid Build Coastguard Worker                     setUniformValue(gl, programID, refName, val, arrayNdx);
451*35238bceSAndroid Build Coastguard Worker                     GLU_EXPECT_NO_ERROR(gl.getError(), "set reference uniforms");
452*35238bceSAndroid Build Coastguard Worker                 }
453*35238bceSAndroid Build Coastguard Worker                 else
454*35238bceSAndroid Build Coastguard Worker                 {
455*35238bceSAndroid Build Coastguard Worker                     DE_ASSERT(val.storageType == ShaderCase::Value::STORAGE_UNIFORM);
456*35238bceSAndroid Build Coastguard Worker                     setUniformValue(gl, programID, valueName, val, arrayNdx);
457*35238bceSAndroid Build Coastguard Worker                     GLU_EXPECT_NO_ERROR(gl.getError(), "set uniforms");
458*35238bceSAndroid Build Coastguard Worker                 }
459*35238bceSAndroid Build Coastguard Worker             }
460*35238bceSAndroid Build Coastguard Worker 
461*35238bceSAndroid Build Coastguard Worker             // Clear.
462*35238bceSAndroid Build Coastguard Worker             gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
463*35238bceSAndroid Build Coastguard Worker             gl.clear(GL_COLOR_BUFFER_BIT);
464*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "clear buffer");
465*35238bceSAndroid Build Coastguard Worker 
466*35238bceSAndroid Build Coastguard Worker             // Draw.
467*35238bceSAndroid Build Coastguard Worker             draw(m_renderCtx, program.getProgram(), (int)vertexArrays.size(), &vertexArrays[0],
468*35238bceSAndroid Build Coastguard Worker                  pr::Triangles(DE_LENGTH_OF_ARRAY(s_indices), &s_indices[0]));
469*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "draw");
470*35238bceSAndroid Build Coastguard Worker 
471*35238bceSAndroid Build Coastguard Worker             // Read back results.
472*35238bceSAndroid Build Coastguard Worker             Surface surface(width, height);
473*35238bceSAndroid Build Coastguard Worker             glu::readPixels(m_renderCtx, viewportX, viewportY, surface.getAccess());
474*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "read pixels");
475*35238bceSAndroid Build Coastguard Worker 
476*35238bceSAndroid Build Coastguard Worker             float w  = s_positions[3];
477*35238bceSAndroid Build Coastguard Worker             int minY = deCeilFloatToInt32(((-quadSize / w) * 0.5f + 0.5f) * (float)height + 1.0f);
478*35238bceSAndroid Build Coastguard Worker             int maxY = deFloorFloatToInt32(((+quadSize / w) * 0.5f + 0.5f) * (float)height - 0.5f);
479*35238bceSAndroid Build Coastguard Worker             int minX = deCeilFloatToInt32(((-quadSize / w) * 0.5f + 0.5f) * (float)width + 1.0f);
480*35238bceSAndroid Build Coastguard Worker             int maxX = deFloorFloatToInt32(((+quadSize / w) * 0.5f + 0.5f) * (float)width - 0.5f);
481*35238bceSAndroid Build Coastguard Worker 
482*35238bceSAndroid Build Coastguard Worker             if (!checkPixels(surface, minX, maxX, minY, maxY))
483*35238bceSAndroid Build Coastguard Worker             {
484*35238bceSAndroid Build Coastguard Worker                 log << TestLog::Message << "INCORRECT RESULT for (value block " << (blockNdx + 1) << " of "
485*35238bceSAndroid Build Coastguard Worker                     << (int)m_valueBlocks.size() << ", sub-case " << arrayNdx + 1 << " of " << valueBlock.arrayLength
486*35238bceSAndroid Build Coastguard Worker                     << "):" << TestLog::EndMessage;
487*35238bceSAndroid Build Coastguard Worker 
488*35238bceSAndroid Build Coastguard Worker                 log << TestLog::Message << "Failing shader input/output values:" << TestLog::EndMessage;
489*35238bceSAndroid Build Coastguard Worker                 dumpValues(valueBlock, arrayNdx);
490*35238bceSAndroid Build Coastguard Worker 
491*35238bceSAndroid Build Coastguard Worker                 // Dump image on failure.
492*35238bceSAndroid Build Coastguard Worker                 log << TestLog::Image("Result", "Rendered result image", surface);
493*35238bceSAndroid Build Coastguard Worker 
494*35238bceSAndroid Build Coastguard Worker                 gl.useProgram(0);
495*35238bceSAndroid Build Coastguard Worker                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
496*35238bceSAndroid Build Coastguard Worker                 return false;
497*35238bceSAndroid Build Coastguard Worker             }
498*35238bceSAndroid Build Coastguard Worker         }
499*35238bceSAndroid Build Coastguard Worker     }
500*35238bceSAndroid Build Coastguard Worker 
501*35238bceSAndroid Build Coastguard Worker     gl.useProgram(0);
502*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderCase::execute(): end");
503*35238bceSAndroid Build Coastguard Worker     return true;
504*35238bceSAndroid Build Coastguard Worker }
505*35238bceSAndroid Build Coastguard Worker 
iterate(void)506*35238bceSAndroid Build Coastguard Worker TestCase::IterateResult ShaderCase::iterate(void)
507*35238bceSAndroid Build Coastguard Worker {
508*35238bceSAndroid Build Coastguard Worker     // Initialize state to pass.
509*35238bceSAndroid Build Coastguard Worker     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
510*35238bceSAndroid Build Coastguard Worker 
511*35238bceSAndroid Build Coastguard Worker     bool executeOk = execute();
512*35238bceSAndroid Build Coastguard Worker 
513*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(executeOk ? m_testCtx.getTestResult() == QP_TEST_RESULT_PASS :
514*35238bceSAndroid Build Coastguard Worker                           m_testCtx.getTestResult() != QP_TEST_RESULT_PASS);
515*35238bceSAndroid Build Coastguard Worker     (void)executeOk;
516*35238bceSAndroid Build Coastguard Worker     return TestCase::STOP;
517*35238bceSAndroid Build Coastguard Worker }
518*35238bceSAndroid Build Coastguard Worker 
519*35238bceSAndroid Build Coastguard Worker // This functions builds a matching vertex shader for a 'both' case, when
520*35238bceSAndroid Build Coastguard Worker // the fragment shader is being tested.
521*35238bceSAndroid Build Coastguard Worker // We need to build attributes and varyings for each 'input'.
genVertexShader(const ValueBlock & valueBlock)522*35238bceSAndroid Build Coastguard Worker string ShaderCase::genVertexShader(const ValueBlock &valueBlock)
523*35238bceSAndroid Build Coastguard Worker {
524*35238bceSAndroid Build Coastguard Worker     ostringstream res;
525*35238bceSAndroid Build Coastguard Worker     const bool usesInout = usesShaderInoutQualifiers(m_targetVersion);
526*35238bceSAndroid Build Coastguard Worker     const char *vtxIn    = usesInout ? "in" : "attribute";
527*35238bceSAndroid Build Coastguard Worker     const char *vtxOut   = usesInout ? "out" : "varying";
528*35238bceSAndroid Build Coastguard Worker 
529*35238bceSAndroid Build Coastguard Worker     res << glu::getGLSLVersionDeclaration(m_targetVersion) << "\n";
530*35238bceSAndroid Build Coastguard Worker 
531*35238bceSAndroid Build Coastguard Worker     // Declarations (position + attribute/varying for each input).
532*35238bceSAndroid Build Coastguard Worker     res << "precision highp float;\n";
533*35238bceSAndroid Build Coastguard Worker     res << "precision highp int;\n";
534*35238bceSAndroid Build Coastguard Worker     res << "\n";
535*35238bceSAndroid Build Coastguard Worker     res << vtxIn << " highp vec4 dEQP_Position;\n";
536*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < (int)valueBlock.values.size(); ndx++)
537*35238bceSAndroid Build Coastguard Worker     {
538*35238bceSAndroid Build Coastguard Worker         const ShaderCase::Value &val = valueBlock.values[ndx];
539*35238bceSAndroid Build Coastguard Worker         if (val.storageType == ShaderCase::Value::STORAGE_INPUT)
540*35238bceSAndroid Build Coastguard Worker         {
541*35238bceSAndroid Build Coastguard Worker             DataType floatType  = getDataTypeFloatScalars(val.dataType);
542*35238bceSAndroid Build Coastguard Worker             const char *typeStr = getDataTypeName(floatType);
543*35238bceSAndroid Build Coastguard Worker             res << vtxIn << " " << typeStr << " a_" << val.valueName << ";\n";
544*35238bceSAndroid Build Coastguard Worker 
545*35238bceSAndroid Build Coastguard Worker             if (getDataTypeScalarType(val.dataType) == TYPE_FLOAT)
546*35238bceSAndroid Build Coastguard Worker                 res << vtxOut << " " << typeStr << " " << val.valueName << ";\n";
547*35238bceSAndroid Build Coastguard Worker             else
548*35238bceSAndroid Build Coastguard Worker                 res << vtxOut << " " << typeStr << " v_" << val.valueName << ";\n";
549*35238bceSAndroid Build Coastguard Worker         }
550*35238bceSAndroid Build Coastguard Worker     }
551*35238bceSAndroid Build Coastguard Worker     res << "\n";
552*35238bceSAndroid Build Coastguard Worker 
553*35238bceSAndroid Build Coastguard Worker     // Main function.
554*35238bceSAndroid Build Coastguard Worker     // - gl_Position = dEQP_Position;
555*35238bceSAndroid Build Coastguard Worker     // - for each input: write attribute directly to varying
556*35238bceSAndroid Build Coastguard Worker     res << "void main()\n";
557*35238bceSAndroid Build Coastguard Worker     res << "{\n";
558*35238bceSAndroid Build Coastguard Worker     res << "    gl_Position = dEQP_Position;\n";
559*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < (int)valueBlock.values.size(); ndx++)
560*35238bceSAndroid Build Coastguard Worker     {
561*35238bceSAndroid Build Coastguard Worker         const ShaderCase::Value &val = valueBlock.values[ndx];
562*35238bceSAndroid Build Coastguard Worker         if (val.storageType == ShaderCase::Value::STORAGE_INPUT)
563*35238bceSAndroid Build Coastguard Worker         {
564*35238bceSAndroid Build Coastguard Worker             const string &name = val.valueName;
565*35238bceSAndroid Build Coastguard Worker             if (getDataTypeScalarType(val.dataType) == TYPE_FLOAT)
566*35238bceSAndroid Build Coastguard Worker                 res << "    " << name << " = a_" << name << ";\n";
567*35238bceSAndroid Build Coastguard Worker             else
568*35238bceSAndroid Build Coastguard Worker                 res << "    v_" << name << " = a_" << name << ";\n";
569*35238bceSAndroid Build Coastguard Worker         }
570*35238bceSAndroid Build Coastguard Worker     }
571*35238bceSAndroid Build Coastguard Worker 
572*35238bceSAndroid Build Coastguard Worker     res << "}\n";
573*35238bceSAndroid Build Coastguard Worker     return res.str();
574*35238bceSAndroid Build Coastguard Worker }
575*35238bceSAndroid Build Coastguard Worker 
genCompareFunctions(ostringstream & stream,const ShaderCase::ValueBlock & valueBlock,bool useFloatTypes)576*35238bceSAndroid Build Coastguard Worker static void genCompareFunctions(ostringstream &stream, const ShaderCase::ValueBlock &valueBlock, bool useFloatTypes)
577*35238bceSAndroid Build Coastguard Worker {
578*35238bceSAndroid Build Coastguard Worker     bool cmpTypeFound[TYPE_LAST];
579*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < TYPE_LAST; i++)
580*35238bceSAndroid Build Coastguard Worker         cmpTypeFound[i] = false;
581*35238bceSAndroid Build Coastguard Worker 
582*35238bceSAndroid Build Coastguard Worker     for (int valueNdx = 0; valueNdx < (int)valueBlock.values.size(); valueNdx++)
583*35238bceSAndroid Build Coastguard Worker     {
584*35238bceSAndroid Build Coastguard Worker         const ShaderCase::Value &val = valueBlock.values[valueNdx];
585*35238bceSAndroid Build Coastguard Worker         if (val.storageType == ShaderCase::Value::STORAGE_OUTPUT)
586*35238bceSAndroid Build Coastguard Worker             cmpTypeFound[(int)val.dataType] = true;
587*35238bceSAndroid Build Coastguard Worker     }
588*35238bceSAndroid Build Coastguard Worker 
589*35238bceSAndroid Build Coastguard Worker     if (useFloatTypes)
590*35238bceSAndroid Build Coastguard Worker     {
591*35238bceSAndroid Build Coastguard Worker         if (cmpTypeFound[TYPE_BOOL])
592*35238bceSAndroid Build Coastguard Worker             stream << "bool isOk (float a, bool b) { return ((a > 0.5) == b); }\n";
593*35238bceSAndroid Build Coastguard Worker         if (cmpTypeFound[TYPE_BOOL_VEC2])
594*35238bceSAndroid Build Coastguard Worker             stream << "bool isOk (vec2 a, bvec2 b) { return (greaterThan(a, vec2(0.5)) == b); }\n";
595*35238bceSAndroid Build Coastguard Worker         if (cmpTypeFound[TYPE_BOOL_VEC3])
596*35238bceSAndroid Build Coastguard Worker             stream << "bool isOk (vec3 a, bvec3 b) { return (greaterThan(a, vec3(0.5)) == b); }\n";
597*35238bceSAndroid Build Coastguard Worker         if (cmpTypeFound[TYPE_BOOL_VEC4])
598*35238bceSAndroid Build Coastguard Worker             stream << "bool isOk (vec4 a, bvec4 b) { return (greaterThan(a, vec4(0.5)) == b); }\n";
599*35238bceSAndroid Build Coastguard Worker         if (cmpTypeFound[TYPE_INT])
600*35238bceSAndroid Build Coastguard Worker             stream << "bool isOk (float a, int b)  { float atemp = a+0.5; return (float(b) <= atemp && atemp <= "
601*35238bceSAndroid Build Coastguard Worker                       "float(b+1)); }\n";
602*35238bceSAndroid Build Coastguard Worker         if (cmpTypeFound[TYPE_INT_VEC2])
603*35238bceSAndroid Build Coastguard Worker             stream << "bool isOk (vec2 a, ivec2 b) { return (ivec2(floor(a + 0.5)) == b); }\n";
604*35238bceSAndroid Build Coastguard Worker         if (cmpTypeFound[TYPE_INT_VEC3])
605*35238bceSAndroid Build Coastguard Worker             stream << "bool isOk (vec3 a, ivec3 b) { return (ivec3(floor(a + 0.5)) == b); }\n";
606*35238bceSAndroid Build Coastguard Worker         if (cmpTypeFound[TYPE_INT_VEC4])
607*35238bceSAndroid Build Coastguard Worker             stream << "bool isOk (vec4 a, ivec4 b) { return (ivec4(floor(a + 0.5)) == b); }\n";
608*35238bceSAndroid Build Coastguard Worker         if (cmpTypeFound[TYPE_UINT])
609*35238bceSAndroid Build Coastguard Worker             stream << "bool isOk (float a, uint b) { float atemp = a+0.5; return (float(b) <= atemp && atemp <= "
610*35238bceSAndroid Build Coastguard Worker                       "float(b+1)); }\n";
611*35238bceSAndroid Build Coastguard Worker         if (cmpTypeFound[TYPE_UINT_VEC2])
612*35238bceSAndroid Build Coastguard Worker             stream << "bool isOk (vec2 a, uvec2 b) { return (uvec2(floor(a + 0.5)) == b); }\n";
613*35238bceSAndroid Build Coastguard Worker         if (cmpTypeFound[TYPE_UINT_VEC3])
614*35238bceSAndroid Build Coastguard Worker             stream << "bool isOk (vec3 a, uvec3 b) { return (uvec3(floor(a + 0.5)) == b); }\n";
615*35238bceSAndroid Build Coastguard Worker         if (cmpTypeFound[TYPE_UINT_VEC4])
616*35238bceSAndroid Build Coastguard Worker             stream << "bool isOk (vec4 a, uvec4 b) { return (uvec4(floor(a + 0.5)) == b); }\n";
617*35238bceSAndroid Build Coastguard Worker     }
618*35238bceSAndroid Build Coastguard Worker     else
619*35238bceSAndroid Build Coastguard Worker     {
620*35238bceSAndroid Build Coastguard Worker         if (cmpTypeFound[TYPE_BOOL])
621*35238bceSAndroid Build Coastguard Worker             stream << "bool isOk (bool a, bool b)   { return (a == b); }\n";
622*35238bceSAndroid Build Coastguard Worker         if (cmpTypeFound[TYPE_BOOL_VEC2])
623*35238bceSAndroid Build Coastguard Worker             stream << "bool isOk (bvec2 a, bvec2 b) { return (a == b); }\n";
624*35238bceSAndroid Build Coastguard Worker         if (cmpTypeFound[TYPE_BOOL_VEC3])
625*35238bceSAndroid Build Coastguard Worker             stream << "bool isOk (bvec3 a, bvec3 b) { return (a == b); }\n";
626*35238bceSAndroid Build Coastguard Worker         if (cmpTypeFound[TYPE_BOOL_VEC4])
627*35238bceSAndroid Build Coastguard Worker             stream << "bool isOk (bvec4 a, bvec4 b) { return (a == b); }\n";
628*35238bceSAndroid Build Coastguard Worker         if (cmpTypeFound[TYPE_INT])
629*35238bceSAndroid Build Coastguard Worker             stream << "bool isOk (int a, int b)     { return (a == b); }\n";
630*35238bceSAndroid Build Coastguard Worker         if (cmpTypeFound[TYPE_INT_VEC2])
631*35238bceSAndroid Build Coastguard Worker             stream << "bool isOk (ivec2 a, ivec2 b) { return (a == b); }\n";
632*35238bceSAndroid Build Coastguard Worker         if (cmpTypeFound[TYPE_INT_VEC3])
633*35238bceSAndroid Build Coastguard Worker             stream << "bool isOk (ivec3 a, ivec3 b) { return (a == b); }\n";
634*35238bceSAndroid Build Coastguard Worker         if (cmpTypeFound[TYPE_INT_VEC4])
635*35238bceSAndroid Build Coastguard Worker             stream << "bool isOk (ivec4 a, ivec4 b) { return (a == b); }\n";
636*35238bceSAndroid Build Coastguard Worker         if (cmpTypeFound[TYPE_UINT])
637*35238bceSAndroid Build Coastguard Worker             stream << "bool isOk (uint a, uint b)   { return (a == b); }\n";
638*35238bceSAndroid Build Coastguard Worker         if (cmpTypeFound[TYPE_UINT_VEC2])
639*35238bceSAndroid Build Coastguard Worker             stream << "bool isOk (uvec2 a, uvec2 b) { return (a == b); }\n";
640*35238bceSAndroid Build Coastguard Worker         if (cmpTypeFound[TYPE_UINT_VEC3])
641*35238bceSAndroid Build Coastguard Worker             stream << "bool isOk (uvec3 a, uvec3 b) { return (a == b); }\n";
642*35238bceSAndroid Build Coastguard Worker         if (cmpTypeFound[TYPE_UINT_VEC4])
643*35238bceSAndroid Build Coastguard Worker             stream << "bool isOk (uvec4 a, uvec4 b) { return (a == b); }\n";
644*35238bceSAndroid Build Coastguard Worker     }
645*35238bceSAndroid Build Coastguard Worker 
646*35238bceSAndroid Build Coastguard Worker     if (cmpTypeFound[TYPE_FLOAT])
647*35238bceSAndroid Build Coastguard Worker         stream << "bool isOk (float a, float b, float eps) { return (abs(a-b) <= (eps*abs(b) + eps)); }\n";
648*35238bceSAndroid Build Coastguard Worker     if (cmpTypeFound[TYPE_FLOAT_VEC2])
649*35238bceSAndroid Build Coastguard Worker         stream
650*35238bceSAndroid Build Coastguard Worker             << "bool isOk (vec2 a, vec2 b, float eps) { return all(lessThanEqual(abs(a-b), (eps*abs(b) + eps))); }\n";
651*35238bceSAndroid Build Coastguard Worker     if (cmpTypeFound[TYPE_FLOAT_VEC3])
652*35238bceSAndroid Build Coastguard Worker         stream
653*35238bceSAndroid Build Coastguard Worker             << "bool isOk (vec3 a, vec3 b, float eps) { return all(lessThanEqual(abs(a-b), (eps*abs(b) + eps))); }\n";
654*35238bceSAndroid Build Coastguard Worker     if (cmpTypeFound[TYPE_FLOAT_VEC4])
655*35238bceSAndroid Build Coastguard Worker         stream
656*35238bceSAndroid Build Coastguard Worker             << "bool isOk (vec4 a, vec4 b, float eps) { return all(lessThanEqual(abs(a-b), (eps*abs(b) + eps))); }\n";
657*35238bceSAndroid Build Coastguard Worker 
658*35238bceSAndroid Build Coastguard Worker     if (cmpTypeFound[TYPE_FLOAT_MAT2])
659*35238bceSAndroid Build Coastguard Worker         stream << "bool isOk (mat2 a, mat2 b, float eps) { vec2 diff = max(abs(a[0]-b[0]), abs(a[1]-b[1])); return "
660*35238bceSAndroid Build Coastguard Worker                   "all(lessThanEqual(diff, vec2(eps))); }\n";
661*35238bceSAndroid Build Coastguard Worker     if (cmpTypeFound[TYPE_FLOAT_MAT2X3])
662*35238bceSAndroid Build Coastguard Worker         stream << "bool isOk (mat2x3 a, mat2x3 b, float eps) { vec3 diff = max(abs(a[0]-b[0]), abs(a[1]-b[1])); return "
663*35238bceSAndroid Build Coastguard Worker                   "all(lessThanEqual(diff, vec3(eps))); }\n";
664*35238bceSAndroid Build Coastguard Worker     if (cmpTypeFound[TYPE_FLOAT_MAT2X4])
665*35238bceSAndroid Build Coastguard Worker         stream << "bool isOk (mat2x4 a, mat2x4 b, float eps) { vec4 diff = max(abs(a[0]-b[0]), abs(a[1]-b[1])); return "
666*35238bceSAndroid Build Coastguard Worker                   "all(lessThanEqual(diff, vec4(eps))); }\n";
667*35238bceSAndroid Build Coastguard Worker     if (cmpTypeFound[TYPE_FLOAT_MAT3X2])
668*35238bceSAndroid Build Coastguard Worker         stream << "bool isOk (mat3x2 a, mat3x2 b, float eps) { vec2 diff = max(max(abs(a[0]-b[0]), abs(a[1]-b[1])), "
669*35238bceSAndroid Build Coastguard Worker                   "abs(a[2]-b[2])); return all(lessThanEqual(diff, vec2(eps))); }\n";
670*35238bceSAndroid Build Coastguard Worker     if (cmpTypeFound[TYPE_FLOAT_MAT3])
671*35238bceSAndroid Build Coastguard Worker         stream << "bool isOk (mat3 a, mat3 b, float eps) { vec3 diff = max(max(abs(a[0]-b[0]), abs(a[1]-b[1])), "
672*35238bceSAndroid Build Coastguard Worker                   "abs(a[2]-b[2])); return all(lessThanEqual(diff, vec3(eps))); }\n";
673*35238bceSAndroid Build Coastguard Worker     if (cmpTypeFound[TYPE_FLOAT_MAT3X4])
674*35238bceSAndroid Build Coastguard Worker         stream << "bool isOk (mat3x4 a, mat3x4 b, float eps) { vec4 diff = max(max(abs(a[0]-b[0]), abs(a[1]-b[1])), "
675*35238bceSAndroid Build Coastguard Worker                   "abs(a[2]-b[2])); return all(lessThanEqual(diff, vec4(eps))); }\n";
676*35238bceSAndroid Build Coastguard Worker     if (cmpTypeFound[TYPE_FLOAT_MAT4X2])
677*35238bceSAndroid Build Coastguard Worker         stream << "bool isOk (mat4x2 a, mat4x2 b, float eps) { vec2 diff = max(max(abs(a[0]-b[0]), abs(a[1]-b[1])), "
678*35238bceSAndroid Build Coastguard Worker                   "max(abs(a[2]-b[2]), abs(a[3]-b[3]))); return all(lessThanEqual(diff, vec2(eps))); }\n";
679*35238bceSAndroid Build Coastguard Worker     if (cmpTypeFound[TYPE_FLOAT_MAT4X3])
680*35238bceSAndroid Build Coastguard Worker         stream << "bool isOk (mat4x3 a, mat4x3 b, float eps) { vec3 diff = max(max(abs(a[0]-b[0]), abs(a[1]-b[1])), "
681*35238bceSAndroid Build Coastguard Worker                   "max(abs(a[2]-b[2]), abs(a[3]-b[3]))); return all(lessThanEqual(diff, vec3(eps))); }\n";
682*35238bceSAndroid Build Coastguard Worker     if (cmpTypeFound[TYPE_FLOAT_MAT4])
683*35238bceSAndroid Build Coastguard Worker         stream << "bool isOk (mat4 a, mat4 b, float eps) { vec4 diff = max(max(abs(a[0]-b[0]), abs(a[1]-b[1])), "
684*35238bceSAndroid Build Coastguard Worker                   "max(abs(a[2]-b[2]), abs(a[3]-b[3]))); return all(lessThanEqual(diff, vec4(eps))); }\n";
685*35238bceSAndroid Build Coastguard Worker }
686*35238bceSAndroid Build Coastguard Worker 
genCompareOp(ostringstream & output,const char * dstVec4Var,const ShaderCase::ValueBlock & valueBlock,const char * nonFloatNamePrefix,const char * checkVarName)687*35238bceSAndroid Build Coastguard Worker static void genCompareOp(ostringstream &output, const char *dstVec4Var, const ShaderCase::ValueBlock &valueBlock,
688*35238bceSAndroid Build Coastguard Worker                          const char *nonFloatNamePrefix, const char *checkVarName)
689*35238bceSAndroid Build Coastguard Worker {
690*35238bceSAndroid Build Coastguard Worker     bool isFirstOutput = true;
691*35238bceSAndroid Build Coastguard Worker 
692*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < (int)valueBlock.values.size(); ndx++)
693*35238bceSAndroid Build Coastguard Worker     {
694*35238bceSAndroid Build Coastguard Worker         const ShaderCase::Value &val = valueBlock.values[ndx];
695*35238bceSAndroid Build Coastguard Worker         const char *valueName        = val.valueName.c_str();
696*35238bceSAndroid Build Coastguard Worker 
697*35238bceSAndroid Build Coastguard Worker         if (val.storageType == ShaderCase::Value::STORAGE_OUTPUT)
698*35238bceSAndroid Build Coastguard Worker         {
699*35238bceSAndroid Build Coastguard Worker             // Check if we're only interested in one variable (then skip if not the right one).
700*35238bceSAndroid Build Coastguard Worker             if (checkVarName && !deStringEqual(valueName, checkVarName))
701*35238bceSAndroid Build Coastguard Worker                 continue;
702*35238bceSAndroid Build Coastguard Worker 
703*35238bceSAndroid Build Coastguard Worker             // Prefix.
704*35238bceSAndroid Build Coastguard Worker             if (isFirstOutput)
705*35238bceSAndroid Build Coastguard Worker             {
706*35238bceSAndroid Build Coastguard Worker                 output << "bool RES = ";
707*35238bceSAndroid Build Coastguard Worker                 isFirstOutput = false;
708*35238bceSAndroid Build Coastguard Worker             }
709*35238bceSAndroid Build Coastguard Worker             else
710*35238bceSAndroid Build Coastguard Worker                 output << "RES = RES && ";
711*35238bceSAndroid Build Coastguard Worker 
712*35238bceSAndroid Build Coastguard Worker             // Generate actual comparison.
713*35238bceSAndroid Build Coastguard Worker             if (getDataTypeScalarType(val.dataType) == TYPE_FLOAT)
714*35238bceSAndroid Build Coastguard Worker                 output << "isOk(" << valueName << ", ref_" << valueName << ", 0.05);\n";
715*35238bceSAndroid Build Coastguard Worker             else
716*35238bceSAndroid Build Coastguard Worker                 output << "isOk(" << nonFloatNamePrefix << valueName << ", ref_" << valueName << ");\n";
717*35238bceSAndroid Build Coastguard Worker         }
718*35238bceSAndroid Build Coastguard Worker         // \note Uniforms are already declared in shader.
719*35238bceSAndroid Build Coastguard Worker     }
720*35238bceSAndroid Build Coastguard Worker 
721*35238bceSAndroid Build Coastguard Worker     if (isFirstOutput)
722*35238bceSAndroid Build Coastguard Worker         output << dstVec4Var << " = vec4(1.0);\n"; // \todo [petri] Should we give warning if not expect-failure case?
723*35238bceSAndroid Build Coastguard Worker     else
724*35238bceSAndroid Build Coastguard Worker         output << dstVec4Var << " = vec4(RES, RES, RES, 1.0);\n";
725*35238bceSAndroid Build Coastguard Worker }
726*35238bceSAndroid Build Coastguard Worker 
genFragmentShader(const ValueBlock & valueBlock)727*35238bceSAndroid Build Coastguard Worker string ShaderCase::genFragmentShader(const ValueBlock &valueBlock)
728*35238bceSAndroid Build Coastguard Worker {
729*35238bceSAndroid Build Coastguard Worker     ostringstream shader;
730*35238bceSAndroid Build Coastguard Worker     const bool usesInout      = usesShaderInoutQualifiers(m_targetVersion);
731*35238bceSAndroid Build Coastguard Worker     const bool customColorOut = usesInout;
732*35238bceSAndroid Build Coastguard Worker     const char *fragIn        = usesInout ? "in" : "varying";
733*35238bceSAndroid Build Coastguard Worker 
734*35238bceSAndroid Build Coastguard Worker     shader << glu::getGLSLVersionDeclaration(m_targetVersion) << "\n";
735*35238bceSAndroid Build Coastguard Worker 
736*35238bceSAndroid Build Coastguard Worker     shader << "precision mediump float;\n";
737*35238bceSAndroid Build Coastguard Worker     shader << "precision mediump int;\n";
738*35238bceSAndroid Build Coastguard Worker     shader << "\n";
739*35238bceSAndroid Build Coastguard Worker 
740*35238bceSAndroid Build Coastguard Worker     if (customColorOut)
741*35238bceSAndroid Build Coastguard Worker     {
742*35238bceSAndroid Build Coastguard Worker         shader << "layout(location = 0) out mediump vec4 dEQP_FragColor;\n";
743*35238bceSAndroid Build Coastguard Worker         shader << "\n";
744*35238bceSAndroid Build Coastguard Worker     }
745*35238bceSAndroid Build Coastguard Worker 
746*35238bceSAndroid Build Coastguard Worker     genCompareFunctions(shader, valueBlock, true);
747*35238bceSAndroid Build Coastguard Worker     shader << "\n";
748*35238bceSAndroid Build Coastguard Worker 
749*35238bceSAndroid Build Coastguard Worker     // Declarations (varying, reference for each output).
750*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < (int)valueBlock.values.size(); ndx++)
751*35238bceSAndroid Build Coastguard Worker     {
752*35238bceSAndroid Build Coastguard Worker         const ShaderCase::Value &val = valueBlock.values[ndx];
753*35238bceSAndroid Build Coastguard Worker         DataType floatType           = getDataTypeFloatScalars(val.dataType);
754*35238bceSAndroid Build Coastguard Worker         const char *floatTypeStr     = getDataTypeName(floatType);
755*35238bceSAndroid Build Coastguard Worker         const char *refTypeStr       = getDataTypeName(val.dataType);
756*35238bceSAndroid Build Coastguard Worker 
757*35238bceSAndroid Build Coastguard Worker         if (val.storageType == ShaderCase::Value::STORAGE_OUTPUT)
758*35238bceSAndroid Build Coastguard Worker         {
759*35238bceSAndroid Build Coastguard Worker             if (getDataTypeScalarType(val.dataType) == TYPE_FLOAT)
760*35238bceSAndroid Build Coastguard Worker                 shader << fragIn << " " << floatTypeStr << " " << val.valueName << ";\n";
761*35238bceSAndroid Build Coastguard Worker             else
762*35238bceSAndroid Build Coastguard Worker                 shader << fragIn << " " << floatTypeStr << " v_" << val.valueName << ";\n";
763*35238bceSAndroid Build Coastguard Worker 
764*35238bceSAndroid Build Coastguard Worker             shader << "uniform " << refTypeStr << " ref_" << val.valueName << ";\n";
765*35238bceSAndroid Build Coastguard Worker         }
766*35238bceSAndroid Build Coastguard Worker     }
767*35238bceSAndroid Build Coastguard Worker 
768*35238bceSAndroid Build Coastguard Worker     shader << "\n";
769*35238bceSAndroid Build Coastguard Worker     shader << "void main()\n";
770*35238bceSAndroid Build Coastguard Worker     shader << "{\n";
771*35238bceSAndroid Build Coastguard Worker 
772*35238bceSAndroid Build Coastguard Worker     shader << " ";
773*35238bceSAndroid Build Coastguard Worker     genCompareOp(shader, customColorOut ? "dEQP_FragColor" : "gl_FragColor", valueBlock, "v_", DE_NULL);
774*35238bceSAndroid Build Coastguard Worker 
775*35238bceSAndroid Build Coastguard Worker     shader << "}\n";
776*35238bceSAndroid Build Coastguard Worker     return shader.str();
777*35238bceSAndroid Build Coastguard Worker }
778*35238bceSAndroid Build Coastguard Worker 
779*35238bceSAndroid Build Coastguard Worker // Specialize a shader for the vertex shader test case.
specializeVertexShader(const char * src,const ValueBlock & valueBlock)780*35238bceSAndroid Build Coastguard Worker string ShaderCase::specializeVertexShader(const char *src, const ValueBlock &valueBlock)
781*35238bceSAndroid Build Coastguard Worker {
782*35238bceSAndroid Build Coastguard Worker     ostringstream decl;
783*35238bceSAndroid Build Coastguard Worker     ostringstream setup;
784*35238bceSAndroid Build Coastguard Worker     ostringstream output;
785*35238bceSAndroid Build Coastguard Worker     const bool usesInout = usesShaderInoutQualifiers(m_targetVersion);
786*35238bceSAndroid Build Coastguard Worker     const char *vtxIn    = usesInout ? "in" : "attribute";
787*35238bceSAndroid Build Coastguard Worker     const char *vtxOut   = usesInout ? "out" : "varying";
788*35238bceSAndroid Build Coastguard Worker 
789*35238bceSAndroid Build Coastguard Worker     // Output (write out position).
790*35238bceSAndroid Build Coastguard Worker     output << "gl_Position = dEQP_Position;\n";
791*35238bceSAndroid Build Coastguard Worker 
792*35238bceSAndroid Build Coastguard Worker     // Declarations (position + attribute for each input, varying for each output).
793*35238bceSAndroid Build Coastguard Worker     decl << vtxIn << " highp vec4 dEQP_Position;\n";
794*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < (int)valueBlock.values.size(); ndx++)
795*35238bceSAndroid Build Coastguard Worker     {
796*35238bceSAndroid Build Coastguard Worker         const ShaderCase::Value &val = valueBlock.values[ndx];
797*35238bceSAndroid Build Coastguard Worker         const char *valueName        = val.valueName.c_str();
798*35238bceSAndroid Build Coastguard Worker         DataType floatType           = getDataTypeFloatScalars(val.dataType);
799*35238bceSAndroid Build Coastguard Worker         const char *floatTypeStr     = getDataTypeName(floatType);
800*35238bceSAndroid Build Coastguard Worker         const char *refTypeStr       = getDataTypeName(val.dataType);
801*35238bceSAndroid Build Coastguard Worker 
802*35238bceSAndroid Build Coastguard Worker         if (val.storageType == ShaderCase::Value::STORAGE_INPUT)
803*35238bceSAndroid Build Coastguard Worker         {
804*35238bceSAndroid Build Coastguard Worker             if (getDataTypeScalarType(val.dataType) == TYPE_FLOAT)
805*35238bceSAndroid Build Coastguard Worker             {
806*35238bceSAndroid Build Coastguard Worker                 decl << vtxIn << " " << floatTypeStr << " " << valueName << ";\n";
807*35238bceSAndroid Build Coastguard Worker             }
808*35238bceSAndroid Build Coastguard Worker             else
809*35238bceSAndroid Build Coastguard Worker             {
810*35238bceSAndroid Build Coastguard Worker                 decl << vtxIn << " " << floatTypeStr << " a_" << valueName << ";\n";
811*35238bceSAndroid Build Coastguard Worker                 setup << refTypeStr << " " << valueName << " = " << refTypeStr << "(a_" << valueName << ");\n";
812*35238bceSAndroid Build Coastguard Worker             }
813*35238bceSAndroid Build Coastguard Worker         }
814*35238bceSAndroid Build Coastguard Worker         else if (val.storageType == ShaderCase::Value::STORAGE_OUTPUT)
815*35238bceSAndroid Build Coastguard Worker         {
816*35238bceSAndroid Build Coastguard Worker             if (getDataTypeScalarType(val.dataType) == TYPE_FLOAT)
817*35238bceSAndroid Build Coastguard Worker                 decl << vtxOut << " " << floatTypeStr << " " << valueName << ";\n";
818*35238bceSAndroid Build Coastguard Worker             else
819*35238bceSAndroid Build Coastguard Worker             {
820*35238bceSAndroid Build Coastguard Worker                 decl << vtxOut << " " << floatTypeStr << " v_" << valueName << ";\n";
821*35238bceSAndroid Build Coastguard Worker                 decl << refTypeStr << " " << valueName << ";\n";
822*35238bceSAndroid Build Coastguard Worker 
823*35238bceSAndroid Build Coastguard Worker                 output << "v_" << valueName << " = " << floatTypeStr << "(" << valueName << ");\n";
824*35238bceSAndroid Build Coastguard Worker             }
825*35238bceSAndroid Build Coastguard Worker         }
826*35238bceSAndroid Build Coastguard Worker     }
827*35238bceSAndroid Build Coastguard Worker 
828*35238bceSAndroid Build Coastguard Worker     // Shader specialization.
829*35238bceSAndroid Build Coastguard Worker     map<string, string> params;
830*35238bceSAndroid Build Coastguard Worker     params.insert(pair<string, string>("DECLARATIONS", decl.str()));
831*35238bceSAndroid Build Coastguard Worker     params.insert(pair<string, string>("SETUP", setup.str()));
832*35238bceSAndroid Build Coastguard Worker     params.insert(pair<string, string>("OUTPUT", output.str()));
833*35238bceSAndroid Build Coastguard Worker     params.insert(pair<string, string>("POSITION_FRAG_COLOR", "gl_Position"));
834*35238bceSAndroid Build Coastguard Worker 
835*35238bceSAndroid Build Coastguard Worker     StringTemplate tmpl(src);
836*35238bceSAndroid Build Coastguard Worker     return tmpl.specialize(params);
837*35238bceSAndroid Build Coastguard Worker }
838*35238bceSAndroid Build Coastguard Worker 
839*35238bceSAndroid Build Coastguard Worker // Specialize a shader for the fragment shader test case.
specializeFragmentShader(const char * src,const ValueBlock & valueBlock)840*35238bceSAndroid Build Coastguard Worker string ShaderCase::specializeFragmentShader(const char *src, const ValueBlock &valueBlock)
841*35238bceSAndroid Build Coastguard Worker {
842*35238bceSAndroid Build Coastguard Worker     ostringstream decl;
843*35238bceSAndroid Build Coastguard Worker     ostringstream setup;
844*35238bceSAndroid Build Coastguard Worker     ostringstream output;
845*35238bceSAndroid Build Coastguard Worker 
846*35238bceSAndroid Build Coastguard Worker     const bool usesInout      = usesShaderInoutQualifiers(m_targetVersion);
847*35238bceSAndroid Build Coastguard Worker     const bool customColorOut = usesInout;
848*35238bceSAndroid Build Coastguard Worker     const char *fragIn        = usesInout ? "in" : "varying";
849*35238bceSAndroid Build Coastguard Worker     const char *fragColor     = customColorOut ? "dEQP_FragColor" : "gl_FragColor";
850*35238bceSAndroid Build Coastguard Worker 
851*35238bceSAndroid Build Coastguard Worker     genCompareFunctions(decl, valueBlock, false);
852*35238bceSAndroid Build Coastguard Worker     genCompareOp(output, fragColor, valueBlock, "", DE_NULL);
853*35238bceSAndroid Build Coastguard Worker 
854*35238bceSAndroid Build Coastguard Worker     if (customColorOut)
855*35238bceSAndroid Build Coastguard Worker         decl << "layout(location = 0) out mediump vec4 dEQP_FragColor;\n";
856*35238bceSAndroid Build Coastguard Worker 
857*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < (int)valueBlock.values.size(); ndx++)
858*35238bceSAndroid Build Coastguard Worker     {
859*35238bceSAndroid Build Coastguard Worker         const ShaderCase::Value &val = valueBlock.values[ndx];
860*35238bceSAndroid Build Coastguard Worker         const char *valueName        = val.valueName.c_str();
861*35238bceSAndroid Build Coastguard Worker         DataType floatType           = getDataTypeFloatScalars(val.dataType);
862*35238bceSAndroid Build Coastguard Worker         const char *floatTypeStr     = getDataTypeName(floatType);
863*35238bceSAndroid Build Coastguard Worker         const char *refTypeStr       = getDataTypeName(val.dataType);
864*35238bceSAndroid Build Coastguard Worker 
865*35238bceSAndroid Build Coastguard Worker         if (val.storageType == ShaderCase::Value::STORAGE_INPUT)
866*35238bceSAndroid Build Coastguard Worker         {
867*35238bceSAndroid Build Coastguard Worker             if (getDataTypeScalarType(val.dataType) == TYPE_FLOAT)
868*35238bceSAndroid Build Coastguard Worker                 decl << fragIn << " " << floatTypeStr << " " << valueName << ";\n";
869*35238bceSAndroid Build Coastguard Worker             else
870*35238bceSAndroid Build Coastguard Worker             {
871*35238bceSAndroid Build Coastguard Worker                 decl << fragIn << " " << floatTypeStr << " v_" << valueName << ";\n";
872*35238bceSAndroid Build Coastguard Worker                 std::string offset =
873*35238bceSAndroid Build Coastguard Worker                     isDataTypeIntOrIVec(val.dataType) ?
874*35238bceSAndroid Build Coastguard Worker                         " * 1.0025" :
875*35238bceSAndroid Build Coastguard Worker                         ""; // \todo [petri] bit of a hack to avoid errors in chop() due to varying interpolation
876*35238bceSAndroid Build Coastguard Worker                 setup << refTypeStr << " " << valueName << " = " << refTypeStr << "(v_" << valueName << offset
877*35238bceSAndroid Build Coastguard Worker                       << ");\n";
878*35238bceSAndroid Build Coastguard Worker             }
879*35238bceSAndroid Build Coastguard Worker         }
880*35238bceSAndroid Build Coastguard Worker         else if (val.storageType == ShaderCase::Value::STORAGE_OUTPUT)
881*35238bceSAndroid Build Coastguard Worker         {
882*35238bceSAndroid Build Coastguard Worker             decl << "uniform " << refTypeStr << " ref_" << valueName << ";\n";
883*35238bceSAndroid Build Coastguard Worker             decl << refTypeStr << " " << valueName << ";\n";
884*35238bceSAndroid Build Coastguard Worker         }
885*35238bceSAndroid Build Coastguard Worker     }
886*35238bceSAndroid Build Coastguard Worker 
887*35238bceSAndroid Build Coastguard Worker     /* \todo [2010-04-01 petri] Check all outputs. */
888*35238bceSAndroid Build Coastguard Worker 
889*35238bceSAndroid Build Coastguard Worker     // Shader specialization.
890*35238bceSAndroid Build Coastguard Worker     map<string, string> params;
891*35238bceSAndroid Build Coastguard Worker     params.insert(pair<string, string>("DECLARATIONS", decl.str()));
892*35238bceSAndroid Build Coastguard Worker     params.insert(pair<string, string>("SETUP", setup.str()));
893*35238bceSAndroid Build Coastguard Worker     params.insert(pair<string, string>("OUTPUT", output.str()));
894*35238bceSAndroid Build Coastguard Worker     params.insert(pair<string, string>("POSITION_FRAG_COLOR", fragColor));
895*35238bceSAndroid Build Coastguard Worker 
896*35238bceSAndroid Build Coastguard Worker     StringTemplate tmpl(src);
897*35238bceSAndroid Build Coastguard Worker     return tmpl.specialize(params);
898*35238bceSAndroid Build Coastguard Worker }
899*35238bceSAndroid Build Coastguard Worker 
specializeShaders(const char * vertexSource,const char * fragmentSource,string & outVertexSource,string & outFragmentSource,const ValueBlock & valueBlock)900*35238bceSAndroid Build Coastguard Worker void ShaderCase::specializeShaders(const char *vertexSource, const char *fragmentSource, string &outVertexSource,
901*35238bceSAndroid Build Coastguard Worker                                    string &outFragmentSource, const ValueBlock &valueBlock)
902*35238bceSAndroid Build Coastguard Worker {
903*35238bceSAndroid Build Coastguard Worker     const bool usesInout      = usesShaderInoutQualifiers(m_targetVersion);
904*35238bceSAndroid Build Coastguard Worker     const bool customColorOut = usesInout;
905*35238bceSAndroid Build Coastguard Worker 
906*35238bceSAndroid Build Coastguard Worker     // Vertex shader specialization.
907*35238bceSAndroid Build Coastguard Worker     {
908*35238bceSAndroid Build Coastguard Worker         ostringstream decl;
909*35238bceSAndroid Build Coastguard Worker         ostringstream setup;
910*35238bceSAndroid Build Coastguard Worker         const char *vtxIn = usesInout ? "in" : "attribute";
911*35238bceSAndroid Build Coastguard Worker 
912*35238bceSAndroid Build Coastguard Worker         decl << vtxIn << " highp vec4 dEQP_Position;\n";
913*35238bceSAndroid Build Coastguard Worker 
914*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < (int)valueBlock.values.size(); ndx++)
915*35238bceSAndroid Build Coastguard Worker         {
916*35238bceSAndroid Build Coastguard Worker             const ShaderCase::Value &val = valueBlock.values[ndx];
917*35238bceSAndroid Build Coastguard Worker             const char *typeStr          = getDataTypeName(val.dataType);
918*35238bceSAndroid Build Coastguard Worker 
919*35238bceSAndroid Build Coastguard Worker             if (val.storageType == ShaderCase::Value::STORAGE_INPUT)
920*35238bceSAndroid Build Coastguard Worker             {
921*35238bceSAndroid Build Coastguard Worker                 if (getDataTypeScalarType(val.dataType) == TYPE_FLOAT)
922*35238bceSAndroid Build Coastguard Worker                 {
923*35238bceSAndroid Build Coastguard Worker                     decl << vtxIn << " " << typeStr << " " << val.valueName << ";\n";
924*35238bceSAndroid Build Coastguard Worker                 }
925*35238bceSAndroid Build Coastguard Worker                 else
926*35238bceSAndroid Build Coastguard Worker                 {
927*35238bceSAndroid Build Coastguard Worker                     DataType floatType       = getDataTypeFloatScalars(val.dataType);
928*35238bceSAndroid Build Coastguard Worker                     const char *floatTypeStr = getDataTypeName(floatType);
929*35238bceSAndroid Build Coastguard Worker 
930*35238bceSAndroid Build Coastguard Worker                     decl << vtxIn << " " << floatTypeStr << " a_" << val.valueName << ";\n";
931*35238bceSAndroid Build Coastguard Worker                     setup << typeStr << " " << val.valueName << " = " << typeStr << "(a_" << val.valueName << ");\n";
932*35238bceSAndroid Build Coastguard Worker                 }
933*35238bceSAndroid Build Coastguard Worker             }
934*35238bceSAndroid Build Coastguard Worker             else if (val.storageType == ShaderCase::Value::STORAGE_UNIFORM && val.valueName.find('.') == string::npos)
935*35238bceSAndroid Build Coastguard Worker             {
936*35238bceSAndroid Build Coastguard Worker                 decl << "uniform " << typeStr << " " << val.valueName << ";\n";
937*35238bceSAndroid Build Coastguard Worker             }
938*35238bceSAndroid Build Coastguard Worker         }
939*35238bceSAndroid Build Coastguard Worker 
940*35238bceSAndroid Build Coastguard Worker         map<string, string> params;
941*35238bceSAndroid Build Coastguard Worker         params.insert(pair<string, string>("VERTEX_DECLARATIONS", decl.str()));
942*35238bceSAndroid Build Coastguard Worker         params.insert(pair<string, string>("VERTEX_SETUP", setup.str()));
943*35238bceSAndroid Build Coastguard Worker         params.insert(pair<string, string>("VERTEX_OUTPUT", string("gl_Position = dEQP_Position;\n")));
944*35238bceSAndroid Build Coastguard Worker         StringTemplate tmpl(vertexSource);
945*35238bceSAndroid Build Coastguard Worker         outVertexSource = tmpl.specialize(params);
946*35238bceSAndroid Build Coastguard Worker     }
947*35238bceSAndroid Build Coastguard Worker 
948*35238bceSAndroid Build Coastguard Worker     // Fragment shader specialization.
949*35238bceSAndroid Build Coastguard Worker     {
950*35238bceSAndroid Build Coastguard Worker         ostringstream decl;
951*35238bceSAndroid Build Coastguard Worker         ostringstream output;
952*35238bceSAndroid Build Coastguard Worker         const char *fragColor = customColorOut ? "dEQP_FragColor" : "gl_FragColor";
953*35238bceSAndroid Build Coastguard Worker 
954*35238bceSAndroid Build Coastguard Worker         genCompareFunctions(decl, valueBlock, false);
955*35238bceSAndroid Build Coastguard Worker         genCompareOp(output, fragColor, valueBlock, "", DE_NULL);
956*35238bceSAndroid Build Coastguard Worker 
957*35238bceSAndroid Build Coastguard Worker         if (customColorOut)
958*35238bceSAndroid Build Coastguard Worker             decl << "layout(location = 0) out mediump vec4 dEQP_FragColor;\n";
959*35238bceSAndroid Build Coastguard Worker 
960*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < (int)valueBlock.values.size(); ndx++)
961*35238bceSAndroid Build Coastguard Worker         {
962*35238bceSAndroid Build Coastguard Worker             const ShaderCase::Value &val = valueBlock.values[ndx];
963*35238bceSAndroid Build Coastguard Worker             const char *valueName        = val.valueName.c_str();
964*35238bceSAndroid Build Coastguard Worker             const char *refTypeStr       = getDataTypeName(val.dataType);
965*35238bceSAndroid Build Coastguard Worker 
966*35238bceSAndroid Build Coastguard Worker             if (val.storageType == ShaderCase::Value::STORAGE_OUTPUT)
967*35238bceSAndroid Build Coastguard Worker             {
968*35238bceSAndroid Build Coastguard Worker                 decl << "uniform " << refTypeStr << " ref_" << valueName << ";\n";
969*35238bceSAndroid Build Coastguard Worker                 decl << refTypeStr << " " << valueName << ";\n";
970*35238bceSAndroid Build Coastguard Worker             }
971*35238bceSAndroid Build Coastguard Worker             else if (val.storageType == ShaderCase::Value::STORAGE_UNIFORM && val.valueName.find('.') == string::npos)
972*35238bceSAndroid Build Coastguard Worker             {
973*35238bceSAndroid Build Coastguard Worker                 decl << "uniform " << refTypeStr << " " << valueName << ";\n";
974*35238bceSAndroid Build Coastguard Worker             }
975*35238bceSAndroid Build Coastguard Worker         }
976*35238bceSAndroid Build Coastguard Worker 
977*35238bceSAndroid Build Coastguard Worker         map<string, string> params;
978*35238bceSAndroid Build Coastguard Worker         params.insert(pair<string, string>("FRAGMENT_DECLARATIONS", decl.str()));
979*35238bceSAndroid Build Coastguard Worker         params.insert(pair<string, string>("FRAGMENT_OUTPUT", output.str()));
980*35238bceSAndroid Build Coastguard Worker         params.insert(pair<string, string>("FRAG_COLOR", fragColor));
981*35238bceSAndroid Build Coastguard Worker         StringTemplate tmpl(fragmentSource);
982*35238bceSAndroid Build Coastguard Worker         outFragmentSource = tmpl.specialize(params);
983*35238bceSAndroid Build Coastguard Worker     }
984*35238bceSAndroid Build Coastguard Worker }
985*35238bceSAndroid Build Coastguard Worker 
dumpValues(const ValueBlock & valueBlock,int arrayNdx)986*35238bceSAndroid Build Coastguard Worker void ShaderCase::dumpValues(const ValueBlock &valueBlock, int arrayNdx)
987*35238bceSAndroid Build Coastguard Worker {
988*35238bceSAndroid Build Coastguard Worker     vector<vector<float>> attribValues;
989*35238bceSAndroid Build Coastguard Worker 
990*35238bceSAndroid Build Coastguard Worker     int numValues = (int)valueBlock.values.size();
991*35238bceSAndroid Build Coastguard Worker     for (int valNdx = 0; valNdx < numValues; valNdx++)
992*35238bceSAndroid Build Coastguard Worker     {
993*35238bceSAndroid Build Coastguard Worker         const ShaderCase::Value &val = valueBlock.values[valNdx];
994*35238bceSAndroid Build Coastguard Worker         const char *valueName        = val.valueName.c_str();
995*35238bceSAndroid Build Coastguard Worker         DataType dataType            = val.dataType;
996*35238bceSAndroid Build Coastguard Worker         int scalarSize               = getDataTypeScalarSize(val.dataType);
997*35238bceSAndroid Build Coastguard Worker         ostringstream result;
998*35238bceSAndroid Build Coastguard Worker 
999*35238bceSAndroid Build Coastguard Worker         result << "    ";
1000*35238bceSAndroid Build Coastguard Worker         if (val.storageType == Value::STORAGE_INPUT)
1001*35238bceSAndroid Build Coastguard Worker             result << "input ";
1002*35238bceSAndroid Build Coastguard Worker         else if (val.storageType == Value::STORAGE_UNIFORM)
1003*35238bceSAndroid Build Coastguard Worker             result << "uniform ";
1004*35238bceSAndroid Build Coastguard Worker         else if (val.storageType == Value::STORAGE_OUTPUT)
1005*35238bceSAndroid Build Coastguard Worker             result << "expected ";
1006*35238bceSAndroid Build Coastguard Worker 
1007*35238bceSAndroid Build Coastguard Worker         result << getDataTypeName(dataType) << " " << valueName << ":";
1008*35238bceSAndroid Build Coastguard Worker 
1009*35238bceSAndroid Build Coastguard Worker         if (isDataTypeScalar(dataType))
1010*35238bceSAndroid Build Coastguard Worker             result << " ";
1011*35238bceSAndroid Build Coastguard Worker         if (isDataTypeVector(dataType))
1012*35238bceSAndroid Build Coastguard Worker             result << " [ ";
1013*35238bceSAndroid Build Coastguard Worker         else if (isDataTypeMatrix(dataType))
1014*35238bceSAndroid Build Coastguard Worker             result << "\n";
1015*35238bceSAndroid Build Coastguard Worker 
1016*35238bceSAndroid Build Coastguard Worker         if (isDataTypeScalarOrVector(dataType))
1017*35238bceSAndroid Build Coastguard Worker         {
1018*35238bceSAndroid Build Coastguard Worker             for (int scalarNdx = 0; scalarNdx < scalarSize; scalarNdx++)
1019*35238bceSAndroid Build Coastguard Worker             {
1020*35238bceSAndroid Build Coastguard Worker                 int elemNdx             = (val.arrayLength == 1) ? 0 : arrayNdx;
1021*35238bceSAndroid Build Coastguard Worker                 const Value::Element &e = val.elements[elemNdx * scalarSize + scalarNdx];
1022*35238bceSAndroid Build Coastguard Worker                 result << ((scalarNdx != 0) ? ", " : "");
1023*35238bceSAndroid Build Coastguard Worker 
1024*35238bceSAndroid Build Coastguard Worker                 if (isDataTypeFloatOrVec(dataType))
1025*35238bceSAndroid Build Coastguard Worker                     result << e.float32;
1026*35238bceSAndroid Build Coastguard Worker                 else if (isDataTypeIntOrIVec(dataType))
1027*35238bceSAndroid Build Coastguard Worker                     result << e.int32;
1028*35238bceSAndroid Build Coastguard Worker                 else if (isDataTypeBoolOrBVec(dataType))
1029*35238bceSAndroid Build Coastguard Worker                     result << (e.bool32 ? "true" : "false");
1030*35238bceSAndroid Build Coastguard Worker             }
1031*35238bceSAndroid Build Coastguard Worker         }
1032*35238bceSAndroid Build Coastguard Worker         else if (isDataTypeMatrix(dataType))
1033*35238bceSAndroid Build Coastguard Worker         {
1034*35238bceSAndroid Build Coastguard Worker             int numRows = getDataTypeMatrixNumRows(dataType);
1035*35238bceSAndroid Build Coastguard Worker             int numCols = getDataTypeMatrixNumColumns(dataType);
1036*35238bceSAndroid Build Coastguard Worker             for (int rowNdx = 0; rowNdx < numRows; rowNdx++)
1037*35238bceSAndroid Build Coastguard Worker             {
1038*35238bceSAndroid Build Coastguard Worker                 result << "       [ ";
1039*35238bceSAndroid Build Coastguard Worker                 for (int colNdx = 0; colNdx < numCols; colNdx++)
1040*35238bceSAndroid Build Coastguard Worker                 {
1041*35238bceSAndroid Build Coastguard Worker                     int elemNdx = (val.arrayLength == 1) ? 0 : arrayNdx;
1042*35238bceSAndroid Build Coastguard Worker                     float v     = val.elements[elemNdx * scalarSize + rowNdx * numCols + colNdx].float32;
1043*35238bceSAndroid Build Coastguard Worker                     result << ((colNdx == 0) ? "" : ", ") << v;
1044*35238bceSAndroid Build Coastguard Worker                 }
1045*35238bceSAndroid Build Coastguard Worker                 result << " ]\n";
1046*35238bceSAndroid Build Coastguard Worker             }
1047*35238bceSAndroid Build Coastguard Worker         }
1048*35238bceSAndroid Build Coastguard Worker 
1049*35238bceSAndroid Build Coastguard Worker         if (isDataTypeScalar(dataType))
1050*35238bceSAndroid Build Coastguard Worker             result << "\n";
1051*35238bceSAndroid Build Coastguard Worker         else if (isDataTypeVector(dataType))
1052*35238bceSAndroid Build Coastguard Worker             result << " ]\n";
1053*35238bceSAndroid Build Coastguard Worker 
1054*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Message << result.str() << TestLog::EndMessage;
1055*35238bceSAndroid Build Coastguard Worker     }
1056*35238bceSAndroid Build Coastguard Worker }
1057*35238bceSAndroid Build Coastguard Worker 
1058*35238bceSAndroid Build Coastguard Worker } // namespace sl
1059*35238bceSAndroid Build Coastguard Worker } // namespace deqp
1060