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