xref: /aosp_15_r20/external/deqp/external/openglcts/modules/gl/gl4cTextureFilterMinmaxTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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, &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)
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), &params);
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