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 uint16_t 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)
636 , m_renderScale(renderScale)
637 , m_mipmapping(mipmapping)
638 {
639 }
640
641 /** Executes test iteration.
642 *
643 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
644 */
iterate()645 tcu::TestNode::IterateResult TextureFilterMinmaxFilteringTestCaseBase::iterate()
646 {
647 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_texture_filter_minmax"))
648 {
649 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
650 return STOP;
651 }
652
653 const glu::RenderContext &renderContext = m_context.getRenderContext();
654 const glw::Functions &gl = renderContext.getFunctions();
655
656 for (TextureFilterMinmaxUtils::SupportedTextureTypeIter textureTypeIter =
657 m_utils.getSupportedTextureTypes().begin();
658 textureTypeIter != m_utils.getSupportedTextureTypes().end(); ++textureTypeIter)
659 {
660 TextureFilterMinmaxUtils::SupportedTextureType *textureType = *textureTypeIter;
661
662 for (TextureFilterMinmaxUtils::SupportedTextureDataTypeIter dataTypeIter =
663 m_utils.getSupportedTextureDataTypes().begin();
664 dataTypeIter != m_utils.getSupportedTextureDataTypes().end(); ++dataTypeIter)
665 {
666 if (!dataTypeIter->hasFlag(TextureFilterMinmaxUtils::MINMAX))
667 continue;
668
669 if (dataTypeIter->hasFlag(TextureFilterMinmaxUtils::EXCLUDE_3D) && textureType->getType() == GL_TEXTURE_3D)
670 continue;
671
672 if (dataTypeIter->hasFlag(TextureFilterMinmaxUtils::EXCLUDE_CUBE) &&
673 textureType->getType() == GL_TEXTURE_CUBE_MAP)
674 continue;
675
676 std::map<glw::GLint, glw::GLuint> reductionModeTexelSumMap;
677
678 for (TextureFilterMinmaxUtils::ReductionModeParamIter paramIter = m_utils.getReductionModeParams().begin();
679 paramIter != m_utils.getReductionModeParams().end(); ++paramIter)
680 {
681 if (paramIter->m_queryTestOnly)
682 continue;
683
684 tcu::IVec2 scaledTextureSize(int(float(TEXTURE_FILTER_MINMAX_SIZE) * m_renderScale));
685
686 textureType->generate(renderContext, tcu::IVec3(TEXTURE_FILTER_MINMAX_SIZE), dataTypeIter->m_format,
687 dataTypeIter->m_type, m_mipmapping);
688
689 glw::GLuint resultTextureId = 0;
690 gl.genTextures(1, &resultTextureId);
691 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
692
693 textureType->renderToFBO(renderContext, resultTextureId, scaledTextureSize, paramIter->m_reductionMode);
694
695 reductionModeTexelSumMap[paramIter->m_reductionMode] = m_utils.calcPixelSumValue(
696 renderContext, resultTextureId, scaledTextureSize, GL_RED, GL_UNSIGNED_BYTE);
697
698 gl.deleteTextures(1, &resultTextureId);
699 }
700
701 TCU_CHECK_MSG(reductionModeTexelSumMap[GL_MIN] < reductionModeTexelSumMap[GL_WEIGHTED_AVERAGE_ARB],
702 "Sum of texels for GL_MIN should be smaller than for GL_WEIGHTED_AVERAGE_ARB");
703
704 TCU_CHECK_MSG(reductionModeTexelSumMap[GL_MAX] > reductionModeTexelSumMap[GL_WEIGHTED_AVERAGE_ARB],
705 "Sum of texels for GL_MAX should be greater than for GL_WEIGHTED_AVERAGE_ARB");
706 }
707 }
708
709 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
710
711 return STOP;
712 }
713
714 /** Constructor.
715 *
716 * @param context Rendering context
717 */
TextureFilterMinmaxMinificationFilteringTestCase(deqp::Context & context)718 TextureFilterMinmaxMinificationFilteringTestCase::TextureFilterMinmaxMinificationFilteringTestCase(
719 deqp::Context &context)
720 : TextureFilterMinmaxFilteringTestCaseBase(
721 context, "TextureFilterMinmaxMinificationFiltering",
722 "Implements minification filtering tests described in CTS_ARB_texture_filter_minmax",
723 TEXTURE_FILTER_MINMAX_DOWNSCALE_FACTOR, false)
724 {
725 /* Left blank intentionally */
726 }
727
728 /** Constructor.
729 *
730 * @param context Rendering context
731 */
TextureFilterMinmaxMagnificationFilteringTestCase(deqp::Context & context)732 TextureFilterMinmaxMagnificationFilteringTestCase::TextureFilterMinmaxMagnificationFilteringTestCase(
733 deqp::Context &context)
734 : TextureFilterMinmaxFilteringTestCaseBase(
735 context, "TextureFilterMinmaxMagnificationFiltering",
736 "Implements magnification filtering tests described in CTS_ARB_texture_filter_minmax",
737 TEXTURE_FILTER_MINMAX_UPSCALE_FACTOR, false)
738 {
739 /* Left blank intentionally */
740 }
741
742 /** Constructor.
743 *
744 * @param context Rendering context
745 */
TextureFilterMinmaxMipmapMinificationFilteringTestCase(deqp::Context & context)746 TextureFilterMinmaxMipmapMinificationFilteringTestCase::TextureFilterMinmaxMipmapMinificationFilteringTestCase(
747 deqp::Context &context)
748 : TextureFilterMinmaxFilteringTestCaseBase(
749 context, "TextureFilterMinmaxMipmapMinificationFiltering",
750 "Implements mipmap minification filtering tests described in CTS_ARB_texture_filter_minmax",
751 TEXTURE_FILTER_MINMAX_DOWNSCALE_FACTOR, true)
752 {
753 /* Left blank intentionally */
754 }
755
756 /** Constructor.
757 *
758 * @param context Rendering context
759 */
TextureFilterMinmaxSupportTestCase(deqp::Context & context)760 TextureFilterMinmaxSupportTestCase::TextureFilterMinmaxSupportTestCase(deqp::Context &context)
761 : TestCase(context, "TextureFilterMinmaxSupport",
762 "Implements calling GetInternalFormat* and validates with "
763 "expected result described in CTS_ARB_texture_filter_minmax")
764 {
765 }
766
767 /** Executes test iteration.
768 *
769 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
770 */
iterate()771 tcu::TestNode::IterateResult TextureFilterMinmaxSupportTestCase::iterate()
772 {
773 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_texture_filter_minmax"))
774 {
775 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
776 return STOP;
777 }
778
779 const glu::RenderContext &renderContext = m_context.getRenderContext();
780 const glw::Functions &gl = renderContext.getFunctions();
781
782 for (TextureFilterMinmaxUtils::SupportedTextureTypeIter textureTypeIter =
783 m_utils.getSupportedTextureTypes().begin();
784 textureTypeIter != m_utils.getSupportedTextureTypes().end(); ++textureTypeIter)
785 {
786 TextureFilterMinmaxUtils::SupportedTextureType *textureType = *textureTypeIter;
787
788 for (TextureFilterMinmaxUtils::SupportedTextureDataTypeIter dataTypeIter =
789 m_utils.getSupportedTextureDataTypes().begin();
790 dataTypeIter != m_utils.getSupportedTextureDataTypes().end(); ++dataTypeIter)
791 {
792 if (!dataTypeIter->hasFlag(TextureFilterMinmaxUtils::MINMAX))
793 continue;
794
795 if (dataTypeIter->hasFlag(TextureFilterMinmaxUtils::EXCLUDE_3D) && textureType->getType() == GL_TEXTURE_3D)
796 continue;
797
798 if (dataTypeIter->hasFlag(TextureFilterMinmaxUtils::EXCLUDE_CUBE) &&
799 textureType->getType() == GL_TEXTURE_CUBE_MAP)
800 continue;
801
802 glw::GLint params = 0;
803 gl.getInternalformativ(textureType->getType(), dataTypeIter->m_format, GL_TEXTURE_REDUCTION_MODE_ARB,
804 sizeof(glw::GLint), ¶ms);
805 GLU_EXPECT_NO_ERROR(gl.getError(), "getInternalformativ() call failed.");
806 TCU_CHECK_MSG(params, "GetInternalformativ incorrect value");
807 }
808 }
809
810 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
811
812 return STOP;
813 }
814
815 /** Constructor.
816 *
817 * @param context Rendering context.
818 */
TextureFilterMinmax(deqp::Context & context)819 TextureFilterMinmax::TextureFilterMinmax(deqp::Context &context)
820 : TestCaseGroup(context, "texture_filter_minmax_tests",
821 "Verify conformance of CTS_ARB_texture_filter_minmax implementation")
822 {
823 }
824
825 /** Initializes the test group contents. */
init()826 void TextureFilterMinmax::init()
827 {
828 addChild(new TextureFilterMinmaxParameterQueriesTestCase(m_context));
829 addChild(new TextureFilterMinmaxMinificationFilteringTestCase(m_context));
830 addChild(new TextureFilterMinmaxMagnificationFilteringTestCase(m_context));
831 addChild(new TextureFilterMinmaxMipmapMinificationFilteringTestCase(m_context));
832 addChild(new TextureFilterMinmaxSupportTestCase(m_context));
833 }
834 } // namespace gl4cts
835