xref: /aosp_15_r20/external/deqp/modules/glshared/glsTextureTestUtil.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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 std::map;
42 using std::string;
43 using std::vector;
44 using tcu::TestLog;
45 
46 using namespace glu::TextureTestUtil;
47 
48 namespace deqp
49 {
50 namespace gls
51 {
52 namespace TextureTestUtil
53 {
54 
RandomViewport(const tcu::RenderTarget & renderTarget,int preferredWidth,int preferredHeight,uint32_t seed)55 RandomViewport::RandomViewport(const tcu::RenderTarget &renderTarget, int preferredWidth, int preferredHeight,
56                                uint32_t seed)
57     : x(0)
58     , y(0)
59     , width(deMin32(preferredWidth, renderTarget.getWidth()))
60     , height(deMin32(preferredHeight, renderTarget.getHeight()))
61 {
62     de::Random rnd(seed);
63     x = rnd.getInt(0, renderTarget.getWidth() - width);
64     y = rnd.getInt(0, renderTarget.getHeight() - height);
65 }
66 
ProgramLibrary(const glu::RenderContext & context,tcu::TestLog & log,glu::GLSLVersion glslVersion,glu::Precision texCoordPrecision)67 ProgramLibrary::ProgramLibrary(const glu::RenderContext &context, tcu::TestLog &log, glu::GLSLVersion glslVersion,
68                                glu::Precision texCoordPrecision)
69     : m_context(context)
70     , m_log(log)
71     , m_glslVersion(glslVersion)
72     , m_texCoordPrecision(texCoordPrecision)
73 {
74 }
75 
~ProgramLibrary(void)76 ProgramLibrary::~ProgramLibrary(void)
77 {
78     clear();
79 }
80 
clear(void)81 void ProgramLibrary::clear(void)
82 {
83     for (map<Program, glu::ShaderProgram *>::iterator i = m_programs.begin(); i != m_programs.end(); i++)
84     {
85         delete i->second;
86         i->second = DE_NULL;
87     }
88     m_programs.clear();
89 }
90 
getProgram(Program program)91 glu::ShaderProgram *ProgramLibrary::getProgram(Program program)
92 {
93     if (m_programs.find(program) != m_programs.end())
94         return m_programs[program]; // Return from cache.
95 
96     static const char *vertShaderTemplate = "${VTX_HEADER}"
97                                             "${VTX_IN} highp vec4 a_position;\n"
98                                             "${VTX_IN} ${PRECISION} ${TEXCOORD_TYPE} a_texCoord;\n"
99                                             "${VTX_OUT} ${PRECISION} ${TEXCOORD_TYPE} v_texCoord;\n"
100                                             "\n"
101                                             "void main (void)\n"
102                                             "{\n"
103                                             "    gl_Position = a_position;\n"
104                                             "    v_texCoord = a_texCoord;\n"
105                                             "}\n";
106     static const char *fragShaderTemplate = "${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 ||
146              m_glslVersion == glu::GLSL_VERSION_320_ES || m_glslVersion > glu::GLSL_VERSION_330)
147     {
148         const string version = glu::getGLSLVersionDeclaration(m_glslVersion);
149         const char *ext      = DE_NULL;
150 
151         if (glu::glslVersionIsES(m_glslVersion) && m_glslVersion != glu::GLSL_VERSION_320_ES)
152         {
153             if (isCubeArray)
154                 ext = "GL_EXT_texture_cube_map_array";
155             else if (isBuffer)
156                 ext = "GL_EXT_texture_buffer";
157         }
158 
159         params["FRAG_HEADER"] = version + (ext ? string("\n#extension ") + ext + " : require" : string()) +
160                                 "\nlayout(location = 0) out mediump vec4 dEQP_FragColor;\n";
161         params["VTX_HEADER"] = version + "\n";
162         params["VTX_IN"]     = "in";
163         params["VTX_OUT"]    = "out";
164         params["FRAG_IN"]    = "in";
165         params["FRAG_COLOR"] = "dEQP_FragColor";
166     }
167     else
168         DE_FATAL("Unsupported version");
169 
170     params["PRECISION"] = glu::getPrecisionName(m_texCoordPrecision);
171 
172     if (isCubeArray)
173         params["TEXCOORD_TYPE"] = "vec4";
174     else if (isCube || (is2D && isArray) || is3D)
175         params["TEXCOORD_TYPE"] = "vec3";
176     else if ((is1D && isArray) || is2D)
177         params["TEXCOORD_TYPE"] = "vec2";
178     else if (is1D)
179         params["TEXCOORD_TYPE"] = "float";
180     else
181         DE_ASSERT(false);
182 
183     const char *sampler = DE_NULL;
184     const char *lookup  = DE_NULL;
185 
186     if (m_glslVersion == glu::GLSL_VERSION_300_ES || m_glslVersion == glu::GLSL_VERSION_310_ES ||
187         m_glslVersion == glu::GLSL_VERSION_320_ES || m_glslVersion > glu::GLSL_VERSION_330)
188     {
189         switch (program)
190         {
191         case PROGRAM_2D_FLOAT:
192             sampler = "sampler2D";
193             lookup  = "texture(u_sampler, v_texCoord)";
194             break;
195         case PROGRAM_2D_INT:
196             sampler = "isampler2D";
197             lookup  = "vec4(texture(u_sampler, v_texCoord))";
198             break;
199         case PROGRAM_2D_UINT:
200             sampler = "usampler2D";
201             lookup  = "vec4(texture(u_sampler, v_texCoord))";
202             break;
203         case PROGRAM_2D_SHADOW:
204             sampler = "sampler2DShadow";
205             lookup  = "vec4(texture(u_sampler, vec3(v_texCoord, u_ref)), 0.0, 0.0, 1.0)";
206             break;
207         case PROGRAM_2D_FLOAT_BIAS:
208             sampler = "sampler2D";
209             lookup  = "texture(u_sampler, v_texCoord, u_bias)";
210             break;
211         case PROGRAM_2D_INT_BIAS:
212             sampler = "isampler2D";
213             lookup  = "vec4(texture(u_sampler, v_texCoord, u_bias))";
214             break;
215         case PROGRAM_2D_UINT_BIAS:
216             sampler = "usampler2D";
217             lookup  = "vec4(texture(u_sampler, v_texCoord, u_bias))";
218             break;
219         case PROGRAM_2D_SHADOW_BIAS:
220             sampler = "sampler2DShadow";
221             lookup  = "vec4(texture(u_sampler, vec3(v_texCoord, u_ref), u_bias), 0.0, 0.0, 1.0)";
222             break;
223         case PROGRAM_1D_FLOAT:
224             sampler = "sampler1D";
225             lookup  = "texture(u_sampler, v_texCoord)";
226             break;
227         case PROGRAM_1D_INT:
228             sampler = "isampler1D";
229             lookup  = "vec4(texture(u_sampler, v_texCoord))";
230             break;
231         case PROGRAM_1D_UINT:
232             sampler = "usampler1D";
233             lookup  = "vec4(texture(u_sampler, v_texCoord))";
234             break;
235         case PROGRAM_1D_SHADOW:
236             sampler = "sampler1DShadow";
237             lookup  = "vec4(texture(u_sampler, vec3(v_texCoord, u_ref)), 0.0, 0.0, 1.0)";
238             break;
239         case PROGRAM_1D_FLOAT_BIAS:
240             sampler = "sampler1D";
241             lookup  = "texture(u_sampler, v_texCoord, u_bias)";
242             break;
243         case PROGRAM_1D_INT_BIAS:
244             sampler = "isampler1D";
245             lookup  = "vec4(texture(u_sampler, v_texCoord, u_bias))";
246             break;
247         case PROGRAM_1D_UINT_BIAS:
248             sampler = "usampler1D";
249             lookup  = "vec4(texture(u_sampler, v_texCoord, u_bias))";
250             break;
251         case PROGRAM_1D_SHADOW_BIAS:
252             sampler = "sampler1DShadow";
253             lookup  = "vec4(texture(u_sampler, vec3(v_texCoord, u_ref), u_bias), 0.0, 0.0, 1.0)";
254             break;
255         case PROGRAM_CUBE_FLOAT:
256             sampler = "samplerCube";
257             lookup  = "texture(u_sampler, v_texCoord)";
258             break;
259         case PROGRAM_CUBE_INT:
260             sampler = "isamplerCube";
261             lookup  = "vec4(texture(u_sampler, v_texCoord))";
262             break;
263         case PROGRAM_CUBE_UINT:
264             sampler = "usamplerCube";
265             lookup  = "vec4(texture(u_sampler, v_texCoord))";
266             break;
267         case PROGRAM_CUBE_SHADOW:
268             sampler = "samplerCubeShadow";
269             lookup  = "vec4(texture(u_sampler, vec4(v_texCoord, u_ref)), 0.0, 0.0, 1.0)";
270             break;
271         case PROGRAM_CUBE_FLOAT_BIAS:
272             sampler = "samplerCube";
273             lookup  = "texture(u_sampler, v_texCoord, u_bias)";
274             break;
275         case PROGRAM_CUBE_INT_BIAS:
276             sampler = "isamplerCube";
277             lookup  = "vec4(texture(u_sampler, v_texCoord, u_bias))";
278             break;
279         case PROGRAM_CUBE_UINT_BIAS:
280             sampler = "usamplerCube";
281             lookup  = "vec4(texture(u_sampler, v_texCoord, u_bias))";
282             break;
283         case PROGRAM_CUBE_SHADOW_BIAS:
284             sampler = "samplerCubeShadow";
285             lookup  = "vec4(texture(u_sampler, vec4(v_texCoord, u_ref), u_bias), 0.0, 0.0, 1.0)";
286             break;
287         case PROGRAM_2D_ARRAY_FLOAT:
288             sampler = "sampler2DArray";
289             lookup  = "texture(u_sampler, v_texCoord)";
290             break;
291         case PROGRAM_2D_ARRAY_INT:
292             sampler = "isampler2DArray";
293             lookup  = "vec4(texture(u_sampler, v_texCoord))";
294             break;
295         case PROGRAM_2D_ARRAY_UINT:
296             sampler = "usampler2DArray";
297             lookup  = "vec4(texture(u_sampler, v_texCoord))";
298             break;
299         case PROGRAM_2D_ARRAY_SHADOW:
300             sampler = "sampler2DArrayShadow";
301             lookup  = "vec4(texture(u_sampler, vec4(v_texCoord, u_ref)), 0.0, 0.0, 1.0)";
302             break;
303         case PROGRAM_3D_FLOAT:
304             sampler = "sampler3D";
305             lookup  = "texture(u_sampler, v_texCoord)";
306             break;
307         case PROGRAM_3D_INT:
308             sampler = "isampler3D";
309             lookup  = "vec4(texture(u_sampler, v_texCoord))";
310             break;
311         case PROGRAM_3D_UINT:
312             sampler = "usampler3D";
313             lookup  = "vec4(texture(u_sampler, v_texCoord))";
314             break;
315         case PROGRAM_3D_FLOAT_BIAS:
316             sampler = "sampler3D";
317             lookup  = "texture(u_sampler, v_texCoord, u_bias)";
318             break;
319         case PROGRAM_3D_INT_BIAS:
320             sampler = "isampler3D";
321             lookup  = "vec4(texture(u_sampler, v_texCoord, u_bias))";
322             break;
323         case PROGRAM_3D_UINT_BIAS:
324             sampler = "usampler3D";
325             lookup  = "vec4(texture(u_sampler, v_texCoord, u_bias))";
326             break;
327         case PROGRAM_CUBE_ARRAY_FLOAT:
328             sampler = "samplerCubeArray";
329             lookup  = "texture(u_sampler, v_texCoord)";
330             break;
331         case PROGRAM_CUBE_ARRAY_INT:
332             sampler = "isamplerCubeArray";
333             lookup  = "vec4(texture(u_sampler, v_texCoord))";
334             break;
335         case PROGRAM_CUBE_ARRAY_UINT:
336             sampler = "usamplerCubeArray";
337             lookup  = "vec4(texture(u_sampler, v_texCoord))";
338             break;
339         case PROGRAM_CUBE_ARRAY_SHADOW:
340             sampler = "samplerCubeArrayShadow";
341             lookup  = "vec4(texture(u_sampler, vec4(v_texCoord, u_ref)), 0.0, 0.0, 1.0)";
342             break;
343         case PROGRAM_1D_ARRAY_FLOAT:
344             sampler = "sampler1DArray";
345             lookup  = "texture(u_sampler, v_texCoord)";
346             break;
347         case PROGRAM_1D_ARRAY_INT:
348             sampler = "isampler1DArray";
349             lookup  = "vec4(texture(u_sampler, v_texCoord))";
350             break;
351         case PROGRAM_1D_ARRAY_UINT:
352             sampler = "usampler1DArray";
353             lookup  = "vec4(texture(u_sampler, v_texCoord))";
354             break;
355         case PROGRAM_1D_ARRAY_SHADOW:
356             sampler = "sampler1DArrayShadow";
357             lookup  = "vec4(texture(u_sampler, vec4(v_texCoord, u_ref)), 0.0, 0.0, 1.0)";
358             break;
359         case PROGRAM_BUFFER_FLOAT:
360             sampler = "samplerBuffer";
361             lookup  = "texelFetch(u_sampler, int(v_texCoord))";
362             break;
363         case PROGRAM_BUFFER_INT:
364             sampler = "isamplerBuffer";
365             lookup  = "vec4(texelFetch(u_sampler, int(v_texCoord)))";
366             break;
367         case PROGRAM_BUFFER_UINT:
368             sampler = "usamplerBuffer";
369             lookup  = "vec4(texelFetch(u_sampler, int(v_texCoord)))";
370             break;
371         default:
372             DE_ASSERT(false);
373         }
374     }
375     else if (m_glslVersion == glu::GLSL_VERSION_100_ES)
376     {
377         sampler = isCube ? "samplerCube" : "sampler2D";
378 
379         switch (program)
380         {
381         case PROGRAM_2D_FLOAT:
382             lookup = "texture2D(u_sampler, v_texCoord)";
383             break;
384         case PROGRAM_2D_FLOAT_BIAS:
385             lookup = "texture2D(u_sampler, v_texCoord, u_bias)";
386             break;
387         case PROGRAM_CUBE_FLOAT:
388             lookup = "textureCube(u_sampler, v_texCoord)";
389             break;
390         case PROGRAM_CUBE_FLOAT_BIAS:
391             lookup = "textureCube(u_sampler, v_texCoord, u_bias)";
392             break;
393         default:
394             DE_ASSERT(false);
395         }
396     }
397     else
398         DE_FATAL("Unsupported version");
399 
400     params["SAMPLER_TYPE"] = sampler;
401     params["LOOKUP"]       = lookup;
402 
403     std::string vertSrc = tcu::StringTemplate(vertShaderTemplate).specialize(params);
404     std::string fragSrc = tcu::StringTemplate(fragShaderTemplate).specialize(params);
405 
406     glu::ShaderProgram *progObj = new glu::ShaderProgram(m_context, glu::makeVtxFragSources(vertSrc, fragSrc));
407     if (!progObj->isOk())
408     {
409         m_log << *progObj;
410         delete progObj;
411         TCU_FAIL("Failed to compile shader program");
412     }
413 
414     try
415     {
416         m_programs[program] = progObj;
417     }
418     catch (...)
419     {
420         delete progObj;
421         throw;
422     }
423 
424     return progObj;
425 }
426 
getTexCoordPrecision()427 glu::Precision ProgramLibrary::getTexCoordPrecision()
428 {
429     return m_texCoordPrecision;
430 }
431 
TextureRenderer(const glu::RenderContext & context,tcu::TestLog & log,glu::GLSLVersion glslVersion,glu::Precision texCoordPrecision)432 TextureRenderer::TextureRenderer(const glu::RenderContext &context, tcu::TestLog &log, glu::GLSLVersion glslVersion,
433                                  glu::Precision texCoordPrecision)
434     : m_renderCtx(context)
435     , m_log(log)
436     , m_programLibrary(context, log, glslVersion, texCoordPrecision)
437 {
438 }
439 
~TextureRenderer(void)440 TextureRenderer::~TextureRenderer(void)
441 {
442     clear();
443 }
444 
clear(void)445 void TextureRenderer::clear(void)
446 {
447     m_programLibrary.clear();
448 }
449 
renderQuad(int texUnit,const float * texCoord,TextureType texType)450 void TextureRenderer::renderQuad(int texUnit, const float *texCoord, TextureType texType)
451 {
452     renderQuad(texUnit, texCoord, RenderParams(texType));
453 }
454 
renderQuad(int texUnit,const float * texCoord,const RenderParams & params)455 void TextureRenderer::renderQuad(int texUnit, const float *texCoord, const RenderParams &params)
456 {
457     const glw::Functions &gl = m_renderCtx.getFunctions();
458     tcu::Vec4 wCoord         = params.flags & RenderParams::PROJECTED ? params.w : tcu::Vec4(1.0f);
459     bool useBias             = !!(params.flags & RenderParams::USE_BIAS);
460     bool logUniforms         = !!(params.flags & RenderParams::LOG_UNIFORMS);
461 
462     // Render quad with texture.
463     float position[]                = {-1.0f * wCoord.x(), -1.0f * wCoord.x(), 0.0f, wCoord.x(),
464                                        -1.0f * wCoord.y(), +1.0f * wCoord.y(), 0.0f, wCoord.y(),
465                                        +1.0f * wCoord.z(), -1.0f * wCoord.z(), 0.0f, wCoord.z(),
466                                        +1.0f * wCoord.w(), +1.0f * wCoord.w(), 0.0f, wCoord.w()};
467     static const uint16_t indices[] = {0, 1, 2, 2, 1, 3};
468 
469     Program progSpec = PROGRAM_LAST;
470     int numComps     = 0;
471     if (params.texType == TEXTURETYPE_2D)
472     {
473         numComps = 2;
474 
475         switch (params.samplerType)
476         {
477         case SAMPLERTYPE_FLOAT:
478             progSpec = useBias ? PROGRAM_2D_FLOAT_BIAS : PROGRAM_2D_FLOAT;
479             break;
480         case SAMPLERTYPE_INT:
481             progSpec = useBias ? PROGRAM_2D_INT_BIAS : PROGRAM_2D_INT;
482             break;
483         case SAMPLERTYPE_UINT:
484             progSpec = useBias ? PROGRAM_2D_UINT_BIAS : PROGRAM_2D_UINT;
485             break;
486         case SAMPLERTYPE_SHADOW:
487             progSpec = useBias ? PROGRAM_2D_SHADOW_BIAS : PROGRAM_2D_SHADOW;
488             break;
489         default:
490             DE_ASSERT(false);
491         }
492     }
493     else if (params.texType == TEXTURETYPE_1D)
494     {
495         numComps = 1;
496 
497         switch (params.samplerType)
498         {
499         case SAMPLERTYPE_FLOAT:
500             progSpec = useBias ? PROGRAM_1D_FLOAT_BIAS : PROGRAM_1D_FLOAT;
501             break;
502         case SAMPLERTYPE_INT:
503             progSpec = useBias ? PROGRAM_1D_INT_BIAS : PROGRAM_1D_INT;
504             break;
505         case SAMPLERTYPE_UINT:
506             progSpec = useBias ? PROGRAM_1D_UINT_BIAS : PROGRAM_1D_UINT;
507             break;
508         case SAMPLERTYPE_SHADOW:
509             progSpec = useBias ? PROGRAM_1D_SHADOW_BIAS : PROGRAM_1D_SHADOW;
510             break;
511         default:
512             DE_ASSERT(false);
513         }
514     }
515     else if (params.texType == TEXTURETYPE_CUBE)
516     {
517         numComps = 3;
518 
519         switch (params.samplerType)
520         {
521         case SAMPLERTYPE_FLOAT:
522             progSpec = useBias ? PROGRAM_CUBE_FLOAT_BIAS : PROGRAM_CUBE_FLOAT;
523             break;
524         case SAMPLERTYPE_INT:
525             progSpec = useBias ? PROGRAM_CUBE_INT_BIAS : PROGRAM_CUBE_INT;
526             break;
527         case SAMPLERTYPE_UINT:
528             progSpec = useBias ? PROGRAM_CUBE_UINT_BIAS : PROGRAM_CUBE_UINT;
529             break;
530         case SAMPLERTYPE_SHADOW:
531             progSpec = useBias ? PROGRAM_CUBE_SHADOW_BIAS : PROGRAM_CUBE_SHADOW;
532             break;
533         default:
534             DE_ASSERT(false);
535         }
536     }
537     else if (params.texType == TEXTURETYPE_3D)
538     {
539         numComps = 3;
540 
541         switch (params.samplerType)
542         {
543         case SAMPLERTYPE_FLOAT:
544             progSpec = useBias ? PROGRAM_3D_FLOAT_BIAS : PROGRAM_3D_FLOAT;
545             break;
546         case SAMPLERTYPE_INT:
547             progSpec = useBias ? PROGRAM_3D_INT_BIAS : PROGRAM_3D_INT;
548             break;
549         case SAMPLERTYPE_UINT:
550             progSpec = useBias ? PROGRAM_3D_UINT_BIAS : PROGRAM_3D_UINT;
551             break;
552         default:
553             DE_ASSERT(false);
554         }
555     }
556     else if (params.texType == TEXTURETYPE_2D_ARRAY)
557     {
558         DE_ASSERT(!useBias); // \todo [2012-02-17 pyry] Support bias.
559 
560         numComps = 3;
561 
562         switch (params.samplerType)
563         {
564         case SAMPLERTYPE_FLOAT:
565             progSpec = PROGRAM_2D_ARRAY_FLOAT;
566             break;
567         case SAMPLERTYPE_INT:
568             progSpec = PROGRAM_2D_ARRAY_INT;
569             break;
570         case SAMPLERTYPE_UINT:
571             progSpec = PROGRAM_2D_ARRAY_UINT;
572             break;
573         case SAMPLERTYPE_SHADOW:
574             progSpec = PROGRAM_2D_ARRAY_SHADOW;
575             break;
576         default:
577             DE_ASSERT(false);
578         }
579     }
580     else if (params.texType == TEXTURETYPE_CUBE_ARRAY)
581     {
582         DE_ASSERT(!useBias);
583 
584         numComps = 4;
585 
586         switch (params.samplerType)
587         {
588         case SAMPLERTYPE_FLOAT:
589             progSpec = PROGRAM_CUBE_ARRAY_FLOAT;
590             break;
591         case SAMPLERTYPE_INT:
592             progSpec = PROGRAM_CUBE_ARRAY_INT;
593             break;
594         case SAMPLERTYPE_UINT:
595             progSpec = PROGRAM_CUBE_ARRAY_UINT;
596             break;
597         case SAMPLERTYPE_SHADOW:
598             progSpec = PROGRAM_CUBE_ARRAY_SHADOW;
599             break;
600         default:
601             DE_ASSERT(false);
602         }
603     }
604     else if (params.texType == TEXTURETYPE_1D_ARRAY)
605     {
606         DE_ASSERT(!useBias); // \todo [2012-02-17 pyry] Support bias.
607 
608         numComps = 2;
609 
610         switch (params.samplerType)
611         {
612         case SAMPLERTYPE_FLOAT:
613             progSpec = PROGRAM_1D_ARRAY_FLOAT;
614             break;
615         case SAMPLERTYPE_INT:
616             progSpec = PROGRAM_1D_ARRAY_INT;
617             break;
618         case SAMPLERTYPE_UINT:
619             progSpec = PROGRAM_1D_ARRAY_UINT;
620             break;
621         case SAMPLERTYPE_SHADOW:
622             progSpec = PROGRAM_1D_ARRAY_SHADOW;
623             break;
624         default:
625             DE_ASSERT(false);
626         }
627     }
628     else if (params.texType == TEXTURETYPE_BUFFER)
629     {
630         numComps = 1;
631 
632         switch (params.samplerType)
633         {
634         case SAMPLERTYPE_FETCH_FLOAT:
635             progSpec = PROGRAM_BUFFER_FLOAT;
636             break;
637         case SAMPLERTYPE_FETCH_INT:
638             progSpec = PROGRAM_BUFFER_INT;
639             break;
640         case SAMPLERTYPE_FETCH_UINT:
641             progSpec = PROGRAM_BUFFER_UINT;
642             break;
643         default:
644             DE_ASSERT(false);
645         }
646     }
647     else
648         DE_ASSERT(false);
649 
650     glu::ShaderProgram *program = m_programLibrary.getProgram(progSpec);
651 
652     // \todo [2012-09-26 pyry] Move to ProgramLibrary and log unique programs only(?)
653     if (params.flags & RenderParams::LOG_PROGRAMS)
654         m_log << *program;
655 
656     GLU_EXPECT_NO_ERROR(gl.getError(), "Set vertex attributes");
657 
658     // Program and uniforms.
659     uint32_t prog = program->getProgram();
660     gl.useProgram(prog);
661 
662     gl.uniform1i(gl.getUniformLocation(prog, "u_sampler"), texUnit);
663     if (logUniforms)
664         m_log << TestLog::Message << "u_sampler = " << texUnit << TestLog::EndMessage;
665 
666     if (useBias)
667     {
668         gl.uniform1f(gl.getUniformLocation(prog, "u_bias"), params.bias);
669         if (logUniforms)
670             m_log << TestLog::Message << "u_bias = " << params.bias << TestLog::EndMessage;
671     }
672 
673     if (params.samplerType == SAMPLERTYPE_SHADOW)
674     {
675         gl.uniform1f(gl.getUniformLocation(prog, "u_ref"), params.ref);
676         if (logUniforms)
677             m_log << TestLog::Message << "u_ref = " << params.ref << TestLog::EndMessage;
678     }
679 
680     gl.uniform4fv(gl.getUniformLocation(prog, "u_colorScale"), 1, params.colorScale.getPtr());
681     gl.uniform4fv(gl.getUniformLocation(prog, "u_colorBias"), 1, params.colorBias.getPtr());
682 
683     if (logUniforms)
684     {
685         m_log << TestLog::Message << "u_colorScale = " << params.colorScale << TestLog::EndMessage;
686         m_log << TestLog::Message << "u_colorBias = " << params.colorBias << TestLog::EndMessage;
687     }
688 
689     GLU_EXPECT_NO_ERROR(gl.getError(), "Set program state");
690 
691     {
692         const glu::VertexArrayBinding vertexArrays[] = {glu::va::Float("a_position", 4, 4, 0, &position[0]),
693                                                         glu::va::Float("a_texCoord", numComps, 4, 0, texCoord)};
694         glu::draw(m_renderCtx, prog, DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0],
695                   glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
696     }
697 }
698 
getTexCoordPrecision()699 glu::Precision TextureRenderer::getTexCoordPrecision()
700 {
701     return m_programLibrary.getTexCoordPrecision();
702 }
703 
704 } // namespace TextureTestUtil
705 } // namespace gls
706 } // namespace deqp
707