• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2024 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  glcTextureStorageCompressedDataTests.cpp
27  * \brief Conformance tests for the textureStorage functionality.
28  */ /*-------------------------------------------------------------------*/
29 
30 #include "deMath.h"
31 
32 #include "glcTextureStorageTests.hpp"
33 #include "gluContextInfo.hpp"
34 #include "gluDefs.hpp"
35 #include "gluStrUtil.hpp"
36 #include "glwEnums.hpp"
37 #include "glwFunctions.hpp"
38 #include "tcuRenderTarget.hpp"
39 #include "tcuTestLog.hpp"
40 
41 #include <cmath>
42 
43 using namespace glw;
44 using namespace glu;
45 
46 namespace glcts
47 {
48 /** Constructor.
49  *
50  *  @param context     Rendering context
51  */
TextureStorageCompressedDataTestCase(deqp::Context & context)52 TextureStorageCompressedDataTestCase::TextureStorageCompressedDataTestCase(deqp::Context &context)
53     : TestCase(context, "compressed_data", "Verifies compressed texture data loading functionality")
54     , m_isContextES(false)
55     , m_testSupported(false)
56     , m_texture2D(0)
57     , m_textureCubeMap(0)
58     , m_texture3D(0)
59     , m_texture2DArray(0)
60     , m_textureSize2D(512)
61     , m_textureSize3D(64)
62     , m_maxTexturePixels(0)
63 {
64 }
65 
66 /** Stub deinit method. */
deinit()67 void TextureStorageCompressedDataTestCase::deinit()
68 {
69     /* Left blank intentionally */
70 }
71 
72 /** Stub init method */
init()73 void TextureStorageCompressedDataTestCase::init()
74 {
75     const glu::RenderContext &renderContext = m_context.getRenderContext();
76     m_isContextES                           = glu::isContextTypeES(renderContext.getType());
77 
78     m_textureLevels2D = (int)std::floor(std::log2f((float)m_textureSize2D)) + 1;
79     m_textureLevels3D = (int)std::floor(std::log2f((float)m_textureSize3D)) + 1;
80 
81     /* create largest used 2D/3D texture */
82     m_maxTexturePixels = std::max(4 * m_textureSize2D * m_textureSize2D,
83                                   4 * m_textureSize3D * m_textureSize3D * m_textureSize3D); /* RGBA, thus 4x */
84     m_texData = std::vector<GLfloat>(4 * m_maxTexturePixels, 0.f); /* f32 or (u)i32, which are 4 bytes per pixel */
85 
86     auto contextType = m_context.getRenderContext().getType();
87     if (!m_isContextES)
88     {
89         m_testSupported = (m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_storage") &&
90                            (glu::contextSupports(contextType, glu::ApiType::core(3, 0)) ||
91                             glu::contextSupports(contextType, glu::ApiType::core(3, 1)))) ||
92                           glu::contextSupports(contextType, glu::ApiType::core(4, 2));
93     }
94     else
95         m_testSupported = true;
96 }
97 
iterate_gl()98 bool TextureStorageCompressedDataTestCase::iterate_gl()
99 {
100     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
101     bool ret                 = true;
102     int curTextureSize       = 0;
103 
104     struct formats
105     {
106         GLenum intFormat;
107         GLenum format;
108         GLenum type;
109         GLboolean allowedWithTex3D;
110     } formats[] = {{GL_COMPRESSED_RG_RGTC2, GL_RG, GL_UNSIGNED_BYTE, GL_FALSE},
111                    {GL_COMPRESSED_SIGNED_RG_RGTC2, GL_RG, GL_UNSIGNED_BYTE, GL_FALSE},
112                    {GL_R16_SNORM, GL_RED, GL_UNSIGNED_BYTE, GL_TRUE},
113                    {GL_R8_SNORM, GL_RED, GL_UNSIGNED_BYTE, GL_TRUE},
114                    {GL_COMPRESSED_RED_RGTC1, GL_RED, GL_UNSIGNED_BYTE, GL_FALSE},
115                    {GL_COMPRESSED_SIGNED_RED_RGTC1, GL_RED, GL_UNSIGNED_BYTE, GL_FALSE}};
116 
117     GLenum format[] = {GL_RED, GL_RG, GL_RGB, GL_RGBA};
118 
119     GLenum cubeMapTarget[] = {GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
120                               GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
121                               GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z};
122 
123     /* test with TEXTURE_2D target */
124     m_testCtx.getLog() << tcu::TestLog::Message
125                        << "testing TEXTURE_2D compressed texture loading with each internal format\n"
126                        << tcu::TestLog::EndMessage;
127 
128     for (size_t i = 0; i < sizeof(formats) / sizeof(formats[0]); i++)
129     {
130         gl.genTextures(1, &m_texture2D);
131         GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
132 
133         gl.bindTexture(GL_TEXTURE_2D, m_texture2D);
134         GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
135 
136         gl.texStorage2D(GL_TEXTURE_2D, m_textureLevels2D, formats[i].intFormat, m_textureSize2D, m_textureSize2D);
137         GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage2D");
138 
139         /* test each format and level*/
140         for (size_t j = 0; j < sizeof(format) / sizeof(format[0]); j++)
141         {
142             curTextureSize = m_textureSize2D;
143 
144             for (size_t k = 0; k < (size_t)m_textureLevels2D; k++)
145             {
146                 gl.texSubImage2D(GL_TEXTURE_2D, k, 0, 0, curTextureSize, curTextureSize, format[j], formats[i].type,
147                                  m_texData.data());
148                 GLU_EXPECT_NO_ERROR(gl.getError(), "texSubImage2D");
149 
150                 curTextureSize /= 2;
151             }
152         }
153         gl.deleteTextures(1, &m_texture2D);
154         GLU_EXPECT_NO_ERROR(gl.getError(), "deleteTextures");
155     }
156 
157     /* test with TEXTURE_CUBE_MAP target */
158     m_testCtx.getLog() << tcu::TestLog::Message
159                        << "testing TEXTURE_CUBE_MAP compressed texture loading with each internal format\n"
160                        << tcu::TestLog::EndMessage;
161 
162     for (size_t i = 0; i < sizeof(formats) / sizeof(formats[0]); i++)
163     {
164         gl.genTextures(1, &m_textureCubeMap);
165         GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
166 
167         gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_textureCubeMap);
168         GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
169 
170         gl.texStorage2D(GL_TEXTURE_CUBE_MAP, m_textureLevels2D, formats[i].intFormat, m_textureSize2D, m_textureSize2D);
171         GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage2D");
172 
173         /* test each format, cubemap face and level */
174         for (size_t j = 0; j < sizeof(format) / sizeof(format[0]); j++)
175         {
176             for (size_t k = 0; k < 6; k++)
177             {
178                 curTextureSize = m_textureSize2D;
179 
180                 for (size_t l = 0; l < (size_t)m_textureLevels2D; l++)
181                 {
182                     gl.texSubImage2D(cubeMapTarget[k], l, 0, 0, curTextureSize, curTextureSize, format[j],
183                                      formats[i].type, m_texData.data());
184                     GLU_EXPECT_NO_ERROR(gl.getError(), "texSubImage2D");
185 
186                     curTextureSize /= 2;
187                 }
188             }
189         }
190         gl.deleteTextures(1, &m_textureCubeMap);
191         GLU_EXPECT_NO_ERROR(gl.getError(), "deleteTextures");
192     }
193 
194     /* test with TEXTURE_3D target */
195     m_testCtx.getLog() << tcu::TestLog::Message
196                        << "testing TEXTURE_3D compressed texture loading with each internal format\n"
197                        << tcu::TestLog::EndMessage;
198 
199     for (size_t i = 0; i < sizeof(formats) / sizeof(formats[0]); i++)
200     {
201         if (formats[i].format != GL_DEPTH_COMPONENT && formats[i].format != GL_DEPTH_STENCIL)
202         {
203             gl.genTextures(1, &m_texture3D);
204             GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
205 
206             gl.bindTexture(GL_TEXTURE_3D, m_texture3D);
207             GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
208 
209             gl.texStorage3D(GL_TEXTURE_3D, m_textureLevels3D, formats[i].intFormat, m_textureSize3D, m_textureSize3D,
210                             m_textureSize3D);
211 
212             if (formats[i].allowedWithTex3D)
213             {
214                 GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage3D");
215 
216                 /* test each format and level */
217                 for (size_t j = 0; j < sizeof(format) / sizeof(format[0]); j++)
218                 {
219                     curTextureSize = m_textureSize3D;
220 
221                     for (size_t k = 0; k < (size_t)m_textureLevels3D; k++)
222                     {
223                         gl.texSubImage3D(GL_TEXTURE_3D, k, 0, 0, 0, curTextureSize, curTextureSize, curTextureSize,
224                                          format[j], formats[i].type, m_texData.data());
225                         GLU_EXPECT_NO_ERROR(gl.getError(), "texSubImage3D");
226 
227                         curTextureSize /= 2;
228                     }
229                 }
230             }
231             else
232             {
233                 /* Using glTexStorage3D with a TEXTURE_3D target and a compressed internal
234                    format should generate INVALID_OPERATION. See Khronos bug 11239. */
235                 auto err = gl.getError();
236                 if (err != GL_INVALID_OPERATION)
237                 {
238                     m_testCtx.getLog() << tcu::TestLog::Message
239                                        << "texStorage3D failed, expected GL_INVALID_OPERATION got "
240                                        << glu::getErrorName(err) << tcu::TestLog::EndMessage;
241                     ret = false;
242                 }
243             }
244             gl.deleteTextures(1, &m_texture3D);
245             GLU_EXPECT_NO_ERROR(gl.getError(), "deleteTextures");
246         }
247     }
248 
249     /* test with TEXTURE_2D_ARRAY target */
250     m_testCtx.getLog() << tcu::TestLog::Message
251                        << "testing TEXTURE_2D_ARRAY compressed texture loading with each internal format\n"
252                        << tcu::TestLog::EndMessage;
253 
254     for (size_t i = 0; i < sizeof(formats) / sizeof(formats[0]); i++)
255     {
256         gl.genTextures(1, &m_texture2DArray);
257         GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
258 
259         gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_texture2DArray);
260         GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
261 
262         gl.texStorage3D(GL_TEXTURE_2D_ARRAY, m_textureLevels3D, formats[i].intFormat, m_textureSize3D, m_textureSize3D,
263                         m_textureSize3D);
264         GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage3D");
265 
266         /* test each format and level */
267         for (size_t j = 0; j < sizeof(format) / sizeof(format[0]); j++)
268         {
269             curTextureSize = m_textureSize3D;
270 
271             for (size_t k = 0; k < (size_t)m_textureLevels3D; k++)
272             {
273                 gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, k, 0, 0, 0, curTextureSize, curTextureSize, curTextureSize,
274                                  format[j], formats[i].type, m_texData.data());
275                 GLU_EXPECT_NO_ERROR(gl.getError(), "texSubImage3D");
276 
277                 curTextureSize /= 2;
278             }
279         }
280         gl.deleteTextures(1, &m_texture2DArray);
281         GLU_EXPECT_NO_ERROR(gl.getError(), "deleteTextures");
282     }
283 
284     return ret;
285 }
286 
iterate_gles()287 bool TextureStorageCompressedDataTestCase::iterate_gles()
288 {
289     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
290     bool ret                 = true;
291 
292     int curTextureSize = 0, curDataSize = 0;
293 
294     struct formats
295     {
296         GLenum intFormat;
297         int bytesPerBlock;
298     } formats[] = {{GL_COMPRESSED_R11_EAC, 8},
299                    {GL_COMPRESSED_SIGNED_R11_EAC, 8},
300                    {GL_COMPRESSED_RG11_EAC, 16},
301                    {GL_COMPRESSED_SIGNED_RG11_EAC, 16},
302                    {GL_COMPRESSED_RGB8_ETC2, 8},
303                    {GL_COMPRESSED_SRGB8_ETC2, 8},
304                    {GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, 8},
305                    {GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, 8},
306                    {GL_COMPRESSED_RGBA8_ETC2_EAC, 16},
307                    {GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, 16}};
308 
309     GLenum cubeMapTarget[] = {GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
310                               GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
311                               GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z};
312 
313     /* test with TEXTURE_2D target */
314     m_testCtx.getLog() << tcu::TestLog::Message
315                        << "testing TEXTURE_2D compressed texture loading with each internal format\n"
316                        << tcu::TestLog::EndMessage;
317 
318     for (size_t i = 0; i < sizeof(formats) / sizeof(formats[0]); i++)
319     {
320         gl.genTextures(1, &m_texture2D);
321         GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
322 
323         gl.bindTexture(GL_TEXTURE_2D, m_texture2D);
324         GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
325 
326         gl.texStorage2D(GL_TEXTURE_2D, m_textureLevels2D, formats[i].intFormat, m_textureSize2D, m_textureSize2D);
327         GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage2D");
328 
329         curTextureSize = m_textureSize2D;
330 
331         for (size_t k = 0; k < (size_t)m_textureLevels2D; k++)
332         {
333             curDataSize = std::max(curTextureSize / 4, 1) * std::max(curTextureSize / 4, 1);
334             curDataSize *= formats[i].bytesPerBlock;
335 
336             gl.compressedTexSubImage2D(GL_TEXTURE_2D, k, 0, 0, curTextureSize, curTextureSize, formats[i].intFormat,
337                                        curDataSize, m_texData.data());
338             GLU_EXPECT_NO_ERROR(gl.getError(), "texSubImage3D");
339 
340             curTextureSize /= 2;
341         }
342 
343         gl.deleteTextures(1, &m_texture2D);
344         GLU_EXPECT_NO_ERROR(gl.getError(), "deleteTextures");
345     }
346 
347     /* test with TEXTURE_CUBE_MAP target */
348     m_testCtx.getLog() << tcu::TestLog::Message
349                        << "testing TEXTURE_CUBE_MAP compressed texture loading with each internal format\n"
350                        << tcu::TestLog::EndMessage;
351 
352     for (size_t i = 0; i < sizeof(formats) / sizeof(formats[0]); i++)
353     {
354         gl.genTextures(1, &m_textureCubeMap);
355         GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
356 
357         gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_textureCubeMap);
358         GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
359 
360         gl.texStorage2D(GL_TEXTURE_CUBE_MAP, m_textureLevels2D, formats[i].intFormat, m_textureSize2D, m_textureSize2D);
361         GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage2D");
362 
363         /* test each cubemap face and level */
364         for (size_t k = 0; k < 6; k++)
365         {
366             curTextureSize = m_textureSize2D;
367 
368             for (size_t l = 0; l < (size_t)m_textureLevels2D; l++)
369             {
370                 curDataSize = std::max(curTextureSize / 4, 1) * std::max(curTextureSize / 4, 1);
371                 curDataSize *= formats[i].bytesPerBlock;
372 
373                 gl.compressedTexSubImage2D(cubeMapTarget[k], l, 0, 0, curTextureSize, curTextureSize,
374                                            formats[i].intFormat, curDataSize, m_texData.data());
375                 GLU_EXPECT_NO_ERROR(gl.getError(), "texSubImage2D");
376 
377                 curTextureSize /= 2;
378             }
379         }
380 
381         gl.deleteTextures(1, &m_textureCubeMap);
382         GLU_EXPECT_NO_ERROR(gl.getError(), "deleteTextures");
383     }
384 
385     /* test with TEXTURE_2D_ARRAY target */
386     m_testCtx.getLog() << tcu::TestLog::Message
387                        << "testing TEXTURE_2D_ARRAY compressed texture loading with each internal format\n"
388                        << tcu::TestLog::EndMessage;
389 
390     for (size_t i = 0; i < sizeof(formats) / sizeof(formats[0]); i++)
391     {
392         gl.genTextures(1, &m_texture2DArray);
393         GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
394 
395         gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_texture2DArray);
396         GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
397 
398         gl.texStorage3D(GL_TEXTURE_2D_ARRAY, m_textureLevels3D, formats[i].intFormat, m_textureSize3D, m_textureSize3D,
399                         m_textureSize3D);
400         GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage3D");
401 
402         /* test each level */
403         curTextureSize = m_textureSize3D;
404 
405         for (size_t k = 0; k < (size_t)m_textureLevels3D; k++)
406         {
407             curDataSize = std::max(curTextureSize / 4, 1) * std::max(curTextureSize / 4, 1) * curTextureSize;
408             curDataSize *= formats[i].bytesPerBlock;
409 
410             gl.compressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, k, 0, 0, 0, curTextureSize, curTextureSize, curTextureSize,
411                                        formats[i].intFormat, curDataSize, m_texData.data());
412             GLU_EXPECT_NO_ERROR(gl.getError(), "compressedTexSubImage3D");
413 
414             curTextureSize /= 2;
415         }
416         gl.deleteTextures(1, &m_texture2DArray);
417         GLU_EXPECT_NO_ERROR(gl.getError(), "deleteTextures");
418     }
419 
420     return ret;
421 }
422 
423 /** Executes test iteration.
424  *
425  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
426  */
iterate()427 tcu::TestNode::IterateResult TextureStorageCompressedDataTestCase::iterate()
428 {
429     bool ret = true;
430 
431     if (!m_testSupported)
432     {
433         m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported");
434         /* This test should only be executed if we're running a GL4.2 context or
435          * GL_EXT_texture_storage extension is supported */
436         throw tcu::NotSupportedError("TextureStorageCompressedDataTestCase is not supported");
437     }
438 
439     if (m_isContextES)
440     {
441         ret = iterate_gles();
442     }
443     else
444     {
445         ret = iterate_gl();
446     }
447 
448     if (ret)
449         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
450     else
451         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
452     return STOP;
453 }
454 
455 /** Constructor.
456  *
457  *  @param context Rendering context.
458  */
TextureStorageTests(deqp::Context & context)459 TextureStorageTests::TextureStorageTests(deqp::Context &context)
460     : TestCaseGroup(context, "texture_storage", "Verify conformance of texture storage functionality")
461 {
462 }
463 
464 /** Initializes the test group contents. */
init()465 void TextureStorageTests::init()
466 {
467     addChild(new TextureStorageCompressedDataTestCase(m_context));
468 }
469 
470 } // namespace glcts
471