Merge "DO NOT MERGE CP vertex array test and warning fixes" into marshmallow-cts-dev
[platform/upstream/VK-GL-CTS.git] / modules / glshared / glsSamplerObjectTest.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.0 Module
3  * -------------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Sampler object testcases.
22  *//*--------------------------------------------------------------------*/
23
24 #include "glsSamplerObjectTest.hpp"
25
26 #include "tcuTexture.hpp"
27 #include "tcuSurface.hpp"
28 #include "tcuTextureUtil.hpp"
29 #include "tcuImageCompare.hpp"
30 #include "tcuTestLog.hpp"
31 #include "tcuRGBA.hpp"
32 #include "tcuRenderTarget.hpp"
33 #include "tcuStringTemplate.hpp"
34
35 #include "gluShaderProgram.hpp"
36 #include "gluPixelTransfer.hpp"
37 #include "gluDrawUtil.hpp"
38 #include "gluRenderContext.hpp"
39 #include "gluTextureUtil.hpp"
40
41 #include "glwFunctions.hpp"
42
43 #include "deRandom.hpp"
44 #include "deString.h"
45
46 #include "deString.h"
47
48 #include <map>
49
50 namespace deqp
51 {
52 namespace gls
53 {
54
55 namespace
56 {
57 const int VIEWPORT_WIDTH        = 128;
58 const int VIEWPORT_HEIGHT       = 128;
59
60 const int TEXTURE2D_WIDTH       = 32;
61 const int TEXTURE2D_HEIGHT      = 32;
62
63 const int TEXTURE3D_WIDTH       = 32;
64 const int TEXTURE3D_HEIGHT      = 32;
65 const int TEXTURE3D_DEPTH       = 32;
66
67 const int CUBEMAP_SIZE          = 32;
68
69 } // anonymous
70
71
72 TextureSamplerTest::TextureSamplerTest (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const TestSpec& spec)
73         : tcu::TestCase         (testCtx, spec.name, spec.desc)
74         , m_renderCtx           (renderCtx)
75         , m_program                     (NULL)
76         , m_target                      (spec.target)
77         , m_textureState        (spec.textureState)
78         , m_samplerState        (spec.samplerState)
79         , m_random                      (deStringHash(spec.name))
80 {
81 }
82
83 void TextureSamplerTest::setTextureState (const glw::Functions& gl, GLenum target, SamplingState state)
84 {
85         gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, state.minFilter);
86         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(target, GL_TEXTURE_MIN_FILTER, state.minFilter)");
87         gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, state.magFilter);
88         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(target, GL_TEXTURE_MAG_FILTER, state.magFilter)");
89         gl.texParameteri(target, GL_TEXTURE_WRAP_S, state.wrapS);
90         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(target, GL_TEXTURE_WRAP_S, state.wrapS)");
91         gl.texParameteri(target, GL_TEXTURE_WRAP_T, state.wrapT);
92         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(target, GL_TEXTURE_WRAP_T, state.wrapT)");
93         gl.texParameteri(target, GL_TEXTURE_WRAP_R, state.wrapR);
94         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(target, GL_TEXTURE_WRAP_R, state.wrapR)");
95         gl.texParameterf(target, GL_TEXTURE_MAX_LOD, state.maxLod);
96         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameterf(target, GL_TEXTURE_MAX_LOD, state.maxLod)");
97         gl.texParameterf(target, GL_TEXTURE_MIN_LOD, state.minLod);
98         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameterf(target, GL_TEXTURE_MIN_LOD, state.minLod)");
99 }
100
101 void TextureSamplerTest::setSamplerState (const glw::Functions& gl, SamplingState state, GLuint sampler)
102 {
103         gl.samplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, state.minFilter);
104         GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, state.minFilter)");
105         gl.samplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, state.magFilter);
106         GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, state.magFilter)");
107         gl.samplerParameteri(sampler, GL_TEXTURE_WRAP_S, state.wrapS);
108         GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, state.wrapS)");
109         gl.samplerParameteri(sampler, GL_TEXTURE_WRAP_T, state.wrapT);
110         GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, state.wrapT)");
111         gl.samplerParameteri(sampler, GL_TEXTURE_WRAP_R, state.wrapR);
112         GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameteri(sampler, GL_TEXTURE_WRAP_R, state.wrapR)");
113         gl.samplerParameterf(sampler, GL_TEXTURE_MAX_LOD, state.maxLod);
114         GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameterf(sampler, GL_TEXTURE_MAX_LOD, state.maxLod)");
115         gl.samplerParameterf(sampler, GL_TEXTURE_MIN_LOD, state.minLod);
116         GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameterf(sampler, GL_TEXTURE_MIN_LOD, state.minLod)");
117 }
118
119 const char* TextureSamplerTest::selectVertexShader (GLenum target)
120 {
121         switch (target)
122         {
123                 case GL_TEXTURE_2D:
124                         return
125                         "${VTX_HDR}"
126                         "${VTX_IN} ${HIGHP} vec2 a_position;\n"
127                         "uniform ${HIGHP} float u_posScale;\n"
128                         "${VTX_OUT} ${MEDIUMP} vec2 v_texCoord;\n"
129                         "void main (void)\n"
130                         "{\n"
131                         "\tv_texCoord = a_position;\n"
132                         "\tgl_Position = vec4(u_posScale * a_position, 0.0, 1.0);\n"
133                         "}";
134
135                 case GL_TEXTURE_3D:
136                         return
137                         "${VTX_HDR}"
138                         "${VTX_IN} ${HIGHP} vec3 a_position;\n"
139                         "uniform ${HIGHP} float u_posScale;\n"
140                         "${VTX_OUT} ${MEDIUMP} vec3 v_texCoord;\n"
141                         "void main (void)\n"
142                         "{\n"
143                         "\tv_texCoord = a_position;\n"
144                         "\tgl_Position = vec4(u_posScale * a_position.xy, 0.0, 1.0);\n"
145                         "}";
146
147                 case GL_TEXTURE_CUBE_MAP:
148                         return
149                         "${VTX_HDR}"
150                         "${VTX_IN} ${HIGHP} vec4 a_position;\n"
151                         "uniform ${HIGHP} float u_posScale;\n"
152                         "${VTX_OUT} ${MEDIUMP} vec2 v_texCoord;\n"
153                         "void main (void)\n"
154                         "{\n"
155                         "\tv_texCoord = a_position.zw;\n"
156                         "\tgl_Position = vec4(u_posScale * a_position.xy, 0.0, 1.0);\n"
157                         "}";
158
159                 default:
160                         DE_ASSERT(false);
161                         return NULL;
162         }
163 }
164
165 const char* TextureSamplerTest::selectFragmentShader (GLenum target)
166 {
167         switch (target)
168         {
169                 case GL_TEXTURE_2D:
170                         return
171                         "${FRAG_HDR}"
172                         "uniform ${LOWP} sampler2D u_sampler;\n"
173                         "${FRAG_IN} ${MEDIUMP} vec2 v_texCoord;\n"
174                         "void main (void)\n"
175                         "{\n"
176                         "\t${FRAG_COLOR} = texture(u_sampler, v_texCoord);\n"
177                         "}";
178
179                 case GL_TEXTURE_3D:
180                         return
181                         "${FRAG_HDR}"
182                         "uniform ${LOWP} sampler3D u_sampler;\n"
183                         "${FRAG_IN} ${MEDIUMP} vec3 v_texCoord;\n"
184                         "void main (void)\n"
185                         "{\n"
186                         "\t${FRAG_COLOR} = texture(u_sampler, v_texCoord);\n"
187                         "}";
188
189                 case GL_TEXTURE_CUBE_MAP:
190                         return
191                         "${FRAG_HDR}"
192                         "uniform ${LOWP} samplerCube u_sampler;\n"
193                         "${FRAG_IN} ${MEDIUMP} vec2 v_texCoord;\n"
194                         "void main (void)\n"
195                         "{\n"
196                         "\t${FRAG_COLOR} = texture(u_sampler, vec3(cos(3.14 * v_texCoord.y) * sin(3.14 * v_texCoord.x), sin(3.14 * v_texCoord.y), cos(3.14 * v_texCoord.y) * cos(3.14 * v_texCoord.x)));\n"
197                         "}";
198
199                 default:
200                         DE_ASSERT(false);
201                         return NULL;
202         }
203 }
204
205 void TextureSamplerTest::init (void)
206 {
207         const char* vertexShaderTemplate        = selectVertexShader(m_target);
208         const char* fragmentShaderTemplate      = selectFragmentShader(m_target);
209
210         std::map<std::string, std::string>      params;
211
212         if (glu::isGLSLVersionSupported(m_renderCtx.getType(), glu::GLSL_VERSION_300_ES))
213         {
214                 params["VTX_HDR"]               = "#version 300 es\n";
215                 params["FRAG_HDR"]              = "#version 300 es\nlayout(location = 0) out mediump vec4 o_color;\n";
216                 params["VTX_IN"]                = "in";
217                 params["VTX_OUT"]               = "out";
218                 params["FRAG_IN"]               = "in";
219                 params["FRAG_COLOR"]    = "o_color";
220                 params["HIGHP"]                 = "highp";
221                 params["LOWP"]                  = "lowp";
222                 params["MEDIUMP"]               = "mediump";
223         }
224         else if (glu::isGLSLVersionSupported(m_renderCtx.getType(), glu::GLSL_VERSION_330))
225         {
226                 params["VTX_HDR"]               = "#version 330\n";
227                 params["FRAG_HDR"]              = "#version 330\nlayout(location = 0) out mediump vec4 o_color;\n";
228                 params["VTX_IN"]                = "in";
229                 params["VTX_OUT"]               = "out";
230                 params["FRAG_IN"]               = "in";
231                 params["FRAG_COLOR"]    = "o_color";
232                 params["HIGHP"]                 = "highp";
233                 params["LOWP"]                  = "lowp";
234                 params["MEDIUMP"]               = "mediump";
235         }
236         else
237                 DE_ASSERT(false);
238
239         DE_ASSERT(!m_program);
240         m_program = new glu::ShaderProgram(m_renderCtx,
241                                                                            glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderTemplate).specialize(params),
242                                                                                                                            tcu::StringTemplate(fragmentShaderTemplate).specialize(params)));
243
244         if (!m_program->isOk())
245         {
246                 tcu::TestLog& log = m_testCtx.getLog();
247                 log << *m_program;
248                 TCU_FAIL("Failed to compile shaders");
249         }
250 }
251
252 void TextureSamplerTest::deinit (void)
253 {
254         delete m_program;
255         m_program = NULL;
256 }
257
258 TextureSamplerTest::~TextureSamplerTest (void)
259 {
260         deinit();
261 }
262
263 const float s_positions[] = {
264         -1.0, -1.0,
265          1.0, -1.0,
266          1.0,  1.0,
267
268          1.0,  1.0,
269         -1.0,  1.0,
270         -1.0, -1.0
271 };
272
273 const float s_positions3D[] = {
274         -1.0f, -1.0f, -1.0f,
275          1.0f, -1.0f,  1.0f,
276          1.0f,  1.0f, -1.0f,
277
278          1.0f,  1.0f, -1.0f,
279         -1.0f,  1.0f,  1.0f,
280         -1.0f, -1.0f, -1.0f
281 };
282
283 const float s_positionsCube[] = {
284         -1.0f, -1.0f, -1.0f, -0.5f,
285          1.0f, -1.0f,  1.0f, -0.5f,
286          1.0f,  1.0f,  1.0f,  0.5f,
287
288          1.0f,  1.0f,  1.0f,  0.5f,
289         -1.0f,  1.0f, -1.0f,  0.5f,
290         -1.0f, -1.0f, -1.0f, -0.5f
291 };
292
293 void TextureSamplerTest::render (void)
294 {
295         const glw::Functions& gl = m_renderCtx.getFunctions();
296
297         GLuint  samplerLoc      = (GLuint)-1;
298         GLuint  scaleLoc        = (GLuint)-1;
299
300         gl.useProgram(m_program->getProgram());
301         GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram(m_program->getProgram())");
302
303         samplerLoc = gl.getUniformLocation(m_program->getProgram(), "u_sampler");
304         TCU_CHECK(samplerLoc != (GLuint)-1);
305
306         scaleLoc = gl.getUniformLocation(m_program->getProgram(), "u_posScale");
307         TCU_CHECK(scaleLoc != (GLuint)-1);
308
309         gl.clearColor(0.5f, 0.5f, 0.5f, 1.0f);
310         GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor(0.5f, 0.5f, 0.5f, 1.0f)");
311
312         gl.clear(GL_COLOR_BUFFER_BIT);
313         GLU_EXPECT_NO_ERROR(gl.getError(), "glClear(GL_COLOR_BUFFER_BIT)");
314
315         gl.uniform1i(samplerLoc, 0);
316         GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i(samplerLoc, 0)");
317
318         gl.uniform1f(scaleLoc, 1.0f);
319         GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f(scaleLoc, 1.0f)");
320
321         switch (m_target)
322         {
323                 case GL_TEXTURE_2D:
324                 {
325                         glu::VertexArrayBinding vertexArrays[] =
326                         {
327                                 glu::VertexArrayBinding(glu::BindingPoint("a_position"), glu::VertexArrayPointer(glu::VTX_COMP_FLOAT, glu::VTX_COMP_CONVERT_NONE, 2, 6, 0, s_positions))
328                         };
329
330                         glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));
331
332                         gl.uniform1f(scaleLoc, 0.25f);
333                         GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f(scaleLoc, 0.25f)");
334
335                         glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));
336
337                         break;
338                 }
339
340                 case GL_TEXTURE_3D:
341                 {
342                         glu::VertexArrayBinding vertexArrays[] =
343                         {
344                                 glu::VertexArrayBinding(glu::BindingPoint("a_position"), glu::VertexArrayPointer(glu::VTX_COMP_FLOAT, glu::VTX_COMP_CONVERT_NONE, 3, 6, 0, s_positions3D))
345                         };
346
347                         glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));
348
349                         gl.uniform1f(scaleLoc, 0.25f);
350                         GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f(scaleLoc, 0.25f)");
351
352                         glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));
353
354                         break;
355                 }
356
357                 case GL_TEXTURE_CUBE_MAP:
358                 {
359                         glu::VertexArrayBinding vertexArrays[] =
360                         {
361                                 glu::VertexArrayBinding(glu::BindingPoint("a_position"), glu::VertexArrayPointer(glu::VTX_COMP_FLOAT, glu::VTX_COMP_CONVERT_NONE, 4, 6, 0, s_positionsCube))
362                         };
363
364                         glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));
365
366                         gl.uniform1f(scaleLoc, 0.25f);
367                         GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f(scaleLoc, 0.25f)");
368
369                         glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));
370
371                         break;
372                 }
373
374                 default:
375                         DE_ASSERT(false);
376         }
377 }
378
379 GLuint TextureSamplerTest::createTexture2D (const glw::Functions& gl)
380 {
381         GLuint                  texture         = (GLuint)-1;
382         tcu::Texture2D  refTexture      (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEXTURE2D_WIDTH, TEXTURE2D_HEIGHT);
383
384         refTexture.allocLevel(0);
385         tcu::fillWithComponentGradients(refTexture.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
386
387         gl.genTextures(1, &texture);
388         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures(1, &texture)");
389
390         gl.bindTexture(GL_TEXTURE_2D, texture);
391         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_2D, texture)");
392
393         gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, refTexture.getWidth(), refTexture.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, refTexture.getLevel(0).getDataPtr());
394         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, refTexture.getWidth(), refTexture.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, refTexture.getLevel(0).getDataPtr())");
395
396         gl.generateMipmap(GL_TEXTURE_2D);
397         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap(GL_TEXTURE_2D)");
398
399         gl.bindTexture(GL_TEXTURE_2D, 0);
400         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_2D, texture)");
401
402         return texture;
403 }
404
405 GLuint TextureSamplerTest::createTexture3D (const glw::Functions& gl)
406 {
407         GLuint                  texture         = (GLuint)-1;
408         tcu::Texture3D  refTexture      (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEXTURE3D_WIDTH, TEXTURE3D_HEIGHT, TEXTURE3D_DEPTH);
409
410         refTexture.allocLevel(0);
411         tcu::fillWithComponentGradients(refTexture.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
412
413         gl.genTextures(1, &texture);
414         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures(1, &texture)");
415
416         gl.bindTexture(GL_TEXTURE_3D, texture);
417         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_3D, texture)");
418
419         gl.texImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, refTexture.getWidth(), refTexture.getHeight(), refTexture.getDepth(), 0, GL_RGBA, GL_UNSIGNED_BYTE, refTexture.getLevel(0).getDataPtr());
420         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, refTexture.getWidth(), refTexture.getHeight(), refTexture.getDepth(), 0, GL_RGBA, GL_UNSIGNED_BYTE, refTexture.getLevel(0).getDataPtr())");
421
422         gl.generateMipmap(GL_TEXTURE_3D);
423         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap(GL_TEXTURE_3D)");
424
425         gl.bindTexture(GL_TEXTURE_3D, 0);
426         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_3D, 0)");
427
428         return texture;
429 }
430
431 GLuint TextureSamplerTest::createTextureCube (const glw::Functions& gl)
432 {
433         GLuint                          texture         = (GLuint)-1;
434         tcu::TextureCube        refTexture      (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), CUBEMAP_SIZE);
435
436         refTexture.allocLevel(tcu::CUBEFACE_POSITIVE_X, 0);
437         refTexture.allocLevel(tcu::CUBEFACE_POSITIVE_Y, 0);
438         refTexture.allocLevel(tcu::CUBEFACE_POSITIVE_Z, 0);
439         refTexture.allocLevel(tcu::CUBEFACE_NEGATIVE_X, 0);
440         refTexture.allocLevel(tcu::CUBEFACE_NEGATIVE_Y, 0);
441         refTexture.allocLevel(tcu::CUBEFACE_NEGATIVE_Z, 0);
442
443         tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_POSITIVE_X), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
444         tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_POSITIVE_Y), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
445         tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_POSITIVE_Z), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
446         tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_NEGATIVE_X), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
447         tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_NEGATIVE_Y), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
448         tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_NEGATIVE_Z), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
449
450         gl.bindTexture(GL_TEXTURE_CUBE_MAP, texture);
451         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_CUBE_MAP, texture)");
452
453         for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
454         {
455                 const deUint32 target = glu::getGLCubeFace((tcu::CubeFace)face);
456                 gl.texImage2D(target, 0, GL_RGBA8, refTexture.getSize(), refTexture.getSize(), 0, GL_RGBA, GL_UNSIGNED_BYTE, refTexture.getLevelFace(0, (tcu::CubeFace)face).getDataPtr());
457         }
458         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D(GL_TEXTURE_CUBE_MAP_...) failed");
459
460         gl.generateMipmap(GL_TEXTURE_CUBE_MAP);
461         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap(GL_TEXTURE_CUBE_MAP)");
462         gl.bindTexture(GL_TEXTURE_CUBE_MAP, 0);
463         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_CUBE_MAP, texture)");
464
465         return texture;
466 }
467
468 GLuint TextureSamplerTest::createTexture (const glw::Functions& gl, GLenum target)
469 {
470         switch (target)
471         {
472                 case GL_TEXTURE_2D:
473                         return createTexture2D(gl);
474
475                 case GL_TEXTURE_3D:
476                         return createTexture3D(gl);
477
478                 case GL_TEXTURE_CUBE_MAP:
479                         return createTextureCube(gl);
480
481                 default:
482                         DE_ASSERT(false);
483                         return (GLuint)-1;
484         }
485 }
486
487 void TextureSamplerTest::renderReferences (tcu::Surface& textureRef, tcu::Surface& samplerRef, int x, int y)
488 {
489         const glw::Functions&   gl              = m_renderCtx.getFunctions();
490         GLuint                                  texture = createTexture(gl, m_target);
491
492         gl.viewport(x, y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
493         GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport(x, y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT)");
494
495         gl.bindTexture(m_target, texture);
496         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, texture)");
497
498         setTextureState(gl, m_target, m_textureState);
499         render();
500         glu::readPixels(m_renderCtx, x, y, textureRef.getAccess());
501
502         setTextureState(gl, m_target, m_samplerState);
503         render();
504         glu::readPixels(m_renderCtx, x, y, samplerRef.getAccess());
505
506         gl.deleteTextures(1, &texture);
507         GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures(1, &texture)");
508 }
509
510 void TextureSamplerTest::renderResults (tcu::Surface& textureResult, tcu::Surface& samplerResult, int x, int y)
511 {
512         const glw::Functions&   gl              = m_renderCtx.getFunctions();
513         GLuint                                  texture = createTexture(gl, m_target);
514         GLuint                                  sampler = -1;
515
516         gl.viewport(x, y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
517         GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport(x, y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT)");
518
519         gl.genSamplers(1, &sampler);
520         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenSamplers(1, &sampler)");
521         TCU_CHECK(sampler != (GLuint)-1);
522
523         gl.bindSampler(0, sampler);
524         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindSampler(0, sampler)");
525
526         // First set sampler state
527         setSamplerState(gl, m_samplerState, sampler);
528
529         // Set texture state
530         gl.bindTexture(m_target, texture);
531         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, texture)");
532
533         setTextureState(gl, m_target, m_textureState);
534
535         // Render using sampler
536         render();
537         glu::readPixels(m_renderCtx, x, y, samplerResult.getAccess());
538
539         // Render without sampler
540         gl.bindSampler(0, 0);
541         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindSampler(0, 0)");
542
543         render();
544         glu::readPixels(m_renderCtx, x, y, textureResult.getAccess());
545
546         gl.deleteSamplers(1, &sampler);
547         GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteSamplers(1, &sampler)");
548         gl.deleteTextures(1, &texture);
549         GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures(1, &texture)");
550 }
551
552 tcu::TestCase::IterateResult TextureSamplerTest::iterate (void)
553 {
554         tcu::TestLog&   log = m_testCtx.getLog();
555
556         tcu::Surface    textureRef(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
557         tcu::Surface    samplerRef(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
558
559         tcu::Surface    textureResult(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
560         tcu::Surface    samplerResult(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
561
562         int                             x = m_random.getInt(0, m_renderCtx.getRenderTarget().getWidth() - VIEWPORT_WIDTH);
563         int                             y = m_random.getInt(0, m_renderCtx.getRenderTarget().getHeight() - VIEWPORT_HEIGHT);
564
565         renderReferences(textureRef, samplerRef, x, y);
566         renderResults(textureResult, samplerResult, x, y);
567
568         bool isOk = pixelThresholdCompare (log, "Sampler render result", "Result from rendering with sampler", samplerRef, samplerResult, tcu::RGBA(0, 0, 0, 0), tcu::COMPARE_LOG_RESULT);
569
570         if (!pixelThresholdCompare (log, "Texture render result", "Result from rendering with texture state", textureRef, textureResult, tcu::RGBA(0, 0, 0, 0), tcu::COMPARE_LOG_RESULT))
571                 isOk = false;
572
573         if (!isOk)
574         {
575                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
576                 return STOP;
577         }
578
579         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
580         return STOP;
581 }
582
583 MultiTextureSamplerTest::MultiTextureSamplerTest (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const TestSpec& spec)
584         : TestCase                      (testCtx, spec.name, spec.desc)
585         , m_renderCtx           (renderCtx)
586         , m_program                     (NULL)
587         , m_target                      (spec.target)
588         , m_textureState1       (spec.textureState1)
589         , m_textureState2       (spec.textureState2)
590         , m_samplerState        (spec.samplerState)
591         , m_random                      (deStringHash(spec.name))
592 {
593 }
594
595 void MultiTextureSamplerTest::setTextureState (const glw::Functions& gl, GLenum target, SamplingState state)
596 {
597         gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, state.minFilter);
598         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(target, GL_TEXTURE_MIN_FILTER, state.minFilter)");
599         gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, state.magFilter);
600         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(target, GL_TEXTURE_MAG_FILTER, state.magFilter)");
601         gl.texParameteri(target, GL_TEXTURE_WRAP_S, state.wrapS);
602         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(target, GL_TEXTURE_WRAP_S, state.wrapS)");
603         gl.texParameteri(target, GL_TEXTURE_WRAP_T, state.wrapT);
604         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(target, GL_TEXTURE_WRAP_T, state.wrapT)");
605         gl.texParameteri(target, GL_TEXTURE_WRAP_R, state.wrapR);
606         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(target, GL_TEXTURE_WRAP_R, state.wrapR)");
607         gl.texParameterf(target, GL_TEXTURE_MAX_LOD, state.maxLod);
608         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameterf(target, GL_TEXTURE_MAX_LOD, state.maxLod)");
609         gl.texParameterf(target, GL_TEXTURE_MIN_LOD, state.minLod);
610         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameterf(target, GL_TEXTURE_MIN_LOD, state.minLod)");
611 }
612
613 void MultiTextureSamplerTest::setSamplerState (const glw::Functions& gl, SamplingState state, GLuint sampler)
614 {
615         gl.samplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, state.minFilter);
616         GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, state.minFilter)");
617         gl.samplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, state.magFilter);
618         GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, state.magFilter)");
619         gl.samplerParameteri(sampler, GL_TEXTURE_WRAP_S, state.wrapS);
620         GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, state.wrapS)");
621         gl.samplerParameteri(sampler, GL_TEXTURE_WRAP_T, state.wrapT);
622         GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, state.wrapT)");
623         gl.samplerParameteri(sampler, GL_TEXTURE_WRAP_R, state.wrapR);
624         GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameteri(sampler, GL_TEXTURE_WRAP_R, state.wrapR)");
625         gl.samplerParameterf(sampler, GL_TEXTURE_MAX_LOD, state.maxLod);
626         GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameterf(sampler, GL_TEXTURE_MAX_LOD, state.maxLod)");
627         gl.samplerParameterf(sampler, GL_TEXTURE_MIN_LOD, state.minLod);
628         GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameterf(sampler, GL_TEXTURE_MIN_LOD, state.minLod)");
629 }
630
631 const char* MultiTextureSamplerTest::selectVertexShader (GLenum target)
632 {
633         switch (target)
634         {
635                 case GL_TEXTURE_2D:
636                         return
637                         "${VTX_HDR}"
638                         "${VTX_IN} ${HIGHP} vec2 a_position;\n"
639                         "uniform ${HIGHP} float u_posScale;\n"
640                         "${VTX_OUT} ${MEDIUMP} vec2 v_texCoord;\n"
641                         "void main (void)\n"
642                         "{\n"
643                         "\tv_texCoord = a_position;\n"
644                         "\tgl_Position = vec4(u_posScale * a_position, 0.0, 1.0);\n"
645                         "}";
646
647                 case GL_TEXTURE_3D:
648                         return
649                         "${VTX_HDR}"
650                         "${VTX_IN} ${HIGHP} vec3 a_position;\n"
651                         "uniform ${HIGHP} float u_posScale;\n"
652                         "${VTX_OUT} ${MEDIUMP} vec3 v_texCoord;\n"
653                         "void main (void)\n"
654                         "{\n"
655                         "\tv_texCoord = a_position;\n"
656                         "\tgl_Position = vec4(u_posScale * a_position.xy, 0.0, 1.0);\n"
657                         "}";
658
659                 case GL_TEXTURE_CUBE_MAP:
660                         return
661                         "${VTX_HDR}"
662                         "${VTX_IN} ${HIGHP} vec4 a_position;\n"
663                         "uniform ${HIGHP} float u_posScale;\n"
664                         "${VTX_OUT} ${MEDIUMP} vec2 v_texCoord;\n"
665                         "void main (void)\n"
666                         "{\n"
667                         "\tv_texCoord = a_position.zw;\n"
668                         "\tgl_Position = vec4(u_posScale * a_position.xy, 0.0, 1.0);\n"
669                         "}";
670
671                 default:
672                         DE_ASSERT(false);
673                         return NULL;
674         }
675
676 }
677
678 const char* MultiTextureSamplerTest::selectFragmentShader (GLenum target)
679 {
680         switch (target)
681         {
682                 case GL_TEXTURE_2D:
683                         return
684                         "${FRAG_HDR}"
685                         "uniform ${LOWP} sampler2D u_sampler1;\n"
686                         "uniform ${LOWP} sampler2D u_sampler2;\n"
687                         "${FRAG_IN} ${MEDIUMP} vec2 v_texCoord;\n"
688                         "void main (void)\n"
689                         "{\n"
690                         "\t${FRAG_COLOR} = vec4(0.75, 0.75, 0.75, 1.0) * (texture(u_sampler1, v_texCoord) + texture(u_sampler2, v_texCoord));\n"
691                         "}";
692
693                         break;
694
695                 case GL_TEXTURE_3D:
696                         return
697                         "${FRAG_HDR}"
698                         "uniform ${LOWP} sampler3D u_sampler1;\n"
699                         "uniform ${LOWP} sampler3D u_sampler2;\n"
700                         "${FRAG_IN} ${MEDIUMP} vec3 v_texCoord;\n"
701                         "void main (void)\n"
702                         "{\n"
703                         "\t${FRAG_COLOR} = vec4(0.75, 0.75, 0.75, 1.0) * (texture(u_sampler1, v_texCoord) + texture(u_sampler2, v_texCoord));\n"
704                         "}";
705
706                 case GL_TEXTURE_CUBE_MAP:
707                         return
708                         "${FRAG_HDR}"
709                         "uniform ${LOWP} samplerCube u_sampler1;\n"
710                         "uniform ${LOWP} samplerCube u_sampler2;\n"
711                         "${FRAG_IN} ${MEDIUMP} vec2 v_texCoord;\n"
712                         "void main (void)\n"
713                         "{\n"
714                         "\t${FRAG_COLOR} = vec4(0.5, 0.5, 0.5, 1.0) * (texture(u_sampler1, vec3(cos(3.14 * v_texCoord.y) * sin(3.14 * v_texCoord.x), sin(3.14 * v_texCoord.y), cos(3.14 * v_texCoord.y) * cos(3.14 * v_texCoord.x)))"
715                         "+ texture(u_sampler2, vec3(cos(3.14 * v_texCoord.y) * sin(3.14 * v_texCoord.x), sin(3.14 * v_texCoord.y), cos(3.14 * v_texCoord.y) * cos(3.14 * v_texCoord.x))));\n"
716                         "}";
717
718                 default:
719                         DE_ASSERT(false);
720                         return NULL;
721         }
722
723 }
724
725 void MultiTextureSamplerTest::init (void)
726 {
727         const char* vertexShaderTemplate        = selectVertexShader(m_target);
728         const char* fragmentShaderTemplate      = selectFragmentShader(m_target);
729
730         std::map<std::string, std::string>      params;
731
732         if (glu::isGLSLVersionSupported(m_renderCtx.getType(), glu::GLSL_VERSION_300_ES))
733         {
734                 params["VTX_HDR"]               = "#version 300 es\n";
735                 params["FRAG_HDR"]              = "#version 300 es\nlayout(location = 0) out mediump vec4 o_color;\n";
736                 params["VTX_IN"]                = "in";
737                 params["VTX_OUT"]               = "out";
738                 params["FRAG_IN"]               = "in";
739                 params["FRAG_COLOR"]    = "o_color";
740                 params["HIGHP"]                 = "highp";
741                 params["LOWP"]                  = "lowp";
742                 params["MEDIUMP"]               = "mediump";
743         }
744         else if (glu::isGLSLVersionSupported(m_renderCtx.getType(), glu::GLSL_VERSION_330))
745         {
746                 params["VTX_HDR"]               = "#version 330\n";
747                 params["FRAG_HDR"]              = "#version 330\nlayout(location = 0) out mediump vec4 o_color;\n";
748                 params["VTX_IN"]                = "in";
749                 params["VTX_OUT"]               = "out";
750                 params["FRAG_IN"]               = "in";
751                 params["FRAG_COLOR"]    = "o_color";
752                 params["HIGHP"]                 = "highp";
753                 params["LOWP"]                  = "lowp";
754                 params["MEDIUMP"]               = "mediump";
755         }
756         else
757                 DE_ASSERT(false);
758
759         DE_ASSERT(!m_program);
760         m_program = new glu::ShaderProgram(m_renderCtx,
761                                                                            glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderTemplate).specialize(params),
762                                                                                                                            tcu::StringTemplate(fragmentShaderTemplate).specialize(params)));
763         if (!m_program->isOk())
764         {
765                 tcu::TestLog& log = m_testCtx.getLog();
766
767                 log << *m_program;
768                 TCU_FAIL("Failed to compile shaders");
769         }
770 }
771
772 void MultiTextureSamplerTest::deinit (void)
773 {
774         delete m_program;
775         m_program = NULL;
776 }
777
778 MultiTextureSamplerTest::~MultiTextureSamplerTest (void)
779 {
780         deinit();
781 }
782
783 void MultiTextureSamplerTest::render (void)
784 {
785         const glw::Functions& gl = m_renderCtx.getFunctions();
786
787         GLuint  samplerLoc1     = (GLuint)-1;
788         GLuint  samplerLoc2     = (GLuint)-1;
789         GLuint  scaleLoc        = (GLuint)-1;
790
791         gl.useProgram(m_program->getProgram());
792         GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram(m_program->getProgram())");
793
794         samplerLoc1 = glGetUniformLocation(m_program->getProgram(), "u_sampler1");
795         TCU_CHECK(samplerLoc1 != (GLuint)-1);
796
797         samplerLoc2 = glGetUniformLocation(m_program->getProgram(), "u_sampler2");
798         TCU_CHECK(samplerLoc2 != (GLuint)-1);
799
800         scaleLoc = glGetUniformLocation(m_program->getProgram(), "u_posScale");
801         TCU_CHECK(scaleLoc != (GLuint)-1);
802
803         gl.clearColor(0.5f, 0.5f, 0.5f, 1.0f);
804         GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor(0.5f, 0.5f, 0.5f, 1.0f)");
805
806         gl.clear(GL_COLOR_BUFFER_BIT);
807         GLU_EXPECT_NO_ERROR(gl.getError(), "glClear(GL_COLOR_BUFFER_BIT)");
808
809         gl.uniform1i(samplerLoc1, 0);
810         GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i(samplerLoc1, 0)");
811
812         gl.uniform1i(samplerLoc2, 1);
813         GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i(samplerLoc2, 1)");
814
815         gl.uniform1f(scaleLoc, 1.0f);
816         GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f(scaleLoc, 1.0f)");
817
818         switch (m_target)
819         {
820                 case GL_TEXTURE_2D:
821                 {
822                         glu::VertexArrayBinding vertexArrays[] =
823                         {
824                                 glu::VertexArrayBinding(glu::BindingPoint("a_position"), glu::VertexArrayPointer(glu::VTX_COMP_FLOAT, glu::VTX_COMP_CONVERT_NONE, 2, 6, 0, s_positions))
825                         };
826
827                         glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));
828
829                         gl.uniform1f(scaleLoc, 0.25f);
830                         GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f(scaleLoc, 0.25f)");
831
832                         glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));
833
834                         break;
835                 }
836
837                 case GL_TEXTURE_3D:
838                 {
839                         glu::VertexArrayBinding vertexArrays[] =
840                         {
841                                 glu::VertexArrayBinding(glu::BindingPoint("a_position"), glu::VertexArrayPointer(glu::VTX_COMP_FLOAT, glu::VTX_COMP_CONVERT_NONE, 3, 6, 0, s_positions3D))
842                         };
843
844                         glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));
845
846                         gl.uniform1f(scaleLoc, 0.25f);
847                         GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f(scaleLoc, 0.25f)");
848
849                         glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));
850
851                         break;
852                 }
853
854                 case GL_TEXTURE_CUBE_MAP:
855                 {
856                         glu::VertexArrayBinding vertexArrays[] =
857                         {
858                                 glu::VertexArrayBinding(glu::BindingPoint("a_position"), glu::VertexArrayPointer(glu::VTX_COMP_FLOAT, glu::VTX_COMP_CONVERT_NONE, 4, 6, 0, s_positionsCube))
859                         };
860
861                         glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));
862
863                         gl.uniform1f(scaleLoc, 0.25f);
864                         GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f(scaleLoc, 0.25f)");
865
866                         glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));
867
868                         break;
869                 }
870
871                 default:
872                         DE_ASSERT(false);
873         }
874 }
875
876 GLuint MultiTextureSamplerTest::createTexture2D (const glw::Functions& gl, int id)
877 {
878         GLuint                  texture         = (GLuint)-1;
879         tcu::Texture2D  refTexture      (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEXTURE2D_WIDTH, TEXTURE2D_HEIGHT);
880
881         refTexture.allocLevel(0);
882
883         gl.genTextures(1, &texture);
884         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures(1, &texture)");
885
886         switch (id)
887         {
888                 case 0:
889                         tcu::fillWithComponentGradients(refTexture.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.5f, 0.5f));
890                         break;
891
892                 case 1:
893                         tcu::fillWithComponentGradients(refTexture.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 1.0f, 1.0f));
894                         break;
895
896                 default:
897                         DE_ASSERT(false);
898         }
899
900         gl.bindTexture(GL_TEXTURE_2D, texture);
901         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_2D, texture)");
902
903         gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, refTexture.getWidth(), refTexture.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, refTexture.getLevel(0).getDataPtr());
904         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, refTexture.getWidth(), refTexture.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, refTexture.getLevel(0).getDataPtr())");
905
906         gl.generateMipmap(GL_TEXTURE_2D);
907         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap(GL_TEXTURE_2D)");
908
909         gl.bindTexture(GL_TEXTURE_2D, 0);
910         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_2D, 0)");
911
912         return texture;
913 }
914
915 GLuint MultiTextureSamplerTest::createTexture3D (const glw::Functions& gl, int id)
916 {
917         GLuint                  texture         = (GLuint)-1;
918         tcu::Texture3D  refTexture      (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEXTURE3D_WIDTH, TEXTURE3D_HEIGHT, TEXTURE3D_DEPTH);
919
920         refTexture.allocLevel(0);
921
922         gl.genTextures(1, &texture);
923         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures(1, &texture)");
924
925         switch (id)
926         {
927                 case 0:
928                         tcu::fillWithComponentGradients(refTexture.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.5f, 0.5f));
929                         break;
930
931                 case 1:
932                         tcu::fillWithComponentGradients(refTexture.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 1.0f, 1.0f));
933                         break;
934
935                 default:
936                         DE_ASSERT(false);
937         }
938
939         gl.bindTexture(GL_TEXTURE_3D, texture);
940         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_3D, texture)");
941
942         gl.texImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, refTexture.getWidth(), refTexture.getHeight(), refTexture.getDepth(), 0, GL_RGBA, GL_UNSIGNED_BYTE, refTexture.getLevel(0).getDataPtr());
943         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, refTexture.getWidth(), refTexture.getHeight(), refTexture.getDepth(), 0, GL_RGBA, GL_UNSIGNED_BYTE, refTexture.getLevel(0).getDataPtr())");
944
945         gl.generateMipmap(GL_TEXTURE_3D);
946         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap(GL_TEXTURE_3D)");
947
948         gl.bindTexture(GL_TEXTURE_3D, 0);
949         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_3D, 0)");
950
951         return texture;
952 }
953
954 GLuint MultiTextureSamplerTest::createTextureCube (const glw::Functions& gl, int id)
955 {
956         GLuint                          texture         = (GLuint)-1;
957         tcu::TextureCube        refTexture      (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), CUBEMAP_SIZE);
958
959         gl.genTextures(1, &texture);
960         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures(1, &texture)");
961
962         refTexture.allocLevel(tcu::CUBEFACE_POSITIVE_X, 0);
963         refTexture.allocLevel(tcu::CUBEFACE_POSITIVE_Y, 0);
964         refTexture.allocLevel(tcu::CUBEFACE_POSITIVE_Z, 0);
965         refTexture.allocLevel(tcu::CUBEFACE_NEGATIVE_X, 0);
966         refTexture.allocLevel(tcu::CUBEFACE_NEGATIVE_Y, 0);
967         refTexture.allocLevel(tcu::CUBEFACE_NEGATIVE_Z, 0);
968
969         switch (id)
970         {
971                 case 0:
972                         tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_POSITIVE_X), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f));
973                         tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_POSITIVE_Y), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f));
974                         tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_POSITIVE_Z), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f));
975                         tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_NEGATIVE_X), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f));
976                         tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_NEGATIVE_Y), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f));
977                         tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_NEGATIVE_Z), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f));
978                         break;
979
980                 case 1:
981                         tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_POSITIVE_X), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
982                         tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_POSITIVE_Y), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
983                         tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_POSITIVE_Z), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
984                         tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_NEGATIVE_X), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
985                         tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_NEGATIVE_Y), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
986                         tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_NEGATIVE_Z), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
987                         break;
988
989                 default:
990                         DE_ASSERT(false);
991         }
992
993         gl.bindTexture(GL_TEXTURE_CUBE_MAP, texture);
994         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_CUBE_MAP, texture)");
995
996         for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
997         {
998                 const deUint32 target = glu::getGLCubeFace((tcu::CubeFace)face);
999                 gl.texImage2D(target, 0, GL_RGBA8, refTexture.getSize(), refTexture.getSize(), 0, GL_RGBA, GL_UNSIGNED_BYTE, refTexture.getLevelFace(0, (tcu::CubeFace)face).getDataPtr());
1000         }
1001         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D(GL_TEXTURE_CUBE_MAP_...) failed");
1002
1003         gl.generateMipmap(GL_TEXTURE_CUBE_MAP);
1004         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap(GL_TEXTURE_CUBE_MAP)");
1005         gl.bindTexture(GL_TEXTURE_CUBE_MAP, 0);
1006         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_CUBE_MAP, 0)");
1007
1008         return texture;
1009 }
1010
1011 GLuint MultiTextureSamplerTest::createTexture (const glw::Functions& gl, GLenum target, int id)
1012 {
1013         switch (target)
1014         {
1015                 case GL_TEXTURE_2D:
1016                         return createTexture2D(gl, id);
1017
1018                 case GL_TEXTURE_3D:
1019                         return createTexture3D(gl, id);
1020
1021                 case GL_TEXTURE_CUBE_MAP:
1022                         return createTextureCube(gl, id);
1023
1024                 default:
1025                         DE_ASSERT(false);
1026                         return (GLuint)-1;
1027         }
1028 }
1029
1030 void MultiTextureSamplerTest::renderReferences (tcu::Surface& textureRef, tcu::Surface& samplerRef, int x, int y)
1031 {
1032         const glw::Functions&   gl                      = m_renderCtx.getFunctions();
1033         GLuint                                  texture1        = createTexture(gl, m_target, 0);
1034         GLuint                                  texture2        = createTexture(gl, m_target, 1);
1035
1036         gl.viewport(x, y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
1037         GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport(x, y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT)");
1038
1039         // Generate texture rendering reference
1040         gl.activeTexture(GL_TEXTURE0);
1041         GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture(GL_TEXTURE0)");
1042         gl.bindTexture(m_target, texture1);
1043         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, texture1)");
1044         setTextureState(gl, m_target, m_textureState1);
1045
1046         gl.activeTexture(GL_TEXTURE1);
1047         GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture(GL_TEXTURE1)");
1048         gl.bindTexture(m_target, texture2);
1049         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, texture2)");
1050         setTextureState(gl, m_target, m_textureState2);
1051
1052         render();
1053         glu::readPixels(m_renderCtx, x, y, textureRef.getAccess());
1054
1055         // Generate sampler rendering reference
1056         gl.activeTexture(GL_TEXTURE0);
1057         GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture(GL_TEXTURE0)");
1058         gl.bindTexture(m_target, texture1);
1059         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, texture1)");
1060         setTextureState(gl, m_target, m_samplerState);
1061
1062         gl.activeTexture(GL_TEXTURE1);
1063         GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture(GL_TEXTURE1)");
1064         gl.bindTexture(m_target, texture2);
1065         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, texture2)");
1066         setTextureState(gl, m_target, m_samplerState);
1067
1068         render();
1069         glu::readPixels(m_renderCtx, x, y, samplerRef.getAccess());
1070 }
1071
1072 void MultiTextureSamplerTest::renderResults (tcu::Surface& textureResult, tcu::Surface& samplerResult, int x, int y)
1073 {
1074         const glw::Functions&   gl                      = m_renderCtx.getFunctions();
1075         GLuint                                  texture1        = createTexture(gl, m_target, 0);
1076         GLuint                                  texture2        = createTexture(gl, m_target, 1);
1077         GLuint                                  sampler         = -1;
1078
1079         gl.viewport(x, y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
1080         GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport(x, y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT)");
1081
1082         gl.genSamplers(1, &sampler);
1083         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenSamplers(1, &sampler)");
1084         TCU_CHECK(sampler != (GLuint)-1);
1085
1086         gl.bindSampler(0, sampler);
1087         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindSampler(0, sampler)");
1088         gl.bindSampler(1, sampler);
1089         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindSampler(1, sampler)");
1090
1091         // First set sampler state
1092         setSamplerState(gl, m_samplerState, sampler);
1093
1094         // Set texture state
1095         gl.bindTexture(m_target, texture1);
1096         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, texture1)");
1097         setTextureState(gl, m_target, m_textureState1);
1098
1099         gl.bindTexture(m_target, texture2);
1100         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, texture2)");
1101         setTextureState(gl, m_target, m_textureState2);
1102
1103         gl.activeTexture(GL_TEXTURE0);
1104         GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture(GL_TEXTURE0)");
1105         gl.bindTexture(m_target, texture1);
1106         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, texture1)");
1107
1108         gl.activeTexture(GL_TEXTURE1);
1109         GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture(GL_TEXTURE1)");
1110         gl.bindTexture(m_target, texture2);
1111         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, texture2)");
1112
1113         // Render using sampler
1114         render();
1115         glu::readPixels(m_renderCtx, x, y, samplerResult.getAccess());
1116
1117         gl.bindSampler(0, 0);
1118         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindSampler(0, 0)");
1119         gl.bindSampler(1, 0);
1120         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindSampler(1, 0)");
1121
1122         render();
1123         glu::readPixels(m_renderCtx, x, y, textureResult.getAccess());
1124
1125         gl.activeTexture(GL_TEXTURE0);
1126         GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture(GL_TEXTURE0)");
1127         gl.bindTexture(m_target, 0);
1128         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, 0)");
1129
1130         gl.activeTexture(GL_TEXTURE1);
1131         GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture(GL_TEXTURE1)");
1132         gl.bindTexture(m_target, 0);
1133         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, 0)");
1134
1135         gl.deleteSamplers(1, &sampler);
1136         GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteSamplers(1, &sampler)");
1137         gl.deleteTextures(1, &texture1);
1138         GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures(1, &texture1)");
1139         gl.deleteTextures(1, &texture2);
1140         GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures(1, &texture2)");
1141 }
1142
1143 tcu::TestCase::IterateResult MultiTextureSamplerTest::iterate (void)
1144 {
1145         tcu::TestLog&   log = m_testCtx.getLog();
1146
1147         tcu::Surface    textureRef(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
1148         tcu::Surface    samplerRef(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
1149
1150         tcu::Surface    textureResult(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
1151         tcu::Surface    samplerResult(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
1152
1153         int                             x = m_random.getInt(0, m_renderCtx.getRenderTarget().getWidth() - VIEWPORT_WIDTH);
1154         int                             y = m_random.getInt(0, m_renderCtx.getRenderTarget().getHeight() - VIEWPORT_HEIGHT);
1155
1156         renderReferences(textureRef, samplerRef, x, y);
1157         renderResults(textureResult, samplerResult, x, y);
1158
1159         bool isOk = pixelThresholdCompare (log, "Sampler render result", "Result from rendering with sampler", samplerRef, samplerResult, tcu::RGBA(0, 0, 0, 0), tcu::COMPARE_LOG_RESULT);
1160
1161         if (!pixelThresholdCompare (log, "Texture render result", "Result from rendering with texture state", textureRef, textureResult, tcu::RGBA(0, 0, 0, 0), tcu::COMPARE_LOG_RESULT))
1162                 isOk = false;
1163
1164         if (!isOk)
1165         {
1166                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1167                 return STOP;
1168         }
1169
1170         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1171         return STOP;
1172 }
1173
1174
1175 } // gls
1176 } // deqp