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, ¶ms);
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, ¶ms);
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, ¶ms);
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, ¶ms);
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, ¶ms);
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), ¶ms);
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