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