Merge "Check only what's needed and use threshold"
[platform/upstream/VK-GL-CTS.git] / modules / glshared / glsTextureTestUtil.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL (ES) Module
3  * -----------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Texture test utilities.
22  *//*--------------------------------------------------------------------*/
23
24 #include "glsTextureTestUtil.hpp"
25 #include "gluDefs.hpp"
26 #include "gluDrawUtil.hpp"
27 #include "gluRenderContext.hpp"
28 #include "deRandom.hpp"
29 #include "tcuTestLog.hpp"
30 #include "tcuVectorUtil.hpp"
31 #include "tcuTextureUtil.hpp"
32 #include "tcuImageCompare.hpp"
33 #include "tcuStringTemplate.hpp"
34 #include "tcuTexLookupVerifier.hpp"
35 #include "tcuTexVerifierUtil.hpp"
36 #include "glwEnums.hpp"
37 #include "glwFunctions.hpp"
38 #include "qpWatchDog.h"
39 #include "deStringUtil.hpp"
40
41 using tcu::TestLog;
42 using std::vector;
43 using std::string;
44 using std::map;
45
46 using namespace glu::TextureTestUtil;
47
48 namespace deqp
49 {
50 namespace gls
51 {
52 namespace TextureTestUtil
53 {
54
55 RandomViewport::RandomViewport (const tcu::RenderTarget& renderTarget, int preferredWidth, int preferredHeight, deUint32 seed)
56         : x                     (0)
57         , y                     (0)
58         , width         (deMin32(preferredWidth, renderTarget.getWidth()))
59         , height        (deMin32(preferredHeight, renderTarget.getHeight()))
60 {
61         de::Random rnd(seed);
62         x = rnd.getInt(0, renderTarget.getWidth()       - width);
63         y = rnd.getInt(0, renderTarget.getHeight()      - height);
64 }
65
66 ProgramLibrary::ProgramLibrary (const glu::RenderContext& context, tcu::TestLog& log, glu::GLSLVersion glslVersion, glu::Precision texCoordPrecision)
67         : m_context                             (context)
68         , m_log                                 (log)
69         , m_glslVersion                 (glslVersion)
70         , m_texCoordPrecision   (texCoordPrecision)
71 {
72 }
73
74 ProgramLibrary::~ProgramLibrary (void)
75 {
76         clear();
77 }
78
79 void ProgramLibrary::clear (void)
80 {
81         for (map<Program, glu::ShaderProgram*>::iterator i = m_programs.begin(); i != m_programs.end(); i++)
82         {
83                 delete i->second;
84                 i->second = DE_NULL;
85         }
86         m_programs.clear();
87 }
88
89 glu::ShaderProgram* ProgramLibrary::getProgram (Program program)
90 {
91         if (m_programs.find(program) != m_programs.end())
92                 return m_programs[program]; // Return from cache.
93
94         static const char* vertShaderTemplate =
95                 "${VTX_HEADER}"
96                 "${VTX_IN} highp vec4 a_position;\n"
97                 "${VTX_IN} ${PRECISION} ${TEXCOORD_TYPE} a_texCoord;\n"
98                 "${VTX_OUT} ${PRECISION} ${TEXCOORD_TYPE} v_texCoord;\n"
99                 "\n"
100                 "void main (void)\n"
101                 "{\n"
102                 "       gl_Position = a_position;\n"
103                 "       v_texCoord = a_texCoord;\n"
104                 "}\n";
105         static const char* fragShaderTemplate =
106                 "${FRAG_HEADER}"
107                 "${FRAG_IN} ${PRECISION} ${TEXCOORD_TYPE} v_texCoord;\n"
108                 "uniform ${PRECISION} float u_bias;\n"
109                 "uniform ${PRECISION} float u_ref;\n"
110                 "uniform ${PRECISION} vec4 u_colorScale;\n"
111                 "uniform ${PRECISION} vec4 u_colorBias;\n"
112                 "uniform ${PRECISION} ${SAMPLER_TYPE} u_sampler;\n"
113                 "\n"
114                 "void main (void)\n"
115                 "{\n"
116                 "       ${FRAG_COLOR} = ${LOOKUP} * u_colorScale + u_colorBias;\n"
117                 "}\n";
118
119         map<string, string> params;
120
121         bool    isCube          = de::inRange<int>(program, PROGRAM_CUBE_FLOAT, PROGRAM_CUBE_SHADOW_BIAS);
122         bool    isArray         = de::inRange<int>(program, PROGRAM_2D_ARRAY_FLOAT, PROGRAM_2D_ARRAY_SHADOW)
123                                                         || de::inRange<int>(program, PROGRAM_1D_ARRAY_FLOAT, PROGRAM_1D_ARRAY_SHADOW);
124
125         bool    is1D            = de::inRange<int>(program, PROGRAM_1D_FLOAT, PROGRAM_1D_UINT_BIAS)
126                                                         || de::inRange<int>(program, PROGRAM_1D_ARRAY_FLOAT, PROGRAM_1D_ARRAY_SHADOW)
127                                                         || de::inRange<int>(program, PROGRAM_BUFFER_FLOAT, PROGRAM_BUFFER_UINT);
128
129         bool    is2D            = de::inRange<int>(program, PROGRAM_2D_FLOAT, PROGRAM_2D_UINT_BIAS)
130                                                         || de::inRange<int>(program, PROGRAM_2D_ARRAY_FLOAT, PROGRAM_2D_ARRAY_SHADOW);
131
132         bool    is3D            = de::inRange<int>(program, PROGRAM_3D_FLOAT, PROGRAM_3D_UINT_BIAS);
133         bool    isCubeArray     = de::inRange<int>(program, PROGRAM_CUBE_ARRAY_FLOAT, PROGRAM_CUBE_ARRAY_SHADOW);
134         bool    isBuffer        = de::inRange<int>(program, PROGRAM_BUFFER_FLOAT, PROGRAM_BUFFER_UINT);
135
136         if (m_glslVersion == glu::GLSL_VERSION_100_ES)
137         {
138                 params["FRAG_HEADER"]   = "";
139                 params["VTX_HEADER"]    = "";
140                 params["VTX_IN"]                = "attribute";
141                 params["VTX_OUT"]               = "varying";
142                 params["FRAG_IN"]               = "varying";
143                 params["FRAG_COLOR"]    = "gl_FragColor";
144         }
145         else if (m_glslVersion == glu::GLSL_VERSION_300_ES || m_glslVersion == glu::GLSL_VERSION_310_ES || m_glslVersion == glu::GLSL_VERSION_320_ES || m_glslVersion == glu::GLSL_VERSION_330)
146         {
147                 const string    version = glu::getGLSLVersionDeclaration(m_glslVersion);
148                 const char*             ext             = DE_NULL;
149
150                 if (glu::glslVersionIsES(m_glslVersion) && m_glslVersion != glu::GLSL_VERSION_320_ES) {
151                         if (isCubeArray)
152                                 ext = "GL_EXT_texture_cube_map_array";
153                         else if (isBuffer)
154                                 ext = "GL_EXT_texture_buffer";
155                 }
156
157                 params["FRAG_HEADER"]   = version + (ext ? string("\n#extension ") + ext + " : require" : string()) + "\nlayout(location = 0) out mediump vec4 dEQP_FragColor;\n";
158                 params["VTX_HEADER"]    = version + "\n";
159                 params["VTX_IN"]                = "in";
160                 params["VTX_OUT"]               = "out";
161                 params["FRAG_IN"]               = "in";
162                 params["FRAG_COLOR"]    = "dEQP_FragColor";
163         }
164         else
165                 DE_FATAL("Unsupported version");
166
167         params["PRECISION"]             = glu::getPrecisionName(m_texCoordPrecision);
168
169         if (isCubeArray)
170                 params["TEXCOORD_TYPE"] = "vec4";
171         else if (isCube || (is2D && isArray) || is3D)
172                 params["TEXCOORD_TYPE"] = "vec3";
173         else if ((is1D && isArray) || is2D)
174                 params["TEXCOORD_TYPE"] = "vec2";
175         else if (is1D)
176                 params["TEXCOORD_TYPE"] = "float";
177         else
178                 DE_ASSERT(DE_FALSE);
179
180         const char*     sampler = DE_NULL;
181         const char*     lookup  = DE_NULL;
182
183         if (m_glslVersion == glu::GLSL_VERSION_300_ES || m_glslVersion == glu::GLSL_VERSION_310_ES || m_glslVersion == glu::GLSL_VERSION_320_ES || m_glslVersion == glu::GLSL_VERSION_330)
184         {
185                 switch (program)
186                 {
187                         case PROGRAM_2D_FLOAT:                  sampler = "sampler2D";                          lookup = "texture(u_sampler, v_texCoord)";                                                                                              break;
188                         case PROGRAM_2D_INT:                    sampler = "isampler2D";                         lookup = "vec4(texture(u_sampler, v_texCoord))";                                                                                break;
189                         case PROGRAM_2D_UINT:                   sampler = "usampler2D";                         lookup = "vec4(texture(u_sampler, v_texCoord))";                                                                                break;
190                         case PROGRAM_2D_SHADOW:                 sampler = "sampler2DShadow";            lookup = "vec4(texture(u_sampler, vec3(v_texCoord, u_ref)), 0.0, 0.0, 1.0)";                    break;
191                         case PROGRAM_2D_FLOAT_BIAS:             sampler = "sampler2D";                          lookup = "texture(u_sampler, v_texCoord, u_bias)";                                                                              break;
192                         case PROGRAM_2D_INT_BIAS:               sampler = "isampler2D";                         lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))";                                                                break;
193                         case PROGRAM_2D_UINT_BIAS:              sampler = "usampler2D";                         lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))";                                                                break;
194                         case PROGRAM_2D_SHADOW_BIAS:    sampler = "sampler2DShadow";            lookup = "vec4(texture(u_sampler, vec3(v_texCoord, u_ref), u_bias), 0.0, 0.0, 1.0)";    break;
195                         case PROGRAM_1D_FLOAT:                  sampler = "sampler1D";                          lookup = "texture(u_sampler, v_texCoord)";                                                                                              break;
196                         case PROGRAM_1D_INT:                    sampler = "isampler1D";                         lookup = "vec4(texture(u_sampler, v_texCoord))";                                                                                break;
197                         case PROGRAM_1D_UINT:                   sampler = "usampler1D";                         lookup = "vec4(texture(u_sampler, v_texCoord))";                                                                                break;
198                         case PROGRAM_1D_SHADOW:                 sampler = "sampler1DShadow";            lookup = "vec4(texture(u_sampler, vec3(v_texCoord, u_ref)), 0.0, 0.0, 1.0)";                    break;
199                         case PROGRAM_1D_FLOAT_BIAS:             sampler = "sampler1D";                          lookup = "texture(u_sampler, v_texCoord, u_bias)";                                                                              break;
200                         case PROGRAM_1D_INT_BIAS:               sampler = "isampler1D";                         lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))";                                                                break;
201                         case PROGRAM_1D_UINT_BIAS:              sampler = "usampler1D";                         lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))";                                                                break;
202                         case PROGRAM_1D_SHADOW_BIAS:    sampler = "sampler1DShadow";            lookup = "vec4(texture(u_sampler, vec3(v_texCoord, u_ref), u_bias), 0.0, 0.0, 1.0)";    break;
203                         case PROGRAM_CUBE_FLOAT:                sampler = "samplerCube";                        lookup = "texture(u_sampler, v_texCoord)";                                                                                              break;
204                         case PROGRAM_CUBE_INT:                  sampler = "isamplerCube";                       lookup = "vec4(texture(u_sampler, v_texCoord))";                                                                                break;
205                         case PROGRAM_CUBE_UINT:                 sampler = "usamplerCube";                       lookup = "vec4(texture(u_sampler, v_texCoord))";                                                                                break;
206                         case PROGRAM_CUBE_SHADOW:               sampler = "samplerCubeShadow";          lookup = "vec4(texture(u_sampler, vec4(v_texCoord, u_ref)), 0.0, 0.0, 1.0)";                    break;
207                         case PROGRAM_CUBE_FLOAT_BIAS:   sampler = "samplerCube";                        lookup = "texture(u_sampler, v_texCoord, u_bias)";                                                                              break;
208                         case PROGRAM_CUBE_INT_BIAS:             sampler = "isamplerCube";                       lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))";                                                                break;
209                         case PROGRAM_CUBE_UINT_BIAS:    sampler = "usamplerCube";                       lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))";                                                                break;
210                         case PROGRAM_CUBE_SHADOW_BIAS:  sampler = "samplerCubeShadow";          lookup = "vec4(texture(u_sampler, vec4(v_texCoord, u_ref), u_bias), 0.0, 0.0, 1.0)";    break;
211                         case PROGRAM_2D_ARRAY_FLOAT:    sampler = "sampler2DArray";                     lookup = "texture(u_sampler, v_texCoord)";                                                                                              break;
212                         case PROGRAM_2D_ARRAY_INT:              sampler = "isampler2DArray";            lookup = "vec4(texture(u_sampler, v_texCoord))";                                                                                break;
213                         case PROGRAM_2D_ARRAY_UINT:             sampler = "usampler2DArray";            lookup = "vec4(texture(u_sampler, v_texCoord))";                                                                                break;
214                         case PROGRAM_2D_ARRAY_SHADOW:   sampler = "sampler2DArrayShadow";       lookup = "vec4(texture(u_sampler, vec4(v_texCoord, u_ref)), 0.0, 0.0, 1.0)";                    break;
215                         case PROGRAM_3D_FLOAT:                  sampler = "sampler3D";                          lookup = "texture(u_sampler, v_texCoord)";                                                                                              break;
216                         case PROGRAM_3D_INT:                    sampler = "isampler3D";                         lookup = "vec4(texture(u_sampler, v_texCoord))";                                                                                break;
217                         case PROGRAM_3D_UINT:                   sampler = "usampler3D";                         lookup = "vec4(texture(u_sampler, v_texCoord))";                                                                                break;
218                         case PROGRAM_3D_FLOAT_BIAS:             sampler = "sampler3D";                          lookup = "texture(u_sampler, v_texCoord, u_bias)";                                                                              break;
219                         case PROGRAM_3D_INT_BIAS:               sampler = "isampler3D";                         lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))";                                                                break;
220                         case PROGRAM_3D_UINT_BIAS:              sampler = "usampler3D";                         lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))";                                                                break;
221                         case PROGRAM_CUBE_ARRAY_FLOAT:  sampler = "samplerCubeArray";           lookup = "texture(u_sampler, v_texCoord)";                                                                                              break;
222                         case PROGRAM_CUBE_ARRAY_INT:    sampler = "isamplerCubeArray";          lookup = "vec4(texture(u_sampler, v_texCoord))";                                                                                break;
223                         case PROGRAM_CUBE_ARRAY_UINT:   sampler = "usamplerCubeArray";          lookup = "vec4(texture(u_sampler, v_texCoord))";                                                                                break;
224                         case PROGRAM_CUBE_ARRAY_SHADOW: sampler = "samplerCubeArrayShadow";     lookup = "vec4(texture(u_sampler, vec4(v_texCoord, u_ref)), 0.0, 0.0, 1.0)";                    break;
225                         case PROGRAM_1D_ARRAY_FLOAT:    sampler = "sampler1DArray";                     lookup = "texture(u_sampler, v_texCoord)";                                                                                              break;
226                         case PROGRAM_1D_ARRAY_INT:              sampler = "isampler1DArray";            lookup = "vec4(texture(u_sampler, v_texCoord))";                                                                                break;
227                         case PROGRAM_1D_ARRAY_UINT:             sampler = "usampler1DArray";            lookup = "vec4(texture(u_sampler, v_texCoord))";                                                                                break;
228                         case PROGRAM_1D_ARRAY_SHADOW:   sampler = "sampler1DArrayShadow";       lookup = "vec4(texture(u_sampler, vec4(v_texCoord, u_ref)), 0.0, 0.0, 1.0)";                    break;
229                         case PROGRAM_BUFFER_FLOAT:              sampler = "samplerBuffer";                      lookup = "texelFetch(u_sampler, int(v_texCoord))";                                                                              break;
230                         case PROGRAM_BUFFER_INT:                sampler = "isamplerBuffer";                     lookup = "vec4(texelFetch(u_sampler, int(v_texCoord)))";                                                                break;
231                         case PROGRAM_BUFFER_UINT:               sampler = "usamplerBuffer";                     lookup = "vec4(texelFetch(u_sampler, int(v_texCoord)))";                                                                break;
232                         default:
233                                 DE_ASSERT(false);
234                 }
235         }
236         else if (m_glslVersion == glu::GLSL_VERSION_100_ES)
237         {
238                 sampler = isCube ? "samplerCube" : "sampler2D";
239
240                 switch (program)
241                 {
242                         case PROGRAM_2D_FLOAT:                  lookup = "texture2D(u_sampler, v_texCoord)";                    break;
243                         case PROGRAM_2D_FLOAT_BIAS:             lookup = "texture2D(u_sampler, v_texCoord, u_bias)";    break;
244                         case PROGRAM_CUBE_FLOAT:                lookup = "textureCube(u_sampler, v_texCoord)";                  break;
245                         case PROGRAM_CUBE_FLOAT_BIAS:   lookup = "textureCube(u_sampler, v_texCoord, u_bias)";  break;
246                         default:
247                                 DE_ASSERT(false);
248                 }
249         }
250         else
251                 DE_FATAL("Unsupported version");
252
253         params["SAMPLER_TYPE"]  = sampler;
254         params["LOOKUP"]                = lookup;
255
256         std::string vertSrc = tcu::StringTemplate(vertShaderTemplate).specialize(params);
257         std::string fragSrc = tcu::StringTemplate(fragShaderTemplate).specialize(params);
258
259         glu::ShaderProgram* progObj = new glu::ShaderProgram(m_context, glu::makeVtxFragSources(vertSrc, fragSrc));
260         if (!progObj->isOk())
261         {
262                 m_log << *progObj;
263                 delete progObj;
264                 TCU_FAIL("Failed to compile shader program");
265         }
266
267         try
268         {
269                 m_programs[program] = progObj;
270         }
271         catch (...)
272         {
273                 delete progObj;
274                 throw;
275         }
276
277         return progObj;
278 }
279
280 TextureRenderer::TextureRenderer (const glu::RenderContext& context, tcu::TestLog& log, glu::GLSLVersion glslVersion, glu::Precision texCoordPrecision)
281         : m_renderCtx           (context)
282         , m_log                         (log)
283         , m_programLibrary      (context, log, glslVersion, texCoordPrecision)
284 {
285 }
286
287 TextureRenderer::~TextureRenderer (void)
288 {
289         clear();
290 }
291
292 void TextureRenderer::clear (void)
293 {
294         m_programLibrary.clear();
295 }
296
297 void TextureRenderer::renderQuad (int texUnit, const float* texCoord, TextureType texType)
298 {
299         renderQuad(texUnit, texCoord, RenderParams(texType));
300 }
301
302 void TextureRenderer::renderQuad (int texUnit, const float* texCoord, const RenderParams& params)
303 {
304         const glw::Functions&   gl                      = m_renderCtx.getFunctions();
305         tcu::Vec4                               wCoord          = params.flags & RenderParams::PROJECTED ? params.w : tcu::Vec4(1.0f);
306         bool                                    useBias         = !!(params.flags & RenderParams::USE_BIAS);
307         bool                                    logUniforms     = !!(params.flags & RenderParams::LOG_UNIFORMS);
308
309         // Render quad with texture.
310         float position[] =
311         {
312                 -1.0f*wCoord.x(), -1.0f*wCoord.x(), 0.0f, wCoord.x(),
313                 -1.0f*wCoord.y(), +1.0f*wCoord.y(), 0.0f, wCoord.y(),
314                 +1.0f*wCoord.z(), -1.0f*wCoord.z(), 0.0f, wCoord.z(),
315                 +1.0f*wCoord.w(), +1.0f*wCoord.w(), 0.0f, wCoord.w()
316         };
317         static const deUint16 indices[] = { 0, 1, 2, 2, 1, 3 };
318
319         Program progSpec        = PROGRAM_LAST;
320         int             numComps        = 0;
321         if (params.texType == TEXTURETYPE_2D)
322         {
323                 numComps = 2;
324
325                 switch (params.samplerType)
326                 {
327                         case SAMPLERTYPE_FLOAT:         progSpec = useBias ? PROGRAM_2D_FLOAT_BIAS      : PROGRAM_2D_FLOAT;             break;
328                         case SAMPLERTYPE_INT:           progSpec = useBias ? PROGRAM_2D_INT_BIAS        : PROGRAM_2D_INT;               break;
329                         case SAMPLERTYPE_UINT:          progSpec = useBias ? PROGRAM_2D_UINT_BIAS       : PROGRAM_2D_UINT;              break;
330                         case SAMPLERTYPE_SHADOW:        progSpec = useBias ? PROGRAM_2D_SHADOW_BIAS     : PROGRAM_2D_SHADOW;    break;
331                         default:                                        DE_ASSERT(false);
332                 }
333         }
334         else if (params.texType == TEXTURETYPE_1D)
335         {
336                 numComps = 1;
337
338                 switch (params.samplerType)
339                 {
340                         case SAMPLERTYPE_FLOAT:         progSpec = useBias ? PROGRAM_1D_FLOAT_BIAS      : PROGRAM_1D_FLOAT;             break;
341                         case SAMPLERTYPE_INT:           progSpec = useBias ? PROGRAM_1D_INT_BIAS        : PROGRAM_1D_INT;               break;
342                         case SAMPLERTYPE_UINT:          progSpec = useBias ? PROGRAM_1D_UINT_BIAS       : PROGRAM_1D_UINT;              break;
343                         case SAMPLERTYPE_SHADOW:        progSpec = useBias ? PROGRAM_1D_SHADOW_BIAS     : PROGRAM_1D_SHADOW;    break;
344                         default:                                        DE_ASSERT(false);
345                 }
346         }
347         else if (params.texType == TEXTURETYPE_CUBE)
348         {
349                 numComps = 3;
350
351                 switch (params.samplerType)
352                 {
353                         case SAMPLERTYPE_FLOAT:         progSpec = useBias ? PROGRAM_CUBE_FLOAT_BIAS    : PROGRAM_CUBE_FLOAT;   break;
354                         case SAMPLERTYPE_INT:           progSpec = useBias ? PROGRAM_CUBE_INT_BIAS              : PROGRAM_CUBE_INT;             break;
355                         case SAMPLERTYPE_UINT:          progSpec = useBias ? PROGRAM_CUBE_UINT_BIAS             : PROGRAM_CUBE_UINT;    break;
356                         case SAMPLERTYPE_SHADOW:        progSpec = useBias ? PROGRAM_CUBE_SHADOW_BIAS   : PROGRAM_CUBE_SHADOW;  break;
357                         default:                                        DE_ASSERT(false);
358                 }
359         }
360         else if (params.texType == TEXTURETYPE_3D)
361         {
362                 numComps = 3;
363
364                 switch (params.samplerType)
365                 {
366                         case SAMPLERTYPE_FLOAT:         progSpec = useBias ? PROGRAM_3D_FLOAT_BIAS      : PROGRAM_3D_FLOAT;             break;
367                         case SAMPLERTYPE_INT:           progSpec = useBias ? PROGRAM_3D_INT_BIAS        : PROGRAM_3D_INT;               break;
368                         case SAMPLERTYPE_UINT:          progSpec = useBias ? PROGRAM_3D_UINT_BIAS       : PROGRAM_3D_UINT;              break;
369                         default:                                        DE_ASSERT(false);
370                 }
371         }
372         else if (params.texType == TEXTURETYPE_2D_ARRAY)
373         {
374                 DE_ASSERT(!useBias); // \todo [2012-02-17 pyry] Support bias.
375
376                 numComps = 3;
377
378                 switch (params.samplerType)
379                 {
380                         case SAMPLERTYPE_FLOAT:         progSpec = PROGRAM_2D_ARRAY_FLOAT;      break;
381                         case SAMPLERTYPE_INT:           progSpec = PROGRAM_2D_ARRAY_INT;        break;
382                         case SAMPLERTYPE_UINT:          progSpec = PROGRAM_2D_ARRAY_UINT;       break;
383                         case SAMPLERTYPE_SHADOW:        progSpec = PROGRAM_2D_ARRAY_SHADOW;     break;
384                         default:                                        DE_ASSERT(false);
385                 }
386         }
387         else if (params.texType == TEXTURETYPE_CUBE_ARRAY)
388         {
389                 DE_ASSERT(!useBias);
390
391                 numComps = 4;
392
393                 switch (params.samplerType)
394                 {
395                         case SAMPLERTYPE_FLOAT:         progSpec = PROGRAM_CUBE_ARRAY_FLOAT;    break;
396                         case SAMPLERTYPE_INT:           progSpec = PROGRAM_CUBE_ARRAY_INT;              break;
397                         case SAMPLERTYPE_UINT:          progSpec = PROGRAM_CUBE_ARRAY_UINT;             break;
398                         case SAMPLERTYPE_SHADOW:        progSpec = PROGRAM_CUBE_ARRAY_SHADOW;   break;
399                         default:                                        DE_ASSERT(false);
400                 }
401         }
402         else if (params.texType == TEXTURETYPE_1D_ARRAY)
403         {
404                 DE_ASSERT(!useBias); // \todo [2012-02-17 pyry] Support bias.
405
406                 numComps = 2;
407
408                 switch (params.samplerType)
409                 {
410                         case SAMPLERTYPE_FLOAT:         progSpec = PROGRAM_1D_ARRAY_FLOAT;      break;
411                         case SAMPLERTYPE_INT:           progSpec = PROGRAM_1D_ARRAY_INT;        break;
412                         case SAMPLERTYPE_UINT:          progSpec = PROGRAM_1D_ARRAY_UINT;       break;
413                         case SAMPLERTYPE_SHADOW:        progSpec = PROGRAM_1D_ARRAY_SHADOW;     break;
414                         default:                                        DE_ASSERT(false);
415                 }
416         }
417         else if (params.texType == TEXTURETYPE_BUFFER)
418         {
419                 numComps = 1;
420
421                 switch (params.samplerType)
422                 {
423                         case SAMPLERTYPE_FETCH_FLOAT:   progSpec = PROGRAM_BUFFER_FLOAT;        break;
424                         case SAMPLERTYPE_FETCH_INT:             progSpec = PROGRAM_BUFFER_INT;          break;
425                         case SAMPLERTYPE_FETCH_UINT:    progSpec = PROGRAM_BUFFER_UINT;         break;
426                         default:                                                DE_ASSERT(false);
427                 }
428         }
429         else
430                 DE_ASSERT(DE_FALSE);
431
432         glu::ShaderProgram* program = m_programLibrary.getProgram(progSpec);
433
434         // \todo [2012-09-26 pyry] Move to ProgramLibrary and log unique programs only(?)
435         if (params.flags & RenderParams::LOG_PROGRAMS)
436                 m_log << *program;
437
438         GLU_EXPECT_NO_ERROR(gl.getError(), "Set vertex attributes");
439
440         // Program and uniforms.
441         deUint32 prog = program->getProgram();
442         gl.useProgram(prog);
443
444         gl.uniform1i(gl.getUniformLocation(prog, "u_sampler"), texUnit);
445         if (logUniforms)
446                 m_log << TestLog::Message << "u_sampler = " << texUnit << TestLog::EndMessage;
447
448         if (useBias)
449         {
450                 gl.uniform1f(gl.getUniformLocation(prog, "u_bias"), params.bias);
451                 if (logUniforms)
452                         m_log << TestLog::Message << "u_bias = " << params.bias << TestLog::EndMessage;
453         }
454
455         if (params.samplerType == SAMPLERTYPE_SHADOW)
456         {
457                 gl.uniform1f(gl.getUniformLocation(prog, "u_ref"), params.ref);
458                 if (logUniforms)
459                         m_log << TestLog::Message << "u_ref = " << params.ref << TestLog::EndMessage;
460         }
461
462         gl.uniform4fv(gl.getUniformLocation(prog, "u_colorScale"),      1, params.colorScale.getPtr());
463         gl.uniform4fv(gl.getUniformLocation(prog, "u_colorBias"),       1, params.colorBias.getPtr());
464
465         if (logUniforms)
466         {
467                 m_log << TestLog::Message << "u_colorScale = " << params.colorScale << TestLog::EndMessage;
468                 m_log << TestLog::Message << "u_colorBias = " << params.colorBias << TestLog::EndMessage;
469         }
470
471         GLU_EXPECT_NO_ERROR(gl.getError(), "Set program state");
472
473         {
474                 const glu::VertexArrayBinding vertexArrays[] =
475                 {
476                         glu::va::Float("a_position",    4,                      4, 0, &position[0]),
477                         glu::va::Float("a_texCoord",    numComps,       4, 0, texCoord)
478                 };
479                 glu::draw(m_renderCtx, prog, DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0],
480                                   glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
481         }
482 }
483
484
485 } // TextureTestUtil
486 } // gls
487 } // deqp