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