xref: /aosp_15_r20/external/deqp/modules/gles2/functional/es2fTextureCompletenessTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 2.0 Module
3  * -------------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Texture completeness tests.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "es2fTextureCompletenessTests.hpp"
25 #include "glsTextureTestUtil.hpp"
26 
27 #include "tcuTestLog.hpp"
28 #include "tcuSurface.hpp"
29 #include "tcuImageCompare.hpp"
30 #include "tcuVector.hpp"
31 #include "tcuTextureUtil.hpp"
32 #include "tcuRenderTarget.hpp"
33 
34 #include "deRandom.hpp"
35 #include "deMath.h"
36 #include "deInt32.h"
37 #include "deString.h"
38 
39 #include "gluTextureUtil.hpp"
40 #include "gluPixelTransfer.hpp"
41 #include "gluContextInfo.hpp"
42 #include "gluRenderContext.hpp"
43 
44 #include "glw.h"
45 
46 namespace deqp
47 {
48 namespace gles2
49 {
50 namespace Functional
51 {
52 
53 using gls::TextureTestUtil::TextureRenderer;
54 using glu::TextureTestUtil::computeQuadTexCoord2D;
55 using glu::TextureTestUtil::computeQuadTexCoordCube;
56 using std::string;
57 using std::vector;
58 using tcu::IVec2;
59 using tcu::RGBA;
60 using tcu::Sampler;
61 using tcu::TestLog;
62 using tcu::TextureFormat;
63 
64 static const GLenum s_cubeTargets[] = {GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_X,
65                                        GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
66                                        GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, GL_TEXTURE_CUBE_MAP_POSITIVE_Z};
67 
isExtensionSupported(const glu::ContextInfo & ctxInfo,const char * extension)68 static bool isExtensionSupported(const glu::ContextInfo &ctxInfo, const char *extension)
69 {
70     vector<string> extensions = ctxInfo.getExtensions();
71 
72     for (vector<string>::iterator iter = extensions.begin(); iter != extensions.end(); ++iter)
73         if (iter->compare(extension) == 0)
74             return true;
75 
76     return false;
77 }
78 
compareToConstantColor(TestLog & log,const char * imageSetName,const char * imageSetDesc,const tcu::Surface & result,tcu::CompareLogMode logMode,RGBA color)79 static bool compareToConstantColor(TestLog &log, const char *imageSetName, const char *imageSetDesc,
80                                    const tcu::Surface &result, tcu::CompareLogMode logMode, RGBA color)
81 {
82     bool isOk = true;
83 
84     for (int y = 0; y < result.getHeight(); y++)
85     {
86         for (int x = 0; x < result.getWidth(); x++)
87         {
88             if (result.getPixel(x, y).getRed() != color.getRed() ||
89                 result.getPixel(x, y).getGreen() != color.getGreen() ||
90                 result.getPixel(x, y).getBlue() != color.getBlue() ||
91                 result.getPixel(x, y).getAlpha() != color.getAlpha())
92             {
93                 isOk = false;
94             }
95         }
96     }
97 
98     if (!isOk || logMode == tcu::COMPARE_LOG_EVERYTHING)
99     {
100         if (!isOk)
101             log << TestLog::Message << "Image comparison failed" << TestLog::EndMessage;
102 
103         log << TestLog::ImageSet(imageSetName, imageSetDesc) << TestLog::Image("Result", "Result", result)
104             << TestLog::EndImageSet;
105     }
106     else if (logMode == tcu::COMPARE_LOG_RESULT)
107         log << TestLog::ImageSet(imageSetName, imageSetDesc) << TestLog::Image("Result", "Result", result)
108             << TestLog::EndImageSet;
109 
110     return isOk;
111 }
112 
113 // Base classes.
114 
115 class Tex2DCompletenessCase : public tcu::TestCase
116 {
117 public:
118     Tex2DCompletenessCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const char *name,
119                           const char *description);
~Tex2DCompletenessCase(void)120     ~Tex2DCompletenessCase(void)
121     {
122     }
123 
124     IterateResult iterate(void);
125 
126 protected:
127     virtual void createTexture(GLuint texture) = 0;
128 
129     tcu::TestContext &m_testCtx;
130     glu::RenderContext &m_renderCtx;
131     RGBA m_compareColor;
132 };
133 
Tex2DCompletenessCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description)134 Tex2DCompletenessCase::Tex2DCompletenessCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const char *name,
135                                              const char *description)
136     : TestCase(testCtx, name, description)
137     , m_testCtx(testCtx)
138     , m_renderCtx(renderCtx)
139     , m_compareColor(RGBA(0, 0, 0, 255))
140 {
141 }
142 
iterate(void)143 Tex2DCompletenessCase::IterateResult Tex2DCompletenessCase::iterate(void)
144 {
145     int viewportWidth  = de::min(64, m_renderCtx.getRenderTarget().getWidth());
146     int viewportHeight = de::min(64, m_renderCtx.getRenderTarget().getHeight());
147     TestLog &log       = m_testCtx.getLog();
148     TextureRenderer renderer(m_renderCtx, log, glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP);
149     tcu::Surface renderedFrame(viewportWidth, viewportHeight);
150     vector<float> texCoord;
151 
152     de::Random random(deStringHash(getName()));
153     int offsetX = random.getInt(0, m_renderCtx.getRenderTarget().getWidth() - viewportWidth);
154     int offsetY = random.getInt(0, m_renderCtx.getRenderTarget().getHeight() - viewportHeight);
155 
156     computeQuadTexCoord2D(texCoord, tcu::Vec2(0.0f, 0.0f), tcu::Vec2(1.0f, 1.0f));
157 
158     glViewport(offsetX, offsetY, viewportWidth, viewportHeight);
159 
160     GLuint texture;
161     glGenTextures(1, &texture);
162     createTexture(texture);
163 
164     renderer.renderQuad(0, &texCoord[0], glu::TextureTestUtil::TEXTURETYPE_2D);
165     glu::readPixels(m_renderCtx, offsetX, offsetY, renderedFrame.getAccess());
166 
167     bool isOk = compareToConstantColor(log, "Result", "Image comparison result", renderedFrame, tcu::COMPARE_LOG_RESULT,
168                                        m_compareColor);
169 
170     glDeleteTextures(1, &texture);
171 
172     m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
173                             isOk ? "Pass" : "Image comparison failed");
174     return STOP;
175 }
176 
177 class TexCubeCompletenessCase : public tcu::TestCase
178 {
179 public:
180     TexCubeCompletenessCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const char *name,
181                             const char *description);
~TexCubeCompletenessCase(void)182     ~TexCubeCompletenessCase(void)
183     {
184     }
185 
186     IterateResult iterate(void);
187 
188 protected:
189     virtual void createTexture(GLuint texture) = 0;
190 
191     tcu::TestContext &m_testCtx;
192     glu::RenderContext &m_renderCtx;
193     RGBA m_compareColor;
194 };
195 
TexCubeCompletenessCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description)196 TexCubeCompletenessCase::TexCubeCompletenessCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx,
197                                                  const char *name, const char *description)
198     : TestCase(testCtx, name, description)
199     , m_testCtx(testCtx)
200     , m_renderCtx(renderCtx)
201     , m_compareColor(RGBA(0, 0, 0, 255))
202 {
203 }
204 
iterate(void)205 TexCubeCompletenessCase::IterateResult TexCubeCompletenessCase::iterate(void)
206 {
207     int viewportWidth  = de::min(64, m_renderCtx.getRenderTarget().getWidth());
208     int viewportHeight = de::min(64, m_renderCtx.getRenderTarget().getHeight());
209     bool allFacesOk    = true;
210     TestLog &log       = m_testCtx.getLog();
211     TextureRenderer renderer(m_renderCtx, log, glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP);
212     tcu::Surface renderedFrame(viewportWidth, viewportHeight);
213     vector<float> texCoord;
214 
215     de::Random random(deStringHash(getName()));
216     int offsetX = random.getInt(0, de::max(0, m_renderCtx.getRenderTarget().getWidth() - 64));
217     int offsetY = random.getInt(0, de::max(0, m_renderCtx.getRenderTarget().getHeight() - 64));
218 
219     GLuint texture;
220     glGenTextures(1, &texture);
221     createTexture(texture);
222 
223     for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
224     {
225         computeQuadTexCoordCube(texCoord, (tcu::CubeFace)face);
226 
227         glViewport(offsetX, offsetY, viewportWidth, viewportHeight);
228 
229         renderer.renderQuad(0, &texCoord[0], glu::TextureTestUtil::TEXTURETYPE_CUBE);
230         glu::readPixels(m_renderCtx, offsetX, offsetY, renderedFrame.getAccess());
231 
232         bool isOk = compareToConstantColor(log, "Result", "Image comparison result", renderedFrame,
233                                            tcu::COMPARE_LOG_RESULT, m_compareColor);
234 
235         if (!isOk)
236             allFacesOk = false;
237     }
238 
239     glDeleteTextures(1, &texture);
240 
241     m_testCtx.setTestResult(allFacesOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
242                             allFacesOk ? "Pass" : "Image comparison failed");
243     return STOP;
244 }
245 
246 // Texture 2D tests.
247 
248 class Incomplete2DSizeCase : public Tex2DCompletenessCase
249 {
250 public:
251     Incomplete2DSizeCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const char *name,
252                          const char *description, IVec2 size, IVec2 invalidLevelSize, int invalidLevelNdx,
253                          const glu::ContextInfo &ctxInfo);
~Incomplete2DSizeCase(void)254     ~Incomplete2DSizeCase(void)
255     {
256     }
257 
258     virtual void createTexture(GLuint texture);
259 
260 private:
261     int m_invalidLevelNdx;
262     IVec2 m_invalidLevelSize;
263     const glu::ContextInfo &m_ctxInfo;
264     IVec2 m_size;
265 };
266 
Incomplete2DSizeCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,IVec2 size,IVec2 invalidLevelSize,int invalidLevelNdx,const glu::ContextInfo & ctxInfo)267 Incomplete2DSizeCase::Incomplete2DSizeCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const char *name,
268                                            const char *description, IVec2 size, IVec2 invalidLevelSize,
269                                            int invalidLevelNdx, const glu::ContextInfo &ctxInfo)
270     : Tex2DCompletenessCase(testCtx, renderCtx, name, description)
271     , m_invalidLevelNdx(invalidLevelNdx)
272     , m_invalidLevelSize(invalidLevelSize)
273     , m_ctxInfo(ctxInfo)
274     , m_size(size)
275 {
276 }
277 
createTexture(GLuint texture)278 void Incomplete2DSizeCase::createTexture(GLuint texture)
279 {
280     static const char *const s_relaxingExtensions[] = {
281         "GL_OES_texture_npot",
282         "GL_NV_texture_npot_2D_mipmap",
283     };
284 
285     tcu::TextureFormat fmt = glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
286     tcu::TextureLevel levelData(fmt);
287     TestLog &log = m_testCtx.getLog();
288 
289     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
290     glBindTexture(GL_TEXTURE_2D, texture);
291 
292     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
293     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
294     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
295     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
296 
297     int numLevels = 1 + de::max(deLog2Floor32(m_size.x()), deLog2Floor32(m_size.y()));
298 
299     for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
300     {
301         int levelW = (levelNdx == m_invalidLevelNdx) ? m_invalidLevelSize.x() : de::max(1, m_size.x() >> levelNdx);
302         int levelH = (levelNdx == m_invalidLevelNdx) ? m_invalidLevelSize.y() : de::max(1, m_size.y() >> levelNdx);
303 
304         levelData.setSize(m_size.x(), m_size.y());
305         clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
306 
307         glTexImage2D(GL_TEXTURE_2D, levelNdx, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE,
308                      levelData.getAccess().getDataPtr());
309     }
310 
311     GLU_CHECK_MSG("Set texturing state");
312 
313     // If size not allowed in core, search for relaxing extensions
314     if (!deIsPowerOfTwo32(m_size.x()) && !deIsPowerOfTwo32(m_size.y()))
315     {
316         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_relaxingExtensions); ++ndx)
317         {
318             if (isExtensionSupported(m_ctxInfo, s_relaxingExtensions[ndx]))
319             {
320                 log << TestLog::Message << s_relaxingExtensions[ndx]
321                     << " supported, assuming completeness test to pass." << TestLog::EndMessage;
322                 m_compareColor = RGBA(0, 0, 255, 255);
323                 break;
324             }
325         }
326     }
327 }
328 
329 class Incomplete2DFormatCase : public Tex2DCompletenessCase
330 {
331 public:
332     Incomplete2DFormatCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const char *name,
333                            const char *description, IVec2 size, uint32_t format, uint32_t invalidFormat,
334                            int invalidLevelNdx);
~Incomplete2DFormatCase(void)335     ~Incomplete2DFormatCase(void)
336     {
337     }
338 
339     virtual void createTexture(GLuint texture);
340 
341 private:
342     int m_invalidLevelNdx;
343     uint32_t m_format;
344     uint32_t m_invalidFormat;
345     IVec2 m_size;
346 };
347 
Incomplete2DFormatCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,IVec2 size,uint32_t format,uint32_t invalidFormat,int invalidLevelNdx)348 Incomplete2DFormatCase::Incomplete2DFormatCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx,
349                                                const char *name, const char *description, IVec2 size, uint32_t format,
350                                                uint32_t invalidFormat, int invalidLevelNdx)
351     : Tex2DCompletenessCase(testCtx, renderCtx, name, description)
352     , m_invalidLevelNdx(invalidLevelNdx)
353     , m_format(format)
354     , m_invalidFormat(invalidFormat)
355     , m_size(size)
356 {
357 }
358 
createTexture(GLuint texture)359 void Incomplete2DFormatCase::createTexture(GLuint texture)
360 {
361     tcu::TextureFormat fmt = glu::mapGLTransferFormat(m_format, GL_UNSIGNED_BYTE);
362     tcu::TextureLevel levelData(fmt);
363 
364     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
365     glBindTexture(GL_TEXTURE_2D, texture);
366 
367     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
368     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
369     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
370     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
371 
372     int numLevels = 1 + de::max(deLog2Floor32(m_size.x()), deLog2Floor32(m_size.y()));
373 
374     for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
375     {
376         int levelW = de::max(1, m_size.x() >> levelNdx);
377         int levelH = de::max(1, m_size.y() >> levelNdx);
378 
379         levelData.setSize(m_size.x(), m_size.y());
380         clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
381 
382         uint32_t format = levelNdx == m_invalidLevelNdx ? m_invalidFormat : m_format;
383 
384         glTexImage2D(GL_TEXTURE_2D, levelNdx, format, levelW, levelH, 0, format, GL_UNSIGNED_BYTE,
385                      levelData.getAccess().getDataPtr());
386     }
387 
388     GLU_CHECK_MSG("Set texturing state");
389 }
390 
391 class Incomplete2DMissingLevelCase : public Tex2DCompletenessCase
392 {
393 public:
394     Incomplete2DMissingLevelCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const char *name,
395                                  const char *description, IVec2 size, int missingLevelNdx);
~Incomplete2DMissingLevelCase(void)396     ~Incomplete2DMissingLevelCase(void)
397     {
398     }
399 
400     virtual void createTexture(GLuint texture);
401 
402 private:
403     int m_missingLevelNdx;
404     IVec2 m_size;
405 };
406 
Incomplete2DMissingLevelCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,IVec2 size,int missingLevelNdx)407 Incomplete2DMissingLevelCase::Incomplete2DMissingLevelCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx,
408                                                            const char *name, const char *description, IVec2 size,
409                                                            int missingLevelNdx)
410     : Tex2DCompletenessCase(testCtx, renderCtx, name, description)
411     , m_missingLevelNdx(missingLevelNdx)
412     , m_size(size)
413 {
414 }
415 
createTexture(GLuint texture)416 void Incomplete2DMissingLevelCase::createTexture(GLuint texture)
417 {
418     tcu::TextureFormat fmt = glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
419     tcu::TextureLevel levelData(fmt);
420 
421     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
422     glBindTexture(GL_TEXTURE_2D, texture);
423 
424     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
425     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
426     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
427     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
428 
429     int numLevels = 1 + de::max(deLog2Floor32(m_size.x()), deLog2Floor32(m_size.y()));
430 
431     for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
432     {
433         levelData.setSize(m_size.x(), m_size.y());
434         clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
435 
436         int levelW = de::max(1, m_size.x() >> levelNdx);
437         int levelH = de::max(1, m_size.y() >> levelNdx);
438 
439         // Skip specified level.
440         if (levelNdx != m_missingLevelNdx)
441             glTexImage2D(GL_TEXTURE_2D, levelNdx, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE,
442                          levelData.getAccess().getDataPtr());
443     }
444 
445     GLU_CHECK_MSG("Set texturing state");
446 }
447 
448 class Incomplete2DWrapModeCase : public Tex2DCompletenessCase
449 {
450 public:
451     Incomplete2DWrapModeCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const char *name,
452                              const char *description, IVec2 size, uint32_t wrapT, uint32_t wrapS,
453                              const glu::ContextInfo &ctxInfo);
~Incomplete2DWrapModeCase(void)454     ~Incomplete2DWrapModeCase(void)
455     {
456     }
457 
458     virtual void createTexture(GLuint texture);
459 
460 private:
461     uint32_t m_wrapT;
462     uint32_t m_wrapS;
463     const glu::ContextInfo &m_ctxInfo;
464     IVec2 m_size;
465 };
466 
Incomplete2DWrapModeCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,IVec2 size,uint32_t wrapT,uint32_t wrapS,const glu::ContextInfo & ctxInfo)467 Incomplete2DWrapModeCase::Incomplete2DWrapModeCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx,
468                                                    const char *name, const char *description, IVec2 size,
469                                                    uint32_t wrapT, uint32_t wrapS, const glu::ContextInfo &ctxInfo)
470     : Tex2DCompletenessCase(testCtx, renderCtx, name, description)
471     , m_wrapT(wrapT)
472     , m_wrapS(wrapS)
473     , m_ctxInfo(ctxInfo)
474     , m_size(size)
475 {
476 }
477 
createTexture(GLuint texture)478 void Incomplete2DWrapModeCase::createTexture(GLuint texture)
479 {
480     TestLog &log           = m_testCtx.getLog();
481     tcu::TextureFormat fmt = glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
482     tcu::TextureLevel levelData(fmt);
483 
484     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
485     glBindTexture(GL_TEXTURE_2D, texture);
486 
487     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, m_wrapS);
488     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, m_wrapT);
489     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
490     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
491 
492     levelData.setSize(m_size.x(), m_size.y());
493     clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
494 
495     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_size.x(), m_size.y(), 0, GL_RGBA, GL_UNSIGNED_BYTE,
496                  levelData.getAccess().getDataPtr());
497 
498     GLU_CHECK_MSG("Set texturing state");
499 
500     const char *extension = "GL_OES_texture_npot";
501     if (isExtensionSupported(m_ctxInfo, extension))
502     {
503         log << TestLog::Message << extension << " supported, assuming completeness test to pass."
504             << TestLog::EndMessage;
505         m_compareColor = RGBA(0, 0, 255, 255);
506     }
507 }
508 
509 class Complete2DExtraLevelCase : public Tex2DCompletenessCase
510 {
511 public:
512     Complete2DExtraLevelCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const char *name,
513                              const char *description, IVec2 size);
~Complete2DExtraLevelCase(void)514     ~Complete2DExtraLevelCase(void)
515     {
516     }
517 
518     virtual void createTexture(GLuint texture);
519 
520 private:
521     IVec2 m_size;
522 };
523 
Complete2DExtraLevelCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,IVec2 size)524 Complete2DExtraLevelCase::Complete2DExtraLevelCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx,
525                                                    const char *name, const char *description, IVec2 size)
526     : Tex2DCompletenessCase(testCtx, renderCtx, name, description)
527     , m_size(size)
528 {
529 }
530 
createTexture(GLuint texture)531 void Complete2DExtraLevelCase::createTexture(GLuint texture)
532 {
533     tcu::TextureFormat fmt = glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
534     tcu::TextureLevel levelData(fmt);
535 
536     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
537     glBindTexture(GL_TEXTURE_2D, texture);
538 
539     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
540     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
541     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
542     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
543 
544     int numLevels = 1 + de::max(deLog2Floor32(m_size.x()), deLog2Floor32(m_size.y()));
545 
546     for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
547     {
548         int levelW = de::max(1, m_size.x() >> levelNdx);
549         int levelH = de::max(1, m_size.y() >> levelNdx);
550 
551         levelData.setSize(m_size.x(), m_size.y());
552         clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
553 
554         glTexImage2D(GL_TEXTURE_2D, levelNdx, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE,
555                      levelData.getAccess().getDataPtr());
556     }
557 
558     // Specify extra level.
559     glTexImage2D(GL_TEXTURE_2D, numLevels + 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
560                  levelData.getAccess().getDataPtr());
561     m_compareColor = RGBA(0, 0, 255, 255);
562 
563     GLU_CHECK_MSG("Set texturing state");
564 }
565 
566 class Incomplete2DEmptyObjectCase : public Tex2DCompletenessCase
567 {
568 public:
569     Incomplete2DEmptyObjectCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const char *name,
570                                 const char *description, IVec2 size);
~Incomplete2DEmptyObjectCase(void)571     ~Incomplete2DEmptyObjectCase(void)
572     {
573     }
574 
575     virtual void createTexture(GLuint texture);
576 
577 private:
578     IVec2 m_size;
579 };
580 
Incomplete2DEmptyObjectCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,IVec2 size)581 Incomplete2DEmptyObjectCase::Incomplete2DEmptyObjectCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx,
582                                                          const char *name, const char *description, IVec2 size)
583     : Tex2DCompletenessCase(testCtx, renderCtx, name, description)
584     , m_size(size)
585 {
586 }
587 
createTexture(GLuint texture)588 void Incomplete2DEmptyObjectCase::createTexture(GLuint texture)
589 {
590     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
591     glBindTexture(GL_TEXTURE_2D, texture);
592 
593     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
594     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
595     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
596     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
597 
598     GLU_CHECK_MSG("Set texturing state");
599 }
600 
601 // Cube texture tests.
602 
603 class IncompleteCubeSizeCase : public TexCubeCompletenessCase
604 {
605 public:
606     IncompleteCubeSizeCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const char *name,
607                            const char *description, IVec2 size, IVec2 invalidLevelSize, int invalidLevelNdx);
608     IncompleteCubeSizeCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const char *name,
609                            const char *description, IVec2 size, IVec2 invalidLevelSize, int invalidLevelNdx,
610                            tcu::CubeFace invalidCubeFace);
~IncompleteCubeSizeCase(void)611     ~IncompleteCubeSizeCase(void)
612     {
613     }
614 
615     virtual void createTexture(GLuint texture);
616 
617 private:
618     int m_invalidLevelNdx;
619     IVec2 m_invalidLevelSize;
620     tcu::CubeFace m_invalidCubeFace;
621     IVec2 m_size;
622 };
623 
IncompleteCubeSizeCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,IVec2 size,IVec2 invalidLevelSize,int invalidLevelNdx)624 IncompleteCubeSizeCase::IncompleteCubeSizeCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx,
625                                                const char *name, const char *description, IVec2 size,
626                                                IVec2 invalidLevelSize, int invalidLevelNdx)
627     : TexCubeCompletenessCase(testCtx, renderCtx, name, description)
628     , m_invalidLevelNdx(invalidLevelNdx)
629     , m_invalidLevelSize(invalidLevelSize)
630     , m_invalidCubeFace(tcu::CUBEFACE_LAST)
631     , m_size(size)
632 {
633 }
634 
IncompleteCubeSizeCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,IVec2 size,IVec2 invalidLevelSize,int invalidLevelNdx,tcu::CubeFace invalidCubeFace)635 IncompleteCubeSizeCase::IncompleteCubeSizeCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx,
636                                                const char *name, const char *description, IVec2 size,
637                                                IVec2 invalidLevelSize, int invalidLevelNdx,
638                                                tcu::CubeFace invalidCubeFace)
639     : TexCubeCompletenessCase(testCtx, renderCtx, name, description)
640     , m_invalidLevelNdx(invalidLevelNdx)
641     , m_invalidLevelSize(invalidLevelSize)
642     , m_invalidCubeFace(invalidCubeFace)
643     , m_size(size)
644 {
645 }
646 
createTexture(GLuint texture)647 void IncompleteCubeSizeCase::createTexture(GLuint texture)
648 {
649     tcu::TextureFormat fmt = glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
650     tcu::TextureLevel levelData(fmt);
651 
652     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
653     glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
654 
655     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT);
656     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT);
657     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
658     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
659 
660     int numLevels = 1 + de::max(deLog2Floor32(m_size.x()), deLog2Floor32(m_size.y()));
661 
662     for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
663     {
664         levelData.setSize(m_size.x(), m_size.y());
665         clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
666 
667         for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(s_cubeTargets); targetNdx++)
668         {
669             int levelW = de::max(1, m_size.x() >> levelNdx);
670             int levelH = de::max(1, m_size.y() >> levelNdx);
671             if (levelNdx == m_invalidLevelNdx &&
672                 (m_invalidCubeFace == tcu::CUBEFACE_LAST || m_invalidCubeFace == targetNdx))
673             {
674                 levelW = m_invalidLevelSize.x();
675                 levelH = m_invalidLevelSize.y();
676             }
677             glTexImage2D(s_cubeTargets[targetNdx], levelNdx, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE,
678                          levelData.getAccess().getDataPtr());
679         }
680     }
681 
682     GLU_CHECK_MSG("Set texturing state");
683 }
684 
685 class IncompleteCubeFormatCase : public TexCubeCompletenessCase
686 {
687 public:
688     IncompleteCubeFormatCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const char *name,
689                              const char *description, IVec2 size, uint32_t format, uint32_t invalidFormat);
690     IncompleteCubeFormatCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const char *name,
691                              const char *description, IVec2 size, uint32_t format, uint32_t invalidFormat,
692                              tcu::CubeFace invalidCubeFace);
~IncompleteCubeFormatCase(void)693     ~IncompleteCubeFormatCase(void)
694     {
695     }
696 
697     virtual void createTexture(GLuint texture);
698 
699 private:
700     uint32_t m_format;
701     uint32_t m_invalidFormat;
702     tcu::CubeFace m_invalidCubeFace;
703     IVec2 m_size;
704 };
705 
IncompleteCubeFormatCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,IVec2 size,uint32_t format,uint32_t invalidFormat)706 IncompleteCubeFormatCase::IncompleteCubeFormatCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx,
707                                                    const char *name, const char *description, IVec2 size,
708                                                    uint32_t format, uint32_t invalidFormat)
709     : TexCubeCompletenessCase(testCtx, renderCtx, name, description)
710     , m_format(format)
711     , m_invalidFormat(invalidFormat)
712     , m_invalidCubeFace(tcu::CUBEFACE_LAST)
713     , m_size(size)
714 {
715 }
716 
IncompleteCubeFormatCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,IVec2 size,uint32_t format,uint32_t invalidFormat,tcu::CubeFace invalidCubeFace)717 IncompleteCubeFormatCase::IncompleteCubeFormatCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx,
718                                                    const char *name, const char *description, IVec2 size,
719                                                    uint32_t format, uint32_t invalidFormat,
720                                                    tcu::CubeFace invalidCubeFace)
721     : TexCubeCompletenessCase(testCtx, renderCtx, name, description)
722     , m_format(format)
723     , m_invalidFormat(invalidFormat)
724     , m_invalidCubeFace(invalidCubeFace)
725     , m_size(size)
726 {
727 }
728 
createTexture(GLuint texture)729 void IncompleteCubeFormatCase::createTexture(GLuint texture)
730 {
731     tcu::TextureFormat fmt = glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
732     tcu::TextureLevel levelData(fmt);
733 
734     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
735     glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
736 
737     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT);
738     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT);
739     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
740     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
741 
742     int numLevels = 1 + de::max(deLog2Floor32(m_size.x()), deLog2Floor32(m_size.y()));
743 
744     for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
745     {
746         levelData.setSize(m_size.x(), m_size.y());
747         clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
748 
749         int levelW = de::max(1, m_size.x() >> levelNdx);
750         int levelH = de::max(1, m_size.y() >> levelNdx);
751 
752         for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(s_cubeTargets); targetNdx++)
753         {
754             uint32_t format = m_format;
755             if (levelNdx == 0 && (m_invalidCubeFace == tcu::CUBEFACE_LAST || m_invalidCubeFace == targetNdx))
756                 format = m_invalidFormat;
757 
758             glTexImage2D(s_cubeTargets[targetNdx], levelNdx, format, levelW, levelH, 0, format, GL_UNSIGNED_BYTE,
759                          levelData.getAccess().getDataPtr());
760         }
761     }
762 
763     GLU_CHECK_MSG("Set texturing state");
764 }
765 
766 class IncompleteCubeMissingLevelCase : public TexCubeCompletenessCase
767 {
768 public:
769     IncompleteCubeMissingLevelCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const char *name,
770                                    const char *description, IVec2 size, int invalidLevelNdx);
771     IncompleteCubeMissingLevelCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const char *name,
772                                    const char *description, IVec2 size, int invalidLevelNdx,
773                                    tcu::CubeFace invalidCubeFace);
~IncompleteCubeMissingLevelCase(void)774     ~IncompleteCubeMissingLevelCase(void)
775     {
776     }
777 
778     virtual void createTexture(GLuint texture);
779 
780 private:
781     int m_invalidLevelNdx;
782     tcu::CubeFace m_invalidCubeFace;
783     IVec2 m_size;
784 };
785 
IncompleteCubeMissingLevelCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,IVec2 size,int invalidLevelNdx)786 IncompleteCubeMissingLevelCase::IncompleteCubeMissingLevelCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx,
787                                                                const char *name, const char *description, IVec2 size,
788                                                                int invalidLevelNdx)
789     : TexCubeCompletenessCase(testCtx, renderCtx, name, description)
790     , m_invalidLevelNdx(invalidLevelNdx)
791     , m_invalidCubeFace(tcu::CUBEFACE_LAST)
792     , m_size(size)
793 {
794 }
795 
IncompleteCubeMissingLevelCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,IVec2 size,int invalidLevelNdx,tcu::CubeFace invalidCubeFace)796 IncompleteCubeMissingLevelCase::IncompleteCubeMissingLevelCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx,
797                                                                const char *name, const char *description, IVec2 size,
798                                                                int invalidLevelNdx, tcu::CubeFace invalidCubeFace)
799     : TexCubeCompletenessCase(testCtx, renderCtx, name, description)
800     , m_invalidLevelNdx(invalidLevelNdx)
801     , m_invalidCubeFace(invalidCubeFace)
802     , m_size(size)
803 {
804 }
805 
createTexture(GLuint texture)806 void IncompleteCubeMissingLevelCase::createTexture(GLuint texture)
807 {
808     tcu::TextureFormat fmt = glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
809     tcu::TextureLevel levelData(fmt);
810 
811     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
812     glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
813 
814     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT);
815     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT);
816     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
817     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
818 
819     int numLevels = 1 + de::max(deLog2Floor32(m_size.x()), deLog2Floor32(m_size.y()));
820 
821     for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
822     {
823         levelData.setSize(m_size.x(), m_size.y());
824         clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
825 
826         int levelW = (levelNdx == m_invalidLevelNdx) ? m_size.x() : de::max(1, m_size.x() >> levelNdx);
827         int levelH = (levelNdx == m_invalidLevelNdx) ? m_size.y() : de::max(1, m_size.y() >> levelNdx);
828 
829         if (levelNdx != m_invalidLevelNdx || m_invalidCubeFace != tcu::CUBEFACE_LAST)
830         {
831             for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(s_cubeTargets); targetNdx++)
832             {
833                 // If single cubeface is specified then skip only that one.
834                 if (m_invalidCubeFace != targetNdx)
835                     glTexImage2D(s_cubeTargets[targetNdx], levelNdx, GL_RGBA, levelW, levelH, 0, GL_RGBA,
836                                  GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
837             }
838         }
839     }
840 
841     GLU_CHECK_MSG("Set texturing state");
842 }
843 
844 class IncompleteCubeWrapModeCase : public TexCubeCompletenessCase
845 {
846 public:
847     IncompleteCubeWrapModeCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const char *name,
848                                const char *description, IVec2 size, uint32_t wrapT, uint32_t wrapS,
849                                const glu::ContextInfo &ctxInfo);
~IncompleteCubeWrapModeCase(void)850     ~IncompleteCubeWrapModeCase(void)
851     {
852     }
853 
854     virtual void createTexture(GLuint texture);
855 
856 private:
857     uint32_t m_wrapT;
858     uint32_t m_wrapS;
859     const glu::ContextInfo &m_ctxInfo;
860     IVec2 m_size;
861 };
862 
IncompleteCubeWrapModeCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,IVec2 size,uint32_t wrapT,uint32_t wrapS,const glu::ContextInfo & ctxInfo)863 IncompleteCubeWrapModeCase::IncompleteCubeWrapModeCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx,
864                                                        const char *name, const char *description, IVec2 size,
865                                                        uint32_t wrapT, uint32_t wrapS, const glu::ContextInfo &ctxInfo)
866     : TexCubeCompletenessCase(testCtx, renderCtx, name, description)
867     , m_wrapT(wrapT)
868     , m_wrapS(wrapS)
869     , m_ctxInfo(ctxInfo)
870     , m_size(size)
871 {
872 }
873 
createTexture(GLuint texture)874 void IncompleteCubeWrapModeCase::createTexture(GLuint texture)
875 {
876     TestLog &log           = m_testCtx.getLog();
877     tcu::TextureFormat fmt = glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
878     tcu::TextureLevel levelData(fmt);
879 
880     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
881     glBindTexture(GL_TEXTURE_2D, texture);
882 
883     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, m_wrapS);
884     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, m_wrapT);
885     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
886     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
887 
888     levelData.setSize(m_size.x(), m_size.y());
889     clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
890 
891     for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(s_cubeTargets); targetNdx++)
892         glTexImage2D(s_cubeTargets[targetNdx], 0, GL_RGBA, m_size.x(), m_size.y(), 0, GL_RGBA, GL_UNSIGNED_BYTE,
893                      levelData.getAccess().getDataPtr());
894 
895     GLU_CHECK_MSG("Set texturing state");
896 
897     const char *extension = "GL_OES_texture_npot";
898     if (isExtensionSupported(m_ctxInfo, extension))
899     {
900         log << TestLog::Message << extension << " supported, assuming completeness test to pass."
901             << TestLog::EndMessage;
902         m_compareColor = RGBA(0, 0, 255, 255);
903     }
904 }
905 
906 class CompleteCubeExtraLevelCase : public TexCubeCompletenessCase
907 {
908 public:
909     CompleteCubeExtraLevelCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const char *name,
910                                const char *description, IVec2 size);
~CompleteCubeExtraLevelCase(void)911     ~CompleteCubeExtraLevelCase(void)
912     {
913     }
914 
915     virtual void createTexture(GLuint texture);
916 
917 private:
918     IVec2 m_size;
919 };
920 
CompleteCubeExtraLevelCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,IVec2 size)921 CompleteCubeExtraLevelCase::CompleteCubeExtraLevelCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx,
922                                                        const char *name, const char *description, IVec2 size)
923     : TexCubeCompletenessCase(testCtx, renderCtx, name, description)
924     , m_size(size)
925 {
926 }
927 
createTexture(GLuint texture)928 void CompleteCubeExtraLevelCase::createTexture(GLuint texture)
929 {
930     tcu::TextureFormat fmt = glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
931     tcu::TextureLevel levelData(fmt);
932 
933     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
934     glBindTexture(GL_TEXTURE_2D, texture);
935 
936     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
937     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
938     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
939     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
940 
941     int numLevels = 1 + de::max(deLog2Floor32(m_size.x()), deLog2Floor32(m_size.y()));
942 
943     levelData.setSize(m_size.x(), m_size.y());
944     clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
945 
946     for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
947     {
948         int levelW = de::max(1, m_size.x() >> levelNdx);
949         int levelH = de::max(1, m_size.y() >> levelNdx);
950 
951         for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(s_cubeTargets); targetNdx++)
952             glTexImage2D(s_cubeTargets[targetNdx], levelNdx, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE,
953                          levelData.getAccess().getDataPtr());
954     }
955 
956     // Specify extra level.
957     for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(s_cubeTargets); targetNdx++)
958         glTexImage2D(s_cubeTargets[targetNdx], numLevels + 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
959                      levelData.getAccess().getDataPtr());
960 
961     m_compareColor = RGBA(0, 0, 255, 255);
962 
963     GLU_CHECK_MSG("Set texturing state");
964 }
965 
966 class IncompleteCubeEmptyObjectCase : public TexCubeCompletenessCase
967 {
968 public:
969     IncompleteCubeEmptyObjectCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const char *name,
970                                   const char *description, IVec2 size);
~IncompleteCubeEmptyObjectCase(void)971     ~IncompleteCubeEmptyObjectCase(void)
972     {
973     }
974 
975     virtual void createTexture(GLuint texture);
976 
977 private:
978     IVec2 m_size;
979 };
980 
IncompleteCubeEmptyObjectCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,IVec2 size)981 IncompleteCubeEmptyObjectCase::IncompleteCubeEmptyObjectCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx,
982                                                              const char *name, const char *description, IVec2 size)
983     : TexCubeCompletenessCase(testCtx, renderCtx, name, description)
984     , m_size(size)
985 {
986 }
987 
createTexture(GLuint texture)988 void IncompleteCubeEmptyObjectCase::createTexture(GLuint texture)
989 {
990     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
991     glBindTexture(GL_TEXTURE_2D, texture);
992 
993     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
994     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
995     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
996     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
997 
998     GLU_CHECK_MSG("Set texturing state");
999 }
1000 
1001 // Texture completeness group.
1002 
TextureCompletenessTests(Context & context)1003 TextureCompletenessTests::TextureCompletenessTests(Context &context)
1004     : TestCaseGroup(context, "completeness", "Completeness tests")
1005 {
1006 }
1007 
init(void)1008 void TextureCompletenessTests::init(void)
1009 {
1010     tcu::TestCaseGroup *tex2d = new tcu::TestCaseGroup(m_testCtx, "2d", "2D completeness");
1011     addChild(tex2d);
1012     tcu::TestCaseGroup *cube = new tcu::TestCaseGroup(m_testCtx, "cube", "Cubemap completeness");
1013     addChild(cube);
1014 
1015     // Texture 2D size.
1016     tex2d->addChild(new Incomplete2DSizeCase(m_testCtx, m_context.getRenderContext(), "npot_size", "", IVec2(255, 255),
1017                                              IVec2(255, 255), 0, m_context.getContextInfo()));
1018     tex2d->addChild(new Incomplete2DSizeCase(m_testCtx, m_context.getRenderContext(), "npot_size_level_0", "",
1019                                              IVec2(256, 256), IVec2(255, 255), 0, m_context.getContextInfo()));
1020     tex2d->addChild(new Incomplete2DSizeCase(m_testCtx, m_context.getRenderContext(), "npot_size_level_1", "",
1021                                              IVec2(256, 256), IVec2(127, 127), 1, m_context.getContextInfo()));
1022     tex2d->addChild(new Incomplete2DSizeCase(m_testCtx, m_context.getRenderContext(), "not_positive_level_0", "",
1023                                              IVec2(256, 256), IVec2(0, 0), 0, m_context.getContextInfo()));
1024     // Texture 2D format.
1025     tex2d->addChild(new Incomplete2DFormatCase(m_testCtx, m_context.getRenderContext(), "format_mismatch_rgb_rgba", "",
1026                                                IVec2(128, 128), GL_RGB, GL_RGBA, 1));
1027     tex2d->addChild(new Incomplete2DFormatCase(m_testCtx, m_context.getRenderContext(), "format_mismatch_rgba_rgb", "",
1028                                                IVec2(128, 128), GL_RGBA, GL_RGB, 1));
1029     tex2d->addChild(new Incomplete2DFormatCase(m_testCtx, m_context.getRenderContext(),
1030                                                "format_mismatch_luminance_luminance_alpha", "", IVec2(128, 128),
1031                                                GL_LUMINANCE, GL_LUMINANCE_ALPHA, 1));
1032     tex2d->addChild(new Incomplete2DFormatCase(m_testCtx, m_context.getRenderContext(),
1033                                                "format_mismatch_luminance_alpha_luminance", "", IVec2(128, 128),
1034                                                GL_LUMINANCE_ALPHA, GL_LUMINANCE, 1));
1035     // Texture 2D missing level.
1036     tex2d->addChild(new Incomplete2DMissingLevelCase(m_testCtx, m_context.getRenderContext(), "missing_level_1", "",
1037                                                      IVec2(128, 128), 1));
1038     tex2d->addChild(new Incomplete2DMissingLevelCase(m_testCtx, m_context.getRenderContext(), "missing_level_3", "",
1039                                                      IVec2(128, 128), 3));
1040     tex2d->addChild(new Incomplete2DMissingLevelCase(m_testCtx, m_context.getRenderContext(), "last_level_missing", "",
1041                                                      IVec2(128, 64), de::max(deLog2Floor32(128), deLog2Floor32(64))));
1042     // Texture 2D wrap modes.
1043     tex2d->addChild(new Incomplete2DWrapModeCase(m_testCtx, m_context.getRenderContext(), "npot_t_repeat", "",
1044                                                  IVec2(127, 127), GL_CLAMP_TO_EDGE, GL_REPEAT,
1045                                                  m_context.getContextInfo()));
1046     tex2d->addChild(new Incomplete2DWrapModeCase(m_testCtx, m_context.getRenderContext(), "npot_s_repeat", "",
1047                                                  IVec2(127, 127), GL_REPEAT, GL_CLAMP_TO_EDGE,
1048                                                  m_context.getContextInfo()));
1049     tex2d->addChild(new Incomplete2DWrapModeCase(m_testCtx, m_context.getRenderContext(), "npot_all_repeat", "",
1050                                                  IVec2(127, 127), GL_REPEAT, GL_REPEAT, m_context.getContextInfo()));
1051     tex2d->addChild(new Incomplete2DWrapModeCase(m_testCtx, m_context.getRenderContext(), "npot_mirrored_repeat", "",
1052                                                  IVec2(127, 127), GL_MIRRORED_REPEAT, GL_MIRRORED_REPEAT,
1053                                                  m_context.getContextInfo()));
1054     tex2d->addChild(new Incomplete2DWrapModeCase(m_testCtx, m_context.getRenderContext(), "repeat_width_npot", "",
1055                                                  IVec2(127, 128), GL_REPEAT, GL_REPEAT, m_context.getContextInfo()));
1056     tex2d->addChild(new Incomplete2DWrapModeCase(m_testCtx, m_context.getRenderContext(), "repeat_height_npot", "",
1057                                                  IVec2(128, 127), GL_REPEAT, GL_REPEAT, m_context.getContextInfo()));
1058     // Texture 2D extra level.
1059     tex2d->addChild(
1060         new Complete2DExtraLevelCase(m_testCtx, m_context.getRenderContext(), "extra_level", "", IVec2(64, 64)));
1061     // Texture 2D empty object.
1062     tex2d->addChild(
1063         new Incomplete2DEmptyObjectCase(m_testCtx, m_context.getRenderContext(), "empty_object", "", IVec2(64, 64)));
1064 
1065     // Cube size.
1066     cube->addChild(new IncompleteCubeSizeCase(m_testCtx, m_context.getRenderContext(), "npot_size_level_0", "",
1067                                               IVec2(64, 64), IVec2(63, 63), 0));
1068     cube->addChild(new IncompleteCubeSizeCase(m_testCtx, m_context.getRenderContext(), "npot_size_level_1", "",
1069                                               IVec2(64, 64), IVec2(31, 31), 1));
1070     cube->addChild(new IncompleteCubeSizeCase(m_testCtx, m_context.getRenderContext(), "npot_size_level_0_pos_x", "",
1071                                               IVec2(64, 64), IVec2(63, 63), 0, tcu::CUBEFACE_POSITIVE_X));
1072     cube->addChild(new IncompleteCubeSizeCase(m_testCtx, m_context.getRenderContext(), "npot_size_level_1_neg_x", "",
1073                                               IVec2(64, 64), IVec2(31, 31), 1, tcu::CUBEFACE_NEGATIVE_X));
1074     cube->addChild(new IncompleteCubeSizeCase(m_testCtx, m_context.getRenderContext(), "not_positive_level_0", "",
1075                                               IVec2(64, 64), IVec2(0, 0), 0));
1076     // Cube format.
1077     cube->addChild(new IncompleteCubeFormatCase(m_testCtx, m_context.getRenderContext(),
1078                                                 "format_mismatch_rgb_rgba_level_0", "", IVec2(64, 64), GL_RGB,
1079                                                 GL_RGBA));
1080     cube->addChild(new IncompleteCubeFormatCase(m_testCtx, m_context.getRenderContext(),
1081                                                 "format_mismatch_rgba_rgb_level_0", "", IVec2(64, 64), GL_RGBA,
1082                                                 GL_RGB));
1083     cube->addChild(new IncompleteCubeFormatCase(m_testCtx, m_context.getRenderContext(),
1084                                                 "format_mismatch_luminance_luminance_alpha_level_0", "", IVec2(64, 64),
1085                                                 GL_LUMINANCE, GL_LUMINANCE_ALPHA));
1086     cube->addChild(new IncompleteCubeFormatCase(m_testCtx, m_context.getRenderContext(),
1087                                                 "format_mismatch_luminance_alpha_luminance_level_0", "", IVec2(64, 64),
1088                                                 GL_LUMINANCE_ALPHA, GL_LUMINANCE));
1089     cube->addChild(new IncompleteCubeFormatCase(m_testCtx, m_context.getRenderContext(),
1090                                                 "format_mismatch_rgb_rgba_level_0_pos_z", "", IVec2(64, 64), GL_RGB,
1091                                                 GL_RGBA, tcu::CUBEFACE_POSITIVE_Z));
1092     cube->addChild(new IncompleteCubeFormatCase(m_testCtx, m_context.getRenderContext(),
1093                                                 "format_mismatch_rgba_rgb_level_0_neg_z", "", IVec2(64, 64), GL_RGBA,
1094                                                 GL_RGB, tcu::CUBEFACE_NEGATIVE_Z));
1095     // Cube missing level.
1096     cube->addChild(new IncompleteCubeMissingLevelCase(m_testCtx, m_context.getRenderContext(), "missing_level_1", "",
1097                                                       IVec2(64, 64), 1));
1098     cube->addChild(new IncompleteCubeMissingLevelCase(m_testCtx, m_context.getRenderContext(), "missing_level_3", "",
1099                                                       IVec2(64, 64), 3));
1100     cube->addChild(new IncompleteCubeMissingLevelCase(m_testCtx, m_context.getRenderContext(), "missing_level_1_pos_y",
1101                                                       "", IVec2(64, 64), 1, tcu::CUBEFACE_POSITIVE_Y));
1102     cube->addChild(new IncompleteCubeMissingLevelCase(m_testCtx, m_context.getRenderContext(), "missing_level_3_neg_y",
1103                                                       "", IVec2(64, 64), 3, tcu::CUBEFACE_NEGATIVE_Y));
1104     // Cube wrap modes.
1105     cube->addChild(new IncompleteCubeWrapModeCase(m_testCtx, m_context.getRenderContext(), "npot_t_repeat", "",
1106                                                   IVec2(127, 127), GL_CLAMP_TO_EDGE, GL_REPEAT,
1107                                                   m_context.getContextInfo()));
1108     cube->addChild(new IncompleteCubeWrapModeCase(m_testCtx, m_context.getRenderContext(), "npot_s_repeat", "",
1109                                                   IVec2(127, 127), GL_REPEAT, GL_CLAMP_TO_EDGE,
1110                                                   m_context.getContextInfo()));
1111     cube->addChild(new IncompleteCubeWrapModeCase(m_testCtx, m_context.getRenderContext(), "npot_all_repeat", "",
1112                                                   IVec2(127, 127), GL_REPEAT, GL_REPEAT, m_context.getContextInfo()));
1113     cube->addChild(new IncompleteCubeWrapModeCase(m_testCtx, m_context.getRenderContext(), "npot_mirrored_repeat", "",
1114                                                   IVec2(127, 127), GL_MIRRORED_REPEAT, GL_MIRRORED_REPEAT,
1115                                                   m_context.getContextInfo()));
1116     // Cube extra level.
1117     cube->addChild(
1118         new CompleteCubeExtraLevelCase(m_testCtx, m_context.getRenderContext(), "extra_level", "", IVec2(64, 64)));
1119     // Cube extra level.
1120     cube->addChild(
1121         new IncompleteCubeEmptyObjectCase(m_testCtx, m_context.getRenderContext(), "empty_object", "", IVec2(64, 64)));
1122 }
1123 
1124 } // namespace Functional
1125 } // namespace gles2
1126 } // namespace deqp
1127