• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2016 The Khronos Group Inc.
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
22  */ /*-------------------------------------------------------------------*/
23 
24 /**
25  */ /*!
26  * \file  gl4cTextureFilterMinmaxTests.cpp
27  * \brief Conformance tests for the ARB_texture_filter_minmax functionality.
28  */ /*-------------------------------------------------------------------*/
29 
30 #include "gl4cTextureFilterMinmaxTests.hpp"
31 #include "gluContextInfo.hpp"
32 #include "gluDefs.hpp"
33 #include "gluDrawUtil.hpp"
34 #include "gluObjectWrapper.hpp"
35 #include "gluShaderProgram.hpp"
36 #include "gluTexture.hpp"
37 #include "glwEnums.hpp"
38 #include "glwFunctions.hpp"
39 #include "tcuImageIO.hpp"
40 #include "tcuRenderTarget.hpp"
41 #include "tcuTestLog.hpp"
42 #include "tcuTextureUtil.hpp"
43 
44 #include "deUniquePtr.hpp"
45 
46 #include <map>
47 #include <vector>
48 
49 namespace gl4cts
50 {
51 
52 static const int   TEXTURE_FILTER_MINMAX_SIZE			  = 32;
53 static const float TEXTURE_FILTER_MINMAX_DOWNSCALE_FACTOR = 0.57f;
54 static const float TEXTURE_FILTER_MINMAX_UPSCALE_FACTOR   = 1.63f;
55 
TextureFilterMinmaxUtils()56 TextureFilterMinmaxUtils::TextureFilterMinmaxUtils()
57 {
58 	m_reductionModeParams.push_back(ReductionModeParam(GL_MIN, false));
59 	m_reductionModeParams.push_back(ReductionModeParam(GL_WEIGHTED_AVERAGE_ARB, false));
60 	m_reductionModeParams.push_back(ReductionModeParam(GL_MAX, false));
61 
62 	m_supportedTextureTypes.push_back(new Texture1D());
63 	m_supportedTextureTypes.push_back(new Texture1DArray());
64 	m_supportedTextureTypes.push_back(new Texture2D());
65 	m_supportedTextureTypes.push_back(new Texture2DArray());
66 	m_supportedTextureTypes.push_back(new Texture3D());
67 	m_supportedTextureTypes.push_back(new TextureCube());
68 
69 	m_supportedTextureDataTypes.push_back(SupportedTextureDataType(GL_RED, GL_FLOAT, MINMAX));
70 	m_supportedTextureDataTypes.push_back(SupportedTextureDataType(GL_RED, GL_UNSIGNED_BYTE, MINMAX));
71 	m_supportedTextureDataTypes.push_back(
72 		SupportedTextureDataType(GL_DEPTH_COMPONENT, GL_FLOAT, MINMAX | EXCLUDE_3D | EXCLUDE_CUBE));
73 	m_supportedTextureDataTypes.push_back(
74 		SupportedTextureDataType(GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, MINMAX | EXCLUDE_3D | EXCLUDE_CUBE));
75 }
76 
~TextureFilterMinmaxUtils()77 TextureFilterMinmaxUtils::~TextureFilterMinmaxUtils()
78 {
79 	for (SupportedTextureTypeIter iter = m_supportedTextureTypes.begin(); iter != m_supportedTextureTypes.end(); ++iter)
80 	{
81 		SupportedTextureType* textureType = *iter;
82 		delete textureType;
83 	}
84 }
85 
86 // SupportedTextureType
87 
replaceAll(std::string & str,const std::string & from,const std::string & to)88 void TextureFilterMinmaxUtils::SupportedTextureType::replaceAll(std::string& str, const std::string& from,
89 																const std::string& to)
90 {
91 	size_t start = 0;
92 	while ((start = str.find(from, start)) != std::string::npos)
93 	{
94 		str.replace(start, from.length(), to);
95 		start += to.length();
96 	}
97 }
98 
SupportedTextureType(glw::GLenum type,const std::string & shaderTexcoordType,const std::string & shaderSamplerType)99 TextureFilterMinmaxUtils::SupportedTextureType::SupportedTextureType(glw::GLenum		type,
100 																	 const std::string& shaderTexcoordType,
101 																	 const std::string& shaderSamplerType)
102 	: m_type(type)
103 {
104 	m_vertexShader = "#version 450 core\n"
105 					 "in highp vec2 position;\n"
106 					 "in <texcoord_type> inTexcoord;\n"
107 					 "out <texcoord_type> texcoord;\n"
108 					 "void main()\n"
109 					 "{\n"
110 					 "	texcoord = inTexcoord;\n"
111 					 "	gl_Position = vec4(position, 0.0, 1.0);\n"
112 					 "}\n";
113 
114 	m_fragmentShader = "#version 450 core\n"
115 					   "uniform <sampler_type> sampler;\n"
116 					   "in <texcoord_type> texcoord;\n"
117 					   "out vec4 color;\n"
118 					   "void main()\n"
119 					   "{\n"
120 					   "	color = texture(sampler, texcoord);\n"
121 					   "}\n";
122 
123 	replaceAll(m_vertexShader, "<texcoord_type>", shaderTexcoordType);
124 	replaceAll(m_fragmentShader, "<texcoord_type>", shaderTexcoordType);
125 	replaceAll(m_fragmentShader, "<sampler_type>", shaderSamplerType);
126 }
127 
renderToFBO(const glu::RenderContext & context,glw::GLuint resultTextureId,tcu::IVec2 size,glw::GLint reductionMode)128 void TextureFilterMinmaxUtils::SupportedTextureType::renderToFBO(const glu::RenderContext& context,
129 																 glw::GLuint resultTextureId, tcu::IVec2 size,
130 																 glw::GLint reductionMode)
131 {
132 	const glw::Functions& gl = context.getFunctions();
133 
134 	gl.bindTexture(GL_TEXTURE_2D, resultTextureId);
135 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
136 
137 	gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, size.x(), size.y());
138 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");
139 
140 	glw::GLuint fbo = 0;
141 	gl.genFramebuffers(1, &fbo);
142 	GLU_EXPECT_NO_ERROR(gl.getError(), "genFramebuffers error occurred");
143 
144 	gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
145 	GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer error occurred");
146 
147 	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resultTextureId, 0);
148 	GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture2D error occurred");
149 
150 	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
151 	{
152 		throw 0;
153 	}
154 
155 	gl.viewport(0, 0, size.x(), size.y());
156 	renderQuad(context, reductionMode);
157 
158 	gl.deleteFramebuffers(1, &fbo);
159 }
160 
renderQuad(const glu::RenderContext & context,glw::GLint reductionMode)161 void TextureFilterMinmaxUtils::SupportedTextureType::renderQuad(const glu::RenderContext& context,
162 																glw::GLint				  reductionMode)
163 {
164 	const glw::Functions& gl = context.getFunctions();
165 
166 	deUint16 const quadIndices[] = { 0, 1, 2, 2, 1, 3 };
167 
168 	float const position[] = { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f };
169 
170 	std::vector<float> texCoords = getTexCoords();
171 
172 	glu::VertexArrayBinding vertexArrays[] = { glu::va::Float("position", 2, 4, 0, position),
173 											   glu::va::Float("inTexcoord", 1, 4, 0, texCoords.data()) };
174 
175 	gl.bindTexture(m_type, this->getTextureGL());
176 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
177 
178 	gl.texParameteri(m_type, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
179 	gl.texParameteri(m_type, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
180 	gl.texParameteri(m_type, GL_TEXTURE_REDUCTION_MODE_ARB, reductionMode);
181 
182 	glu::ShaderProgram program(context, glu::makeVtxFragSources(m_vertexShader, m_fragmentShader));
183 	if (!program.isOk())
184 	{
185 		TCU_FAIL("Shader compilation failed");
186 	}
187 
188 	gl.useProgram(program.getProgram());
189 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram failed");
190 
191 	gl.uniform1i(gl.getUniformLocation(program.getProgram(), "sampler"), 0);
192 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i failed");
193 
194 	gl.clear(GL_COLOR_BUFFER_BIT);
195 
196 	glu::draw(context, program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays,
197 			  glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(quadIndices), quadIndices));
198 }
199 
200 // Texture1D
201 
Texture1D()202 TextureFilterMinmaxUtils::Texture1D::Texture1D() : SupportedTextureType(GL_TEXTURE_1D, "float", "sampler1D")
203 {
204 }
205 
getTextureGL()206 glw::GLuint TextureFilterMinmaxUtils::Texture1D::getTextureGL()
207 {
208 	return m_texture->getGLTexture();
209 }
210 
getTexCoords()211 std::vector<float> TextureFilterMinmaxUtils::Texture1D::getTexCoords()
212 {
213 	float const texCoord[] = { 0.0f, 0.0f, 1.0f, 1.0f };
214 	return std::vector<float>(texCoord, texCoord + sizeof(texCoord) / sizeof(float));
215 }
216 
generate(const glu::RenderContext & context,tcu::IVec3 size,glw::GLenum format,glw::GLenum type,bool generateMipmaps)217 void TextureFilterMinmaxUtils::Texture1D::generate(const glu::RenderContext& context, tcu::IVec3 size,
218 												   glw::GLenum format, glw::GLenum type, bool generateMipmaps)
219 {
220 	const glw::Functions& gl = context.getFunctions();
221 
222 	m_texture = de::MovePtr<glu::Texture1D>(new glu::Texture1D(context, format, type, size.x()));
223 
224 	m_texture->getRefTexture().allocLevel(0);
225 	if (generateMipmaps)
226 	{
227 		m_texture->getRefTexture().allocLevel(1);
228 	}
229 	GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture1D error occurred");
230 
231 	tcu::fillWithGrid(m_texture->getRefTexture().getLevel(0), 4, tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f),
232 					  tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
233 	GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture1D error occurred");
234 
235 	m_texture->upload();
236 	GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture1D error occurred");
237 
238 	if (generateMipmaps)
239 	{
240 		gl.generateTextureMipmap(m_texture->getGLTexture());
241 	}
242 
243 	gl.activeTexture(GL_TEXTURE0);
244 }
245 
246 // Texture1DArray
247 
Texture1DArray()248 TextureFilterMinmaxUtils::Texture1DArray::Texture1DArray()
249 	: SupportedTextureType(GL_TEXTURE_1D_ARRAY, "vec2", "sampler1DArray")
250 {
251 }
252 
getTextureGL()253 glw::GLuint TextureFilterMinmaxUtils::Texture1DArray::getTextureGL()
254 {
255 	return m_texture->getGLTexture();
256 }
257 
getTexCoords()258 std::vector<float> TextureFilterMinmaxUtils::Texture1DArray::getTexCoords()
259 {
260 	float const texCoord[] = { 0.0f, 0.5f, 0.0f, 0.5f, 1.0f, 0.5f, 1.0f, 0.5f };
261 	return std::vector<float>(texCoord, texCoord + sizeof(texCoord) / sizeof(float));
262 }
263 
generate(const glu::RenderContext & context,tcu::IVec3 size,glw::GLenum format,glw::GLenum type,bool generateMipmaps)264 void TextureFilterMinmaxUtils::Texture1DArray::generate(const glu::RenderContext& context, tcu::IVec3 size,
265 														glw::GLenum format, glw::GLenum type, bool generateMipmaps)
266 {
267 	DE_UNREF(generateMipmaps);
268 
269 	const glw::Functions& gl = context.getFunctions();
270 
271 	m_texture = de::MovePtr<glu::Texture1DArray>(new glu::Texture1DArray(context, format, type, size.x(), 2));
272 
273 	m_texture->getRefTexture().allocLevel(0);
274 	m_texture->getRefTexture().allocLevel(1);
275 	GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture1DArray error occurred");
276 
277 	tcu::fillWithGrid(m_texture->getRefTexture().getLevel(0), 4, tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f),
278 					  tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
279 	GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture1DArray error occurred");
280 
281 	tcu::fillWithGrid(m_texture->getRefTexture().getLevel(1), 4, tcu::Vec4(0.0f, 1.0f, 1.0f, 1.0f),
282 					  tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
283 	GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture1DArray error occurred");
284 
285 	m_texture->upload();
286 	GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture1DArray error occurred");
287 
288 	gl.activeTexture(GL_TEXTURE0);
289 }
290 
291 // Texture2D
292 
Texture2D()293 TextureFilterMinmaxUtils::Texture2D::Texture2D() : SupportedTextureType(GL_TEXTURE_2D, "vec2", "sampler2D")
294 {
295 }
296 
getTextureGL()297 glw::GLuint TextureFilterMinmaxUtils::Texture2D::getTextureGL()
298 {
299 	return m_texture->getGLTexture();
300 }
301 
getTexCoords()302 std::vector<float> TextureFilterMinmaxUtils::Texture2D::getTexCoords()
303 {
304 	float const texCoord[] = { 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f };
305 	return std::vector<float>(texCoord, texCoord + sizeof(texCoord) / sizeof(float));
306 }
307 
generate(const glu::RenderContext & context,tcu::IVec3 size,glw::GLenum format,glw::GLenum type,bool generateMipmaps)308 void TextureFilterMinmaxUtils::Texture2D::generate(const glu::RenderContext& context, tcu::IVec3 size,
309 												   glw::GLenum format, glw::GLenum type, bool generateMipmaps)
310 {
311 	const glw::Functions& gl = context.getFunctions();
312 
313 	m_texture = de::MovePtr<glu::Texture2D>(new glu::Texture2D(context, format, type, size.x(), size.y()));
314 
315 	m_texture->getRefTexture().allocLevel(0);
316 	if (generateMipmaps)
317 	{
318 		m_texture->getRefTexture().allocLevel(1);
319 	}
320 	GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture2D error occurred");
321 
322 	tcu::fillWithGrid(m_texture->getRefTexture().getLevel(0), 4, tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f),
323 					  tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
324 	GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture2D error occurred");
325 
326 	m_texture->upload();
327 	GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture2D error occurred");
328 
329 	if (generateMipmaps)
330 	{
331 		gl.generateTextureMipmap(m_texture->getGLTexture());
332 	}
333 
334 	gl.activeTexture(GL_TEXTURE0);
335 }
336 
337 // Texture2DArray
338 
Texture2DArray()339 TextureFilterMinmaxUtils::Texture2DArray::Texture2DArray()
340 	: SupportedTextureType(GL_TEXTURE_2D_ARRAY, "vec3", "sampler2DArray")
341 {
342 }
343 
getTextureGL()344 glw::GLuint TextureFilterMinmaxUtils::Texture2DArray::getTextureGL()
345 {
346 	return m_texture->getGLTexture();
347 }
348 
getTexCoords()349 std::vector<float> TextureFilterMinmaxUtils::Texture2DArray::getTexCoords()
350 {
351 	float const texCoord[] = { 0.0f, 0.0f, 0.5f, 0.0f, 1.0f, 0.5f, 1.0f, 0.0f, 0.5f, 1.0f, 1.0f, 0.5f };
352 	return std::vector<float>(texCoord, texCoord + sizeof(texCoord) / sizeof(float));
353 }
354 
generate(const glu::RenderContext & context,tcu::IVec3 size,glw::GLenum format,glw::GLenum type,bool generateMipmaps)355 void TextureFilterMinmaxUtils::Texture2DArray::generate(const glu::RenderContext& context, tcu::IVec3 size,
356 														glw::GLenum format, glw::GLenum type, bool generateMipmaps)
357 {
358 	DE_UNREF(generateMipmaps);
359 
360 	const glw::Functions& gl = context.getFunctions();
361 
362 	m_texture = de::MovePtr<glu::Texture2DArray>(new glu::Texture2DArray(context, format, type, size.x(), size.y(), 2));
363 
364 	m_texture->getRefTexture().allocLevel(0);
365 	m_texture->getRefTexture().allocLevel(1);
366 	GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture2DArray error occurred");
367 
368 	tcu::fillWithGrid(m_texture->getRefTexture().getLevel(0), 4, tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f),
369 					  tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
370 	GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture2DArray error occurred");
371 
372 	tcu::fillWithGrid(m_texture->getRefTexture().getLevel(1), 4, tcu::Vec4(0.0f, 1.0f, 1.0f, 1.0f),
373 					  tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
374 	GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture2DArray error occurred");
375 
376 	m_texture->upload();
377 	GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture2DArray error occurred");
378 
379 	gl.activeTexture(GL_TEXTURE0);
380 }
381 
382 // Texture3D
383 
Texture3D()384 TextureFilterMinmaxUtils::Texture3D::Texture3D() : SupportedTextureType(GL_TEXTURE_3D, "vec3", "sampler3D")
385 {
386 }
387 
getTextureGL()388 glw::GLuint TextureFilterMinmaxUtils::Texture3D::getTextureGL()
389 {
390 	return m_texture->getGLTexture();
391 }
392 
getTexCoords()393 std::vector<float> TextureFilterMinmaxUtils::Texture3D::getTexCoords()
394 {
395 	float const texCoord[] = { 0.0f, 0.0f, 0.5f, 0.0f, 1.0f, 0.5f, 1.0f, 0.0f, 0.5f, 1.0f, 1.0f, 0.5f };
396 	return std::vector<float>(texCoord, texCoord + sizeof(texCoord) / sizeof(float));
397 }
398 
generate(const glu::RenderContext & context,tcu::IVec3 size,glw::GLenum format,glw::GLenum type,bool generateMipmaps)399 void TextureFilterMinmaxUtils::Texture3D::generate(const glu::RenderContext& context, tcu::IVec3 size,
400 												   glw::GLenum format, glw::GLenum type, bool generateMipmaps)
401 {
402 	DE_UNREF(generateMipmaps);
403 
404 	const glw::Functions& gl = context.getFunctions();
405 
406 	m_texture = de::MovePtr<glu::Texture3D>(new glu::Texture3D(context, format, type, size.x(), size.y(), size.z()));
407 
408 	m_texture->getRefTexture().allocLevel(0);
409 	GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture3D error occurred");
410 
411 	tcu::fillWithGrid(m_texture->getRefTexture().getLevel(0), 4, tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f),
412 					  tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
413 	GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture3D error occurred");
414 
415 	m_texture->upload();
416 	GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture3D error occurred");
417 
418 	gl.activeTexture(GL_TEXTURE0);
419 }
420 
421 // TextureCube
422 
TextureCube()423 TextureFilterMinmaxUtils::TextureCube::TextureCube() : SupportedTextureType(GL_TEXTURE_CUBE_MAP, "vec3", "samplerCube")
424 {
425 }
426 
getTextureGL()427 glw::GLuint TextureFilterMinmaxUtils::TextureCube::getTextureGL()
428 {
429 	return m_texture->getGLTexture();
430 }
431 
getTexCoords()432 std::vector<float> TextureFilterMinmaxUtils::TextureCube::getTexCoords()
433 {
434 	float const texCoord[] = { 1.0f, 1.0f, 0.0f, -1.0f, 1.0f, 0.0f, -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f };
435 	return std::vector<float>(texCoord, texCoord + sizeof(texCoord) / sizeof(float));
436 }
437 
generate(const glu::RenderContext & context,tcu::IVec3 size,glw::GLenum format,glw::GLenum type,bool generateMipmaps)438 void TextureFilterMinmaxUtils::TextureCube::generate(const glu::RenderContext& context, tcu::IVec3 size,
439 													 glw::GLenum format, glw::GLenum type, bool generateMipmaps)
440 {
441 	DE_UNREF(generateMipmaps);
442 
443 	const glw::Functions& gl = context.getFunctions();
444 
445 	m_texture = de::MovePtr<glu::TextureCube>(new glu::TextureCube(context, format, type, size.x()));
446 
447 	for (int faceIndex = 0; faceIndex < tcu::CUBEFACE_LAST; ++faceIndex)
448 	{
449 		m_texture->getRefTexture().allocLevel((tcu::CubeFace)faceIndex, 0);
450 		GLU_EXPECT_NO_ERROR(gl.getError(), "glu::TextureCube error occurred");
451 
452 		tcu::fillWithGrid(m_texture->getRefTexture().getLevelFace(0, (tcu::CubeFace)faceIndex), 4,
453 						  tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
454 		GLU_EXPECT_NO_ERROR(gl.getError(), "glu::TextureCube error occurred");
455 	}
456 
457 	m_texture->upload();
458 	GLU_EXPECT_NO_ERROR(gl.getError(), "glu::TextureCube error occurred");
459 
460 	gl.activeTexture(GL_TEXTURE0);
461 }
462 
463 // TextureFilterMinmaxUtils methods
464 
getDataFromTexture(const glu::RenderContext & context,glw::GLuint textureId,tcu::IVec2 textureSize,glw::GLenum format,glw::GLenum type)465 std::vector<glw::GLuint> TextureFilterMinmaxUtils::getDataFromTexture(const glu::RenderContext& context,
466 																	  glw::GLuint textureId, tcu::IVec2 textureSize,
467 																	  glw::GLenum format, glw::GLenum type)
468 {
469 	const glw::Functions& gl = context.getFunctions();
470 
471 	glw::GLsizei imageLength = textureSize.x() * textureSize.y();
472 
473 	std::vector<glw::GLuint> data;
474 	data.resize(imageLength);
475 
476 	gl.bindTexture(GL_TEXTURE_2D, textureId);
477 	GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture error occurred");
478 
479 	gl.getTexImage(GL_TEXTURE_2D, 0, format, type, &data[0]);
480 	GLU_EXPECT_NO_ERROR(gl.getError(), "getTexImage error occurred");
481 
482 	return data;
483 }
484 
calcPixelSumValue(const glu::RenderContext & context,glw::GLuint textureId,tcu::IVec2 textureSize,glw::GLenum format,glw::GLenum type)485 glw::GLuint TextureFilterMinmaxUtils::calcPixelSumValue(const glu::RenderContext& context, glw::GLuint textureId,
486 														tcu::IVec2 textureSize, glw::GLenum format, glw::GLenum type)
487 {
488 	std::vector<glw::GLuint> textureData = getDataFromTexture(context, textureId, textureSize, format, type);
489 
490 	glw::GLuint sum = 0;
491 
492 	for (size_t texel = 0; texel < textureData.size(); ++texel)
493 	{
494 		tcu::RGBA rgba(textureData[texel]);
495 		sum += rgba.getRed();
496 		sum += rgba.getGreen();
497 		sum += rgba.getBlue();
498 		sum += rgba.getAlpha();
499 	}
500 
501 	return sum;
502 }
503 
504 /** Constructor.
505 *
506 *  @param context Rendering context
507 */
TextureFilterMinmaxParameterQueriesTestCase(deqp::Context & context)508 TextureFilterMinmaxParameterQueriesTestCase::TextureFilterMinmaxParameterQueriesTestCase(deqp::Context& context)
509 	: TestCase(context, "TextureFilterMinmaxParameterQueries",
510 			   "Implements all parameter queries tests described in CTS_ARB_texture_filter_minmax")
511 {
512 	/* Left blank intentionally */
513 }
514 
515 /** Executes test iteration.
516  *
517  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
518  */
iterate()519 tcu::TestNode::IterateResult TextureFilterMinmaxParameterQueriesTestCase::iterate()
520 {
521 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_texture_filter_minmax"))
522 	{
523 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
524 		return STOP;
525 	}
526 
527 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
528 
529 	testReductionModeQueriesDefaultValues(gl);
530 
531 	for (TextureFilterMinmaxUtils::ReductionModeParamIter iter = m_utils.getReductionModeParams().begin();
532 		 iter != m_utils.getReductionModeParams().end(); ++iter)
533 	{
534 		testReductionModeQueries(gl, iter->m_reductionMode);
535 	}
536 
537 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
538 
539 	return STOP;
540 }
541 
testReductionModeQueriesDefaultValues(const glw::Functions & gl)542 void TextureFilterMinmaxParameterQueriesTestCase::testReductionModeQueriesDefaultValues(const glw::Functions& gl)
543 {
544 	const glu::RenderContext& renderContext = m_context.getRenderContext();
545 	de::MovePtr<glu::Sampler> sampler		= de::MovePtr<glu::Sampler>(new glu::Sampler(renderContext));
546 	GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Sampler error occurred");
547 
548 	glw::GLint params;
549 
550 	gl.getSamplerParameteriv(**sampler, GL_TEXTURE_REDUCTION_MODE_ARB, &params);
551 	GLU_EXPECT_NO_ERROR(gl.getError(), "getSamplerParameteriv error occurred");
552 	TCU_CHECK_MSG(params == GL_WEIGHTED_AVERAGE_ARB, "getSamplerParameteriv value mismatch with expected default");
553 
554 	for (TextureFilterMinmaxUtils::SupportedTextureTypeIter iter = m_utils.getSupportedTextureTypes().begin();
555 		 iter != m_utils.getSupportedTextureTypes().end(); ++iter)
556 	{
557 		TextureFilterMinmaxUtils::SupportedTextureType* textureType = *iter;
558 
559 		gl.getTexParameteriv(textureType->getType(), GL_TEXTURE_REDUCTION_MODE_ARB, &params);
560 		GLU_EXPECT_NO_ERROR(gl.getError(), "getTexParameteriv error occurred");
561 		TCU_CHECK_MSG(params == GL_WEIGHTED_AVERAGE_ARB, "getTexParameteriv value mismatch with expected default");
562 
563 		gl.getTexParameterIiv(textureType->getType(), GL_TEXTURE_REDUCTION_MODE_ARB, &params);
564 		GLU_EXPECT_NO_ERROR(gl.getError(), "getTexParameterIiv error occurred");
565 		TCU_CHECK_MSG(params == GL_WEIGHTED_AVERAGE_ARB, "getTexParameterIiv value mismatch with expected default");
566 	}
567 
568 	for (TextureFilterMinmaxUtils::SupportedTextureDataTypeIter iter = m_utils.getSupportedTextureDataTypes().begin();
569 		 iter != m_utils.getSupportedTextureDataTypes().end(); ++iter)
570 	{
571 		de::MovePtr<glu::Texture2D> texture = de::MovePtr<glu::Texture2D>(new glu::Texture2D(
572 			renderContext, iter->m_format, iter->m_type, TEXTURE_FILTER_MINMAX_SIZE, TEXTURE_FILTER_MINMAX_SIZE));
573 		texture->upload();
574 		GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture2D error occurred");
575 
576 		gl.getTextureParameteriv(texture->getGLTexture(), GL_TEXTURE_REDUCTION_MODE_ARB, &params);
577 		GLU_EXPECT_NO_ERROR(gl.getError(), "getTextureParameteriv error occurred");
578 		TCU_CHECK_MSG(params == GL_WEIGHTED_AVERAGE_ARB, "getTextureParameteriv value mismatch with expected default");
579 
580 		gl.getTextureParameterIiv(texture->getGLTexture(), GL_TEXTURE_REDUCTION_MODE_ARB, &params);
581 		GLU_EXPECT_NO_ERROR(gl.getError(), "getTextureParameterIiv error occurred");
582 		TCU_CHECK_MSG(params == GL_WEIGHTED_AVERAGE_ARB, "getTextureParameterIiv value mismatch with expected default");
583 	}
584 }
585 
testReductionModeQueries(const glw::Functions & gl,glw::GLint pname)586 void TextureFilterMinmaxParameterQueriesTestCase::testReductionModeQueries(const glw::Functions& gl, glw::GLint pname)
587 {
588 	const glu::RenderContext& renderContext = m_context.getRenderContext();
589 	de::MovePtr<glu::Sampler> sampler		= de::MovePtr<glu::Sampler>(new glu::Sampler(renderContext));
590 	GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Sampler error occurred");
591 
592 	gl.samplerParameteri(**sampler, GL_TEXTURE_REDUCTION_MODE_ARB, pname);
593 	GLU_EXPECT_NO_ERROR(gl.getError(), "samplerParameteri error occurred");
594 
595 	for (TextureFilterMinmaxUtils::SupportedTextureTypeIter iter = m_utils.getSupportedTextureTypes().begin();
596 		 iter != m_utils.getSupportedTextureTypes().end(); ++iter)
597 	{
598 		TextureFilterMinmaxUtils::SupportedTextureType* textureType = *iter;
599 
600 		gl.texParameteriv(textureType->getType(), GL_TEXTURE_REDUCTION_MODE_ARB, &pname);
601 		GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteriv error occurred");
602 
603 		gl.texParameterIiv(textureType->getType(), GL_TEXTURE_REDUCTION_MODE_ARB, &pname);
604 		GLU_EXPECT_NO_ERROR(gl.getError(), "texParameterIiv error occurred");
605 	}
606 
607 	for (TextureFilterMinmaxUtils::SupportedTextureDataTypeIter iter = m_utils.getSupportedTextureDataTypes().begin();
608 		 iter != m_utils.getSupportedTextureDataTypes().end(); ++iter)
609 	{
610 		de::MovePtr<glu::Texture2D> texture = de::MovePtr<glu::Texture2D>(new glu::Texture2D(
611 			renderContext, iter->m_format, iter->m_type, TEXTURE_FILTER_MINMAX_SIZE, TEXTURE_FILTER_MINMAX_SIZE));
612 		texture->upload();
613 		GLU_EXPECT_NO_ERROR(gl.getError(), "glu::Texture2D error occurred");
614 
615 		gl.textureParameteriv(texture->getGLTexture(), GL_TEXTURE_REDUCTION_MODE_ARB, &pname);
616 		GLU_EXPECT_NO_ERROR(gl.getError(), "textureParameteriv error occurred");
617 
618 		gl.textureParameterIiv(texture->getGLTexture(), GL_TEXTURE_REDUCTION_MODE_ARB, &pname);
619 		GLU_EXPECT_NO_ERROR(gl.getError(), "textureParameterIiv error occurred");
620 	}
621 }
622 
623 /** Base class for minmax render tests. Constructor.
624 *
625 *  @param context Rendering context
626 *  @param name TestCase name
627 *  @param description TestCase description
628 *  @param renderScale Scale of rendered texture
629 *  @param mipmapping Is mipmapping enabled
630 */
TextureFilterMinmaxFilteringTestCaseBase(deqp::Context & context,const char * name,const char * description,float renderScale,bool mipmapping)631 TextureFilterMinmaxFilteringTestCaseBase::TextureFilterMinmaxFilteringTestCaseBase(deqp::Context& context,
632 																				   const char*	name,
633 																				   const char*	description,
634 																				   float renderScale, bool mipmapping)
635 	: deqp::TestCase(context, name, description), m_renderScale(renderScale), m_mipmapping(mipmapping)
636 {
637 }
638 
639 /** Executes test iteration.
640 *
641 *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
642 */
iterate()643 tcu::TestNode::IterateResult TextureFilterMinmaxFilteringTestCaseBase::iterate()
644 {
645 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_texture_filter_minmax"))
646 	{
647 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
648 		return STOP;
649 	}
650 
651 	const glu::RenderContext& renderContext = m_context.getRenderContext();
652 	const glw::Functions&	 gl			= renderContext.getFunctions();
653 
654 	for (TextureFilterMinmaxUtils::SupportedTextureTypeIter textureTypeIter =
655 			 m_utils.getSupportedTextureTypes().begin();
656 		 textureTypeIter != m_utils.getSupportedTextureTypes().end(); ++textureTypeIter)
657 	{
658 		TextureFilterMinmaxUtils::SupportedTextureType* textureType = *textureTypeIter;
659 
660 		for (TextureFilterMinmaxUtils::SupportedTextureDataTypeIter dataTypeIter =
661 				 m_utils.getSupportedTextureDataTypes().begin();
662 			 dataTypeIter != m_utils.getSupportedTextureDataTypes().end(); ++dataTypeIter)
663 		{
664 			if (!dataTypeIter->hasFlag(TextureFilterMinmaxUtils::MINMAX))
665 				continue;
666 
667 			if (dataTypeIter->hasFlag(TextureFilterMinmaxUtils::EXCLUDE_3D) && textureType->getType() == GL_TEXTURE_3D)
668 				continue;
669 
670 			if (dataTypeIter->hasFlag(TextureFilterMinmaxUtils::EXCLUDE_CUBE) &&
671 				textureType->getType() == GL_TEXTURE_CUBE_MAP)
672 				continue;
673 
674 			std::map<glw::GLint, glw::GLuint> reductionModeTexelSumMap;
675 
676 			for (TextureFilterMinmaxUtils::ReductionModeParamIter paramIter = m_utils.getReductionModeParams().begin();
677 				 paramIter != m_utils.getReductionModeParams().end(); ++paramIter)
678 			{
679 				if (paramIter->m_queryTestOnly)
680 					continue;
681 
682 				tcu::IVec2 scaledTextureSize(int(float(TEXTURE_FILTER_MINMAX_SIZE) * m_renderScale));
683 
684 				textureType->generate(renderContext, tcu::IVec3(TEXTURE_FILTER_MINMAX_SIZE), dataTypeIter->m_format,
685 									  dataTypeIter->m_type, m_mipmapping);
686 
687 				glw::GLuint resultTextureId = 0;
688 				gl.genTextures(1, &resultTextureId);
689 				GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
690 
691 				textureType->renderToFBO(renderContext, resultTextureId, scaledTextureSize, paramIter->m_reductionMode);
692 
693 				reductionModeTexelSumMap[paramIter->m_reductionMode] = m_utils.calcPixelSumValue(
694 					renderContext, resultTextureId, scaledTextureSize, GL_RED, GL_UNSIGNED_BYTE);
695 
696 				gl.deleteTextures(1, &resultTextureId);
697 			}
698 
699 			TCU_CHECK_MSG(reductionModeTexelSumMap[GL_MIN] < reductionModeTexelSumMap[GL_WEIGHTED_AVERAGE_ARB],
700 						  "Sum of texels for GL_MIN should be smaller than for GL_WEIGHTED_AVERAGE_ARB");
701 
702 			TCU_CHECK_MSG(reductionModeTexelSumMap[GL_MAX] > reductionModeTexelSumMap[GL_WEIGHTED_AVERAGE_ARB],
703 						  "Sum of texels for GL_MAX should be greater than for GL_WEIGHTED_AVERAGE_ARB");
704 		}
705 	}
706 
707 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
708 
709 	return STOP;
710 }
711 
712 /** Constructor.
713 *
714 *  @param context Rendering context
715 */
TextureFilterMinmaxMinificationFilteringTestCase(deqp::Context & context)716 TextureFilterMinmaxMinificationFilteringTestCase::TextureFilterMinmaxMinificationFilteringTestCase(
717 	deqp::Context& context)
718 	: TextureFilterMinmaxFilteringTestCaseBase(
719 		  context, "TextureFilterMinmaxMinificationFiltering",
720 		  "Implements minification filtering tests described in CTS_ARB_texture_filter_minmax",
721 		  TEXTURE_FILTER_MINMAX_DOWNSCALE_FACTOR, false)
722 {
723 	/* Left blank intentionally */
724 }
725 
726 /** Constructor.
727 *
728 *  @param context Rendering context
729 */
TextureFilterMinmaxMagnificationFilteringTestCase(deqp::Context & context)730 TextureFilterMinmaxMagnificationFilteringTestCase::TextureFilterMinmaxMagnificationFilteringTestCase(
731 	deqp::Context& context)
732 	: TextureFilterMinmaxFilteringTestCaseBase(
733 		  context, "TextureFilterMinmaxMagnificationFiltering",
734 		  "Implements magnification filtering tests described in CTS_ARB_texture_filter_minmax",
735 		  TEXTURE_FILTER_MINMAX_UPSCALE_FACTOR, false)
736 {
737 	/* Left blank intentionally */
738 }
739 
740 /** Constructor.
741 *
742 *  @param context Rendering context
743 */
TextureFilterMinmaxMipmapMinificationFilteringTestCase(deqp::Context & context)744 TextureFilterMinmaxMipmapMinificationFilteringTestCase::TextureFilterMinmaxMipmapMinificationFilteringTestCase(
745 	deqp::Context& context)
746 	: TextureFilterMinmaxFilteringTestCaseBase(
747 		  context, "TextureFilterMinmaxMipmapMinificationFiltering",
748 		  "Implements mipmap minification filtering tests described in CTS_ARB_texture_filter_minmax",
749 		  TEXTURE_FILTER_MINMAX_DOWNSCALE_FACTOR, true)
750 {
751 	/* Left blank intentionally */
752 }
753 
754 /** Constructor.
755 *
756 *  @param context Rendering context
757 */
TextureFilterMinmaxSupportTestCase(deqp::Context & context)758 TextureFilterMinmaxSupportTestCase::TextureFilterMinmaxSupportTestCase(deqp::Context& context)
759 	: TestCase(context, "TextureFilterMinmaxSupport", "Implements calling GetInternalFormat* and validates with "
760 													  "expected result described in CTS_ARB_texture_filter_minmax")
761 {
762 }
763 
764 /** Executes test iteration.
765 *
766 *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
767 */
iterate()768 tcu::TestNode::IterateResult TextureFilterMinmaxSupportTestCase::iterate()
769 {
770 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_texture_filter_minmax"))
771 	{
772 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
773 		return STOP;
774 	}
775 
776 	const glu::RenderContext& renderContext = m_context.getRenderContext();
777 	const glw::Functions&	 gl			= renderContext.getFunctions();
778 
779 	for (TextureFilterMinmaxUtils::SupportedTextureTypeIter textureTypeIter =
780 			 m_utils.getSupportedTextureTypes().begin();
781 		 textureTypeIter != m_utils.getSupportedTextureTypes().end(); ++textureTypeIter)
782 	{
783 		TextureFilterMinmaxUtils::SupportedTextureType* textureType = *textureTypeIter;
784 
785 		for (TextureFilterMinmaxUtils::SupportedTextureDataTypeIter dataTypeIter =
786 				 m_utils.getSupportedTextureDataTypes().begin();
787 			 dataTypeIter != m_utils.getSupportedTextureDataTypes().end(); ++dataTypeIter)
788 		{
789 			if (!dataTypeIter->hasFlag(TextureFilterMinmaxUtils::MINMAX))
790 				continue;
791 
792 			if (dataTypeIter->hasFlag(TextureFilterMinmaxUtils::EXCLUDE_3D) && textureType->getType() == GL_TEXTURE_3D)
793 				continue;
794 
795 			if (dataTypeIter->hasFlag(TextureFilterMinmaxUtils::EXCLUDE_CUBE) &&
796 				textureType->getType() == GL_TEXTURE_CUBE_MAP)
797 				continue;
798 
799 			glw::GLint params = 0;
800 			gl.getInternalformativ(textureType->getType(), dataTypeIter->m_format, GL_TEXTURE_REDUCTION_MODE_ARB,
801 								   sizeof(glw::GLint), &params);
802 			GLU_EXPECT_NO_ERROR(gl.getError(), "getInternalformativ() call failed.");
803 			TCU_CHECK_MSG(params, "GetInternalformativ incorrect value");
804 		}
805 	}
806 
807 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
808 
809 	return STOP;
810 }
811 
812 /** Constructor.
813  *
814  *  @param context Rendering context.
815  */
TextureFilterMinmax(deqp::Context & context)816 TextureFilterMinmax::TextureFilterMinmax(deqp::Context& context)
817 	: TestCaseGroup(context, "texture_filter_minmax_tests",
818 					"Verify conformance of CTS_ARB_texture_filter_minmax implementation")
819 {
820 }
821 
822 /** Initializes the test group contents. */
init()823 void TextureFilterMinmax::init()
824 {
825 	addChild(new TextureFilterMinmaxParameterQueriesTestCase(m_context));
826 	addChild(new TextureFilterMinmaxMinificationFilteringTestCase(m_context));
827 	addChild(new TextureFilterMinmaxMagnificationFilteringTestCase(m_context));
828 	addChild(new TextureFilterMinmaxMipmapMinificationFilteringTestCase(m_context));
829 	addChild(new TextureFilterMinmaxSupportTestCase(m_context));
830 }
831 } /* gl4cts namespace */
832