xref: /aosp_15_r20/external/deqp/external/openglcts/modules/common/glcPixelStorageModesTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2020 The Khronos Group Inc.
6  * Copyright (c) 2020 Intel Corporation
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */ /*!
21 * \file  glcPixelStorageModesTests.cpp
22 * \brief Conformance tests for usage of pixel storage modes.
23 */ /*-------------------------------------------------------------------*/
24 
25 #include "stdlib.h"
26 #include "tcuRenderTarget.hpp"
27 #include "tcuSurface.hpp"
28 #include "tcuTextureUtil.hpp"
29 #include "tcuTestCase.hpp"
30 #include "tcuTestLog.hpp"
31 #include "tcuDefs.hpp"
32 #include "tcuFloat.hpp"
33 #include "tcuStringTemplate.hpp"
34 #include "gluRenderContext.hpp"
35 #include "gluShaderProgram.hpp"
36 #include "gluShaderUtil.hpp"
37 #include "gluContextInfo.hpp"
38 #include "gluObjectWrapper.hpp"
39 #include "gluCallLogWrapper.hpp"
40 #include "gluPixelTransfer.hpp"
41 #include "gluTexture.hpp"
42 #include "gluTextureUtil.hpp"
43 #include "gluDrawUtil.hpp"
44 #include "gluDefs.hpp"
45 #include "sglrGLContext.hpp"
46 #include "sglrContextWrapper.hpp"
47 #include "sglrContextUtil.hpp"
48 #include "glwFunctions.hpp"
49 #include "glwEnums.hpp"
50 #include "deStringUtil.hpp"
51 #include "deUniquePtr.hpp"
52 #include "glsTextureTestUtil.hpp"
53 #include "glcPixelStorageModesTests.hpp"
54 
55 #include <algorithm>
56 
57 namespace glcts
58 {
59 
60 static const char *const vs_template_src = "${GLSL_VERSION}\n"
61                                            "in highp vec4 pos;\n"
62                                            "out highp ${TEXCOORDS_TYPE} texcoords;\n"
63                                            "${LAYER}\n"
64                                            "void main (void)\n"
65                                            "{\n"
66                                            "     texcoords = ${TEXCOORDS};\n"
67                                            "     gl_Position = pos;\n"
68                                            "}\n";
69 
70 static const char *const fs_template_src =
71     "${GLSL_VERSION}\n"
72     "precision highp float;\n"
73     "precision highp int;\n"
74     "out vec4 fragColour;\n"
75     "in ${TEXCOORDS_TYPE} texcoords;\n"
76     "uniform highp ${SAMPLER_TYPE} sampler;\n"
77     "uniform ${COL_TYPE} refcolour;\n"
78     "void main (void)\n"
79     "{\n"
80     "     ${COL_TYPE} colour = texelFetch(sampler, i${TEXCOORDS_TYPE}(texcoords), 0);\n"
81     "     if (${CONDITION})\n"
82     "         fragColour = vec4(0.0, 1.0, 0.0, 1.0);\n"
83     "     else\n"
84     "         fragColour = vec4(colour);\n"
85     "}\n";
86 
getEps(uint32_t internalFormat)87 double getEps(uint32_t internalFormat)
88 {
89     double eps = 0.0;
90     switch (internalFormat)
91     {
92     case GL_RGBA4:
93         eps = 1.0 / (double)(1 << 4);
94         break;
95     case GL_RGB565:
96     case GL_RGB5_A1:
97     case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
98         eps = 1.0 / (double)(1 << 5);
99         break;
100     case GL_R8:
101     case GL_R8_SNORM:
102     case GL_RG8:
103     case GL_RG8_SNORM:
104     case GL_RGB8:
105     case GL_SRGB8:
106     case GL_RGB8_SNORM:
107     case GL_RGBA8:
108     case GL_SRGB8_ALPHA8:
109     case GL_RGBA8_SNORM:
110         eps = 1.0 / (double)(1 << 8);
111         break;
112     case GL_RGB9_E5:
113         eps = 1.0 / (double)(1 << 9);
114         break;
115     case GL_R11F_G11F_B10F:
116     case GL_RGB10_A2:
117         eps = 1.0 / (double)(1 << 10);
118         break;
119     case GL_R16F:
120     case GL_RG16F:
121     case GL_RGB16F:
122     case GL_RGBA16F:
123     case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
124         eps = 1.0 / (double)(1 << 16);
125         break;
126     case GL_R32F:
127     case GL_RG32F:
128     case GL_RGB32F:
129     case GL_RGBA32F:
130         eps = 1.0 / (double)(1 << 31);
131         break;
132     default:
133         TCU_FAIL("Invalid internal format");
134     }
135 
136     return std::max(0.01, eps);
137 }
138 
inrange(int x,int left,int right)139 bool inrange(int x, int left, int right)
140 {
141     return (x >= left && x < right);
142 }
143 
144 class TexImageUtils
145 {
146 public:
147     TexImageUtils(uint32_t internalFormat, int cuboid_w, int cuboid_h, int cuboid_d, int subcuboid_x0, int subcuboid_y0,
148                   int subcuboid_z0, int subcuboid_w, int subcuboid_h, int subcuboid_d, glu::GLSLVersion glsl_version);
149     ~TexImageUtils(void);
150 
151 protected:
152     void writePixel(glw::GLubyte *p, glw::GLdouble col);
153     void writeChannel(glw::GLubyte *p, int channel, glw::GLdouble col);
154     template <typename T>
155     void writeToUnsignedChannel(glw::GLubyte *p, int channel, glw::GLdouble col);
156     template <typename T>
157     void writeToSignedChannel(glw::GLubyte *p, int channel, glw::GLdouble col);
158     void writeToFloatChannel(glw::GLubyte *p, int channel, glw::GLdouble col);
159     void writeToHalfFloatChannel(glw::GLubyte *p, int channel, glw::GLdouble col);
160     template <typename T, unsigned int size_1, unsigned int size_2, unsigned int size_3, unsigned int off_1,
161               unsigned int off_2, unsigned int off_3>
162     void write3Channel(glw::GLubyte *p, int channel, glw::GLdouble col);
163     template <typename T, unsigned int size_1, unsigned int size_2, unsigned int size_3, unsigned int size_4,
164               unsigned int off_1, unsigned int off_2, unsigned int off_3, unsigned int off_4>
165     void write4Channel(glw::GLubyte *p, int channel, glw::GLdouble col);
166     void write11F_11F_10F_Channel(glw::GLubyte *p, int channel, glw::GLdouble col);
167     void setRefcolour(glu::CallLogWrapper gl, glw::GLdouble col);
168     template <typename T>
169     void setUnsignedRefcolour(glu::CallLogWrapper gl, glw::GLdouble col);
170     template <typename T>
171     void setSignedRefcolour(glu::CallLogWrapper gl, glw::GLdouble col);
172     void setRGB10A2Refcolour(glu::CallLogWrapper gl, glw::GLdouble col);
173     bool verify(tcu::Surface dst, tcu::Surface *errMask);
174 
175     glw::GLubyte *m_src_data;
176     uint32_t tex;
177     glu::ShaderProgram *prog;
178 
179     uint32_t m_internalFormat;
180     uint32_t m_format;
181     uint32_t m_type;
182     int m_pixelsize;
183     int m_num_channels;
184     int m_cuboid_w;
185     int m_cuboid_h;
186     int m_cuboid_d;
187     int m_subcuboid_x0;
188     int m_subcuboid_y0;
189     int m_subcuboid_z0;
190     int m_subcuboid_w;
191     int m_subcuboid_h;
192     int m_subcuboid_d;
193 
194     glu::GLSLVersion m_glsl_version;
195 };
196 
TexImageUtils(uint32_t internalFormat,int cuboid_w,int cuboid_h,int cuboid_d,int subcuboid_x0,int subcuboid_y0,int subcuboid_z0,int subcuboid_w,int subcuboid_h,int subcuboid_d,glu::GLSLVersion glsl_version)197 TexImageUtils::TexImageUtils(uint32_t internalFormat, int cuboid_w, int cuboid_h, int cuboid_d, int subcuboid_x0,
198                              int subcuboid_y0, int subcuboid_z0, int subcuboid_w, int subcuboid_h, int subcuboid_d,
199                              glu::GLSLVersion glsl_version)
200     : m_src_data(0)
201     , tex(0)
202     , prog(0)
203     , m_internalFormat(internalFormat)
204     , m_format(glu::getTransferFormat(glu::mapGLInternalFormat(internalFormat)).format)
205     , m_type(glu::getTransferFormat(glu::mapGLInternalFormat(internalFormat)).dataType)
206     , m_pixelsize(tcu::getPixelSize(glu::mapGLInternalFormat(internalFormat)))
207     , m_num_channels(tcu::getNumUsedChannels(glu::mapGLInternalFormat(internalFormat).order))
208     , m_cuboid_w(cuboid_w)
209     , m_cuboid_h(cuboid_h)
210     , m_cuboid_d(cuboid_d)
211     , m_subcuboid_x0(subcuboid_x0)
212     , m_subcuboid_y0(subcuboid_y0)
213     , m_subcuboid_z0(subcuboid_z0)
214     , m_subcuboid_w(subcuboid_w)
215     , m_subcuboid_h(subcuboid_h)
216     , m_subcuboid_d(subcuboid_d)
217     , m_glsl_version(glsl_version)
218 {
219 }
220 
~TexImageUtils(void)221 TexImageUtils::~TexImageUtils(void)
222 {
223 }
224 
writePixel(glw::GLubyte * p,glw::GLdouble col)225 void TexImageUtils::writePixel(glw::GLubyte *p, glw::GLdouble col)
226 {
227     for (int ch = 0; ch < m_num_channels; ch++)
228         writeChannel(p, ch, (ch == 3) ? 1.0 : col);
229 }
230 
writeChannel(glw::GLubyte * p,int channel,glw::GLdouble col)231 void TexImageUtils::writeChannel(glw::GLubyte *p, int channel, glw::GLdouble col)
232 {
233     switch (m_type)
234     {
235     case GL_UNSIGNED_BYTE:
236         writeToUnsignedChannel<glw::GLubyte>(p, channel, col);
237         break;
238     case GL_BYTE:
239         writeToSignedChannel<glw::GLbyte>(p, channel, col);
240         break;
241     case GL_UNSIGNED_SHORT:
242         writeToUnsignedChannel<glw::GLushort>(p, channel, col);
243         break;
244     case GL_UNSIGNED_SHORT_5_6_5:
245         write3Channel<glw::GLushort, 5, 6, 5, 11, 5, 0>(p, channel, col);
246         break;
247     case GL_SHORT:
248         writeToSignedChannel<glw::GLshort>(p, channel, col);
249         break;
250     case GL_UNSIGNED_INT:
251         writeToUnsignedChannel<glw::GLuint>(p, channel, col);
252         break;
253     case GL_UNSIGNED_INT_2_10_10_10_REV:
254         write4Channel<glw::GLuint, 2, 10, 10, 10, 30, 20, 10, 0>(p, 3 - channel, col);
255         break;
256     case GL_UNSIGNED_INT_10F_11F_11F_REV:
257         write11F_11F_10F_Channel(p, channel, col);
258         break;
259     case GL_UNSIGNED_SHORT_4_4_4_4:
260         write4Channel<glw::GLushort, 4, 4, 4, 4, 12, 8, 4, 0>(p, channel, col);
261         break;
262     case GL_UNSIGNED_SHORT_5_5_5_1:
263         write4Channel<glw::GLushort, 5, 5, 5, 1, 11, 6, 1, 0>(p, channel, col);
264         break;
265     case GL_INT:
266         writeToSignedChannel<glw::GLint>(p, channel, col);
267         break;
268     case GL_HALF_FLOAT:
269         writeToHalfFloatChannel(p, channel, col);
270         break;
271     case GL_FLOAT:
272         writeToFloatChannel(p, channel, col);
273         break;
274     default:
275         TCU_FAIL("Invalid type");
276     }
277 }
278 
279 template <typename T>
writeToUnsignedChannel(glw::GLubyte * p,int channel,glw::GLdouble col)280 void TexImageUtils::writeToUnsignedChannel(glw::GLubyte *p, int channel, glw::GLdouble col)
281 {
282     static const T max = -1;
283 
284     const glw::GLdouble d_max   = (glw::GLdouble)max;
285     const glw::GLdouble d_value = col * d_max;
286     const T t_value             = (T)d_value;
287 
288     T *ptr = (T *)p;
289 
290     ptr[channel] = t_value;
291 }
292 
293 template <typename T>
writeToSignedChannel(glw::GLubyte * p,int channel,glw::GLdouble col)294 void TexImageUtils::writeToSignedChannel(glw::GLubyte *p, int channel, glw::GLdouble col)
295 {
296     static const T max = (T)((1u << (sizeof(T) * 8u - 1u)) - 1u);
297 
298     const glw::GLdouble d_max   = (glw::GLdouble)max;
299     const glw::GLdouble d_value = col * d_max;
300     const T t_value             = (T)d_value;
301 
302     T *ptr = (T *)p;
303 
304     ptr[channel] = t_value;
305 }
306 
writeToFloatChannel(glw::GLubyte * p,int channel,glw::GLdouble col)307 void TexImageUtils::writeToFloatChannel(glw::GLubyte *p, int channel, glw::GLdouble col)
308 {
309     const glw::GLfloat t_value = (glw::GLfloat)col;
310 
311     glw::GLfloat *ptr = (glw::GLfloat *)p;
312 
313     ptr[channel] = t_value;
314 }
315 
writeToHalfFloatChannel(glw::GLubyte * p,int channel,glw::GLdouble col)316 void TexImageUtils::writeToHalfFloatChannel(glw::GLubyte *p, int channel, glw::GLdouble col)
317 {
318     uint16_t *ptr = (uint16_t *)p;
319 
320     tcu::Float16 val(col);
321 
322     ptr[channel] = val.bits();
323 }
324 
325 template <typename T, unsigned int size_1, unsigned int size_2, unsigned int size_3, unsigned int off_1,
326           unsigned int off_2, unsigned int off_3>
write3Channel(glw::GLubyte * p,int channel,glw::GLdouble col)327 void TexImageUtils::write3Channel(glw::GLubyte *p, int channel, glw::GLdouble col)
328 {
329     T mask   = 0;
330     T max    = 0;
331     T off    = 0;
332     T *ptr   = (T *)p;
333     T result = 0;
334 
335     const T max_1 = (1 << size_1) - 1;
336     const T max_2 = (1 << size_2) - 1;
337     const T max_3 = (1 << size_3) - 1;
338 
339     switch (channel)
340     {
341     case 0:
342         mask = max_1;
343         max  = max_1;
344         off  = off_1;
345         break;
346     case 1:
347         mask = max_2;
348         max  = max_2;
349         off  = off_2;
350         break;
351     case 2:
352         mask = max_3;
353         max  = max_3;
354         off  = off_3;
355         break;
356     default:
357         TCU_FAIL("Invalid channel");
358         break;
359     }
360 
361     const glw::GLdouble d_max   = (glw::GLdouble)max;
362     const glw::GLdouble d_value = col * d_max;
363     const T t_value             = (T)d_value;
364 
365     result = (T)((t_value & mask) << off);
366 
367     *ptr |= result;
368 }
369 
370 template <typename T, unsigned int size_1, unsigned int size_2, unsigned int size_3, unsigned int size_4,
371           unsigned int off_1, unsigned int off_2, unsigned int off_3, unsigned int off_4>
write4Channel(glw::GLubyte * p,int channel,glw::GLdouble col)372 void TexImageUtils::write4Channel(glw::GLubyte *p, int channel, glw::GLdouble col)
373 {
374     T mask   = 0;
375     T max    = 0;
376     T off    = 0;
377     T *ptr   = (T *)p;
378     T result = 0;
379 
380     T max_1 = (1 << size_1) - 1;
381     T max_2 = (1 << size_2) - 1;
382     T max_3 = (1 << size_3) - 1;
383     T max_4 = (1 << size_4) - 1;
384 
385     switch (channel)
386     {
387     case 0:
388         mask = max_1;
389         max  = max_1;
390         off  = off_1;
391         break;
392     case 1:
393         mask = max_2;
394         max  = max_2;
395         off  = off_2;
396         break;
397     case 2:
398         mask = max_3;
399         max  = max_3;
400         off  = off_3;
401         break;
402     case 3:
403         mask = max_4;
404         max  = max_4;
405         off  = off_4;
406         break;
407     default:
408         TCU_FAIL("Invalid channel");
409         break;
410     }
411 
412     const glw::GLdouble d_max   = (glw::GLdouble)max;
413     const glw::GLdouble d_value = col * d_max;
414     const T t_value             = (T)d_value;
415 
416     result = (T)((t_value & mask) << off);
417 
418     *ptr |= result;
419 }
420 
write11F_11F_10F_Channel(glw::GLubyte * p,int channel,glw::GLdouble col)421 void TexImageUtils::write11F_11F_10F_Channel(glw::GLubyte *p, int channel, glw::GLdouble col)
422 {
423     uint32_t *ptr = (uint32_t *)p;
424 
425     switch (channel)
426     {
427     case 0:
428     {
429         tcu::Float<uint32_t, 5, 6, 15, tcu::FLOAT_SUPPORT_DENORM> val(col);
430         uint32_t bits = val.bits();
431 
432         *ptr |= bits;
433     }
434     break;
435     case 1:
436     {
437         tcu::Float<uint32_t, 5, 6, 15, tcu::FLOAT_SUPPORT_DENORM> val(col);
438         uint32_t bits = val.bits();
439 
440         *ptr |= (bits << 11);
441     }
442     break;
443     case 2:
444     {
445         tcu::Float<uint32_t, 5, 5, 15, tcu::FLOAT_SUPPORT_DENORM> val(col);
446         uint32_t bits = val.bits();
447 
448         *ptr |= (bits << 22);
449     }
450     break;
451     default:
452         TCU_FAIL("Invalid channel");
453     }
454 }
455 
setRefcolour(glu::CallLogWrapper gl,glw::GLdouble col)456 void TexImageUtils::setRefcolour(glu::CallLogWrapper gl, glw::GLdouble col)
457 {
458     switch (m_format)
459     {
460     case GL_RED:
461     case GL_RG:
462     case GL_RGB:
463     case GL_RGBA:
464         gl.glUniform4f(gl.glGetUniformLocation(prog->getProgram(), "refcolour"),
465                        m_num_channels > 0 ? (glw::GLfloat)col : 0.0f, m_num_channels > 1 ? (glw::GLfloat)col : 0.0f,
466                        m_num_channels > 2 ? (glw::GLfloat)col : 0.0f, 1.0f);
467         break;
468     default:
469         switch (m_type)
470         {
471         case GL_UNSIGNED_BYTE:
472             setUnsignedRefcolour<glw::GLubyte>(gl, col);
473             break;
474         case GL_BYTE:
475             setSignedRefcolour<glw::GLubyte>(gl, col);
476             break;
477         case GL_UNSIGNED_SHORT:
478         case GL_UNSIGNED_SHORT_5_6_5:
479         case GL_UNSIGNED_SHORT_4_4_4_4:
480         case GL_UNSIGNED_SHORT_5_5_5_1:
481             setUnsignedRefcolour<glw::GLushort>(gl, col);
482             break;
483         case GL_SHORT:
484             setSignedRefcolour<glw::GLushort>(gl, col);
485             break;
486         case GL_UNSIGNED_INT:
487             setUnsignedRefcolour<glw::GLuint>(gl, col);
488             break;
489         case GL_UNSIGNED_INT_2_10_10_10_REV:
490             setRGB10A2Refcolour(gl, col);
491             break;
492         case GL_INT:
493             setSignedRefcolour<glw::GLuint>(gl, col);
494             break;
495         default:
496             TCU_FAIL("Invalid type");
497         }
498     }
499 }
500 
501 template <typename T>
setUnsignedRefcolour(glu::CallLogWrapper gl,glw::GLdouble col)502 void TexImageUtils::setUnsignedRefcolour(glu::CallLogWrapper gl, glw::GLdouble col)
503 {
504     static const T max          = -1;
505     const glw::GLdouble d_max   = (glw::GLdouble)max;
506     const glw::GLdouble d_value = d_max * col;
507     const T t_value             = (T)d_value;
508 
509     unsigned int refcol[4] = {
510         m_num_channels > 0 ? t_value : 0u,
511         m_num_channels > 1 ? t_value : 0u,
512         m_num_channels > 2 ? t_value : 0u,
513         255u,
514     };
515 
516     gl.glUniform4uiv(gl.glGetUniformLocation(prog->getProgram(), "refcolour"), 1, refcol);
517 }
518 
519 template <typename T>
setSignedRefcolour(glu::CallLogWrapper gl,glw::GLdouble col)520 void TexImageUtils::setSignedRefcolour(glu::CallLogWrapper gl, glw::GLdouble col)
521 {
522     static const T umax = -1;
523     static const T max  = umax >> 1;
524 
525     const glw::GLdouble d_max   = (glw::GLdouble)max;
526     const glw::GLdouble d_value = d_max * col;
527     const T t_value             = (T)d_value;
528 
529     int refcol[4] = {
530         (m_num_channels > 0 ? (int)t_value : 0),
531         (m_num_channels > 1 ? (int)t_value : 0),
532         (m_num_channels > 2 ? (int)t_value : 0),
533         255,
534     };
535 
536     gl.glUniform4iv(gl.glGetUniformLocation(prog->getProgram(), "refcolour"), 1, refcol);
537 }
538 
setRGB10A2Refcolour(glu::CallLogWrapper gl,glw::GLdouble col)539 void TexImageUtils::setRGB10A2Refcolour(glu::CallLogWrapper gl, glw::GLdouble col)
540 {
541     unsigned int max_channel_value = 1023u;
542 
543     const glw::GLdouble d_max_channel_value = (glw::GLdouble)max_channel_value;
544     const glw::GLdouble d_value             = (glw::GLdouble)d_max_channel_value * col;
545     unsigned int t_value                    = (unsigned int)d_value;
546 
547     unsigned int refcol[4] = {
548         (m_num_channels > 0 ? t_value : 0u),
549         (m_num_channels > 1 ? t_value : 0u),
550         (m_num_channels > 2 ? t_value : 0u),
551         255u,
552     };
553 
554     gl.glUniform4uiv(gl.glGetUniformLocation(prog->getProgram(), "refcolour"), 1, refcol);
555 }
556 
verify(tcu::Surface dst,tcu::Surface * errMask)557 bool TexImageUtils::verify(tcu::Surface dst, tcu::Surface *errMask)
558 {
559     *errMask = tcu::Surface(dst.getWidth(), dst.getHeight());
560     tcu::clear(errMask->getAccess(), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
561     bool pass = true;
562 
563     for (int y = 0; y < dst.getHeight(); y++)
564     {
565         for (int x = 0; x < dst.getWidth(); x++)
566         {
567             if (dst.getPixel(x, y) != tcu::RGBA::green())
568             {
569                 pass = false;
570                 errMask->setPixel(x, y, tcu::RGBA::red());
571             }
572         }
573     }
574 
575     return pass;
576 }
577 
578 class TexImage2DCase : public deqp::TestCase, public sglr::ContextWrapper, public TexImageUtils
579 {
580 public:
581     TexImage2DCase(deqp::Context &context, const char *name, const char *desc, uint32_t internalFormat, int rect_w,
582                    int rect_h, int subrect_x0, int subrect_y0, int subrect_w, int subrect_h,
583                    glu::GLSLVersion glsl_version);
584     ~TexImage2DCase(void);
585     IterateResult iterate(void);
586 
587 protected:
588     void generateSrcData();
589     void createTexture(void);
590     void createShader(void);
591     tcu::Surface renderToSurf(void);
592     void cleanup(void);
593 };
594 
TexImage2DCase(deqp::Context & context,const char * name,const char * desc,uint32_t internalFormat,int rect_w,int rect_h,int subrect_x0,int subrect_y0,int subrect_w,int subrect_h,glu::GLSLVersion glsl_version)595 TexImage2DCase::TexImage2DCase(deqp::Context &context, const char *name, const char *desc, uint32_t internalFormat,
596                                int rect_w, int rect_h, int subrect_x0, int subrect_y0, int subrect_w, int subrect_h,
597                                glu::GLSLVersion glsl_version)
598     : TestCase(context, name, desc)
599     , TexImageUtils(internalFormat, rect_w, rect_h, 1, subrect_x0, subrect_y0, 0, subrect_w, subrect_h, 1, glsl_version)
600 {
601 }
602 
~TexImage2DCase(void)603 TexImage2DCase::~TexImage2DCase(void)
604 {
605 }
606 
iterate(void)607 TexImage2DCase::IterateResult TexImage2DCase::iterate(void)
608 {
609     glu::RenderContext &renderCtx = TestCase::m_context.getRenderContext();
610     tcu::TestLog &log             = m_testCtx.getLog();
611     tcu::Surface dst, errMask;
612 
613     bool pass = true;
614 
615     sglr::GLContext gl_ctx(renderCtx, log, sglr::GLCONTEXT_LOG_CALLS, tcu::IVec4(0, 0, m_subcuboid_w, m_subcuboid_h));
616 
617     setContext((sglr::Context *)&gl_ctx);
618 
619     generateSrcData();
620     createTexture();
621     createShader();
622     dst = renderToSurf();
623 
624     pass = verify(dst, &errMask);
625 
626     cleanup();
627 
628     if (pass)
629     {
630         m_testCtx.getLog() << tcu::TestLog::Message << "Image is valid" << tcu::TestLog::EndMessage
631                            << tcu::TestLog::ImageSet("ImageVerification", "Image verification")
632                            << tcu::TestLog::Image("Result", "Rendered result", dst.getAccess())
633                            << tcu::TestLog::EndImageSet;
634     }
635     else
636     {
637         m_testCtx.getLog() << tcu::TestLog::Message << "Image is invalid" << tcu::TestLog::EndMessage
638                            << tcu::TestLog::ImageSet("ErrorVerification", "Image verification")
639                            << tcu::TestLog::Image("Result", "Rendered result", dst.getAccess())
640                            << tcu::TestLog::Image("ErrorMask", "Error mask", errMask.getAccess())
641                            << tcu::TestLog::EndImageSet;
642     }
643 
644     m_testCtx.setTestResult(pass ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, pass ? "Pass" : "Fail");
645 
646     return STOP;
647 }
648 
generateSrcData()649 void TexImage2DCase::generateSrcData()
650 {
651     m_src_data = new glw::GLubyte[m_cuboid_w * m_cuboid_h * m_pixelsize]();
652 
653     glw::GLdouble col = 0.0;
654 
655     for (int y = 0; y < m_cuboid_h; y++)
656     {
657         for (int x = 0; x < m_cuboid_w; x++)
658         {
659             if (inrange(y, m_subcuboid_y0, m_subcuboid_y0 + m_subcuboid_h) &&
660                 inrange(x, m_subcuboid_x0, m_subcuboid_x0 + m_subcuboid_w))
661                 col = 1.0;
662             else
663                 col = 0.0;
664             int offset = y * m_cuboid_w * m_pixelsize + x * m_pixelsize;
665             writePixel(m_src_data + offset, col);
666         }
667     }
668 }
669 
createTexture(void)670 void TexImage2DCase::createTexture(void)
671 {
672     glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
673 
674     gl.glGenTextures(1, &tex);
675     gl.glBindTexture(GL_TEXTURE_2D, tex);
676     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
677     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
678 
679     gl.glPixelStorei(GL_UNPACK_ROW_LENGTH, m_cuboid_w);
680     gl.glPixelStorei(GL_UNPACK_SKIP_ROWS, m_subcuboid_y0);
681     gl.glPixelStorei(GL_UNPACK_SKIP_PIXELS, m_subcuboid_x0);
682 
683     gl.glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_subcuboid_w, m_subcuboid_h, 0, m_format, m_type, m_src_data);
684 
685     gl.glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
686     gl.glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
687     gl.glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
688 }
689 
createShader(void)690 void TexImage2DCase::createShader(void)
691 {
692     glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
693 
694     const tcu::StringTemplate vs_src(vs_template_src);
695     const tcu::StringTemplate fs_src(fs_template_src);
696 
697     std::map<std::string, std::string> params;
698     params["GLSL_VERSION"]   = getGLSLVersionDeclaration(m_glsl_version);
699     params["TEXCOORDS_TYPE"] = "vec2";
700     params["LAYER"]          = "";
701     params["TEXCOORDS"]      = "pos.xy";
702     params["CONDITION"]      = "colour.rgb == refcolour.rgb";
703 
704     switch (m_format)
705     {
706     case GL_RED_INTEGER:
707     case GL_RG_INTEGER:
708     case GL_RGB_INTEGER:
709     case GL_RGBA_INTEGER:
710         switch (m_type)
711         {
712         case GL_BYTE:
713         case GL_SHORT:
714         case GL_INT:
715             params["SAMPLER_TYPE"] = "isampler2D";
716             params["COL_TYPE"]     = "ivec4";
717             break;
718         default:
719             params["SAMPLER_TYPE"] = "usampler2D";
720             params["COL_TYPE"]     = "uvec4";
721             break;
722         }
723         break;
724     default:
725         params["SAMPLER_TYPE"] = "sampler2D";
726         params["COL_TYPE"]     = "vec4";
727         break;
728     }
729 
730     prog = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
731                                                                     << glu::VertexSource(vs_src.specialize(params))
732                                                                     << glu::FragmentSource(fs_src.specialize(params)));
733 
734     if (!prog->isOk())
735     {
736         m_testCtx.getLog() << tcu::TestLog::Message << "" << tcu::TestLog::EndMessage
737                            << tcu::TestLog::ShaderProgram(false, "")
738                            << tcu::TestLog::Shader(QP_SHADER_TYPE_VERTEX,
739                                                    prog->getShaderInfo(glu::SHADERTYPE_VERTEX, 0).source, false,
740                                                    prog->getShaderInfo(glu::SHADERTYPE_VERTEX, 0).infoLog)
741 
742                            << tcu::TestLog::Shader(QP_SHADER_TYPE_FRAGMENT,
743                                                    prog->getShaderInfo(glu::SHADERTYPE_FRAGMENT, 0).source, false,
744                                                    prog->getShaderInfo(glu::SHADERTYPE_FRAGMENT, 0).infoLog)
745                            << tcu::TestLog::EndShaderProgram;
746         TCU_FAIL("Shader creation failed");
747     }
748 
749     gl.glUseProgram(prog->getProgram());
750     gl.glUniform1i(gl.glGetUniformLocation(prog->getProgram(), "sampler"), 0);
751 }
752 
renderToSurf(void)753 tcu::Surface TexImage2DCase::renderToSurf(void)
754 {
755     glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
756     gl.glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
757     gl.glClear(GL_COLOR_BUFFER_BIT);
758 
759     static const float vertexPositions[4 * 3] = {
760         -1.0, -1.0, -1.0f, 1.0, -1.0, 0.0f, -1.0, 1.0, 0.0f, 1.0, 1.0, 1.0f,
761     };
762 
763     static const uint16_t indices[6] = {0, 1, 2, 2, 1, 3};
764 
765     const glu::VertexArrayBinding attrBindings[] = {glu::va::Float("pos", 3, 4, 0, &vertexPositions[0])};
766 
767     gl.glViewport(0, 0, m_subcuboid_w, m_subcuboid_h);
768     setRefcolour(gl, 1.0);
769     glu::draw(m_context.getRenderContext(), prog->getProgram(), DE_LENGTH_OF_ARRAY(attrBindings), &attrBindings[0],
770               glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
771 
772     tcu::Surface dst;
773     dst.setSize(m_subcuboid_w, m_subcuboid_h);
774 
775     glu::readPixels(m_context.getRenderContext(), 0, 0, dst.getAccess());
776 
777     return dst;
778 }
779 
cleanup(void)780 void TexImage2DCase::cleanup(void)
781 {
782     glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
783 
784     gl.glDeleteTextures(1, &tex);
785     delete[] m_src_data;
786     delete prog;
787 }
788 
789 class TexImage3DCase : public deqp::TestCase, public sglr::ContextWrapper, public TexImageUtils
790 {
791 public:
792     TexImage3DCase(deqp::Context &context, const char *name, const char *desc, uint32_t internalFormat, int cuboid_w,
793                    int cuboid_h, int cuboid_d, int subcuboid_x0, int subrect_y0, int subcuboid_z0, int subcuboid_w,
794                    int subcuboid_h, int subcuboid_d, glu::GLSLVersion glsl_version);
795     ~TexImage3DCase(void);
796     IterateResult iterate(void);
797 
798 protected:
799     void generateSrcData();
800     void createTexture(void);
801     void createShader(void);
802     tcu::Surface renderToSurf(int layer);
803     void cleanup(void);
804 };
805 
TexImage3DCase(deqp::Context & context,const char * name,const char * desc,uint32_t internalFormat,int cuboid_w,int cuboid_h,int cuboid_d,int subcuboid_x0,int subcuboid_y0,int subcuboid_z0,int subcuboid_w,int subcuboid_h,int subcuboid_d,glu::GLSLVersion glsl_version)806 TexImage3DCase::TexImage3DCase(deqp::Context &context, const char *name, const char *desc, uint32_t internalFormat,
807                                int cuboid_w, int cuboid_h, int cuboid_d, int subcuboid_x0, int subcuboid_y0,
808                                int subcuboid_z0, int subcuboid_w, int subcuboid_h, int subcuboid_d,
809                                glu::GLSLVersion glsl_version)
810     : TestCase(context, name, desc)
811     , TexImageUtils(internalFormat, cuboid_w, cuboid_h, cuboid_d, subcuboid_x0, subcuboid_y0, subcuboid_z0, subcuboid_w,
812                     subcuboid_h, subcuboid_d, glsl_version)
813 {
814 }
815 
~TexImage3DCase(void)816 TexImage3DCase::~TexImage3DCase(void)
817 {
818 }
819 
iterate(void)820 TexImage3DCase::IterateResult TexImage3DCase::iterate(void)
821 {
822     glu::RenderContext &renderCtx = TestCase::m_context.getRenderContext();
823     tcu::TestLog &log             = m_testCtx.getLog();
824     tcu::Surface dst, errMask;
825 
826     bool pass = true;
827 
828     sglr::GLContext gl_ctx(renderCtx, log, sglr::GLCONTEXT_LOG_CALLS, tcu::IVec4(0, 0, m_subcuboid_w, m_subcuboid_h));
829 
830     setContext((sglr::Context *)&gl_ctx);
831 
832     generateSrcData();
833     createTexture();
834     createShader();
835 
836     for (int z = 0; z < m_subcuboid_d; z++)
837     {
838         dst = renderToSurf(z);
839 
840         bool layer_pass = verify(dst, &errMask);
841 
842         if (layer_pass)
843         {
844             m_testCtx.getLog() << tcu::TestLog::Message << "Layer " << z << " is valid" << tcu::TestLog::EndMessage
845                                << tcu::TestLog::ImageSet("LayerVerification", "Layer verification")
846                                << tcu::TestLog::Image("Result", "Rendered result", dst.getAccess())
847                                << tcu::TestLog::EndImageSet;
848         }
849         else
850         {
851             m_testCtx.getLog() << tcu::TestLog::Message << "Layer " << z << " is invalid" << tcu::TestLog::EndMessage
852                                << tcu::TestLog::ImageSet("ErrorVerification", "Layer verification")
853                                << tcu::TestLog::Image("Result", "Rendered result", dst.getAccess())
854                                << tcu::TestLog::Image("ErrorMask", "Error mask", errMask.getAccess())
855                                << tcu::TestLog::EndImageSet;
856         }
857 
858         pass &= layer_pass;
859     }
860 
861     cleanup();
862 
863     if (pass)
864     {
865         m_testCtx.getLog() << tcu::TestLog::Message << "Image is valid" << tcu::TestLog::EndMessage;
866     }
867     else
868     {
869         m_testCtx.getLog() << tcu::TestLog::Message << "Image is invalid" << tcu::TestLog::EndMessage;
870     }
871 
872     m_testCtx.setTestResult(pass ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, pass ? "Pass" : "Fail");
873 
874     return STOP;
875 }
876 
generateSrcData()877 void TexImage3DCase::generateSrcData()
878 {
879     m_src_data = new glw::GLubyte[m_cuboid_w * m_cuboid_h * m_cuboid_d * m_pixelsize]();
880 
881     glw::GLdouble col = 0.0;
882 
883     for (int z = 0; z < m_cuboid_d; z++)
884     {
885         for (int y = 0; y < m_cuboid_h; y++)
886         {
887             for (int x = 0; x < m_cuboid_w; x++)
888             {
889                 if (inrange(z, m_subcuboid_z0, m_subcuboid_z0 + m_subcuboid_d) &&
890                     inrange(y, m_subcuboid_y0, m_subcuboid_y0 + m_subcuboid_h) &&
891                     inrange(x, m_subcuboid_x0, m_subcuboid_x0 + m_subcuboid_w))
892                     col = 0.125 + (z - m_subcuboid_z0) * 0.125; /* [0.125, 0.250..1.0] */
893                 else
894                     col = 0.0;
895                 int offset = z * m_cuboid_h * m_cuboid_w * m_pixelsize + y * m_cuboid_w * m_pixelsize + x * m_pixelsize;
896                 writePixel(m_src_data + offset, col);
897             }
898         }
899     }
900 }
901 
createTexture(void)902 void TexImage3DCase::createTexture(void)
903 {
904     glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
905 
906     gl.glGenTextures(1, &tex);
907     gl.glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
908     gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
909     gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
910 
911     gl.glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, m_cuboid_h);
912     gl.glPixelStorei(GL_UNPACK_ROW_LENGTH, m_cuboid_w);
913     gl.glPixelStorei(GL_UNPACK_SKIP_IMAGES, m_subcuboid_z0);
914     gl.glPixelStorei(GL_UNPACK_SKIP_ROWS, m_subcuboid_y0);
915     gl.glPixelStorei(GL_UNPACK_SKIP_PIXELS, m_subcuboid_x0);
916 
917     gl.glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, m_internalFormat, m_subcuboid_w, m_subcuboid_h, m_subcuboid_d, 0, m_format,
918                     m_type, m_src_data);
919 
920     gl.glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
921     gl.glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
922     gl.glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0);
923     gl.glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
924     gl.glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
925 }
926 
createShader(void)927 void TexImage3DCase::createShader(void)
928 {
929     glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
930 
931     const tcu::StringTemplate vs_src(vs_template_src);
932     const tcu::StringTemplate fs_src(fs_template_src);
933 
934     std::map<std::string, std::string> params;
935     params["GLSL_VERSION"]   = getGLSLVersionDeclaration(m_glsl_version);
936     params["TEXCOORDS_TYPE"] = "vec3";
937     params["LAYER"]          = "uniform int layer;";
938     params["TEXCOORDS"]      = "vec3(pos.xy, layer)";
939 
940     switch (m_format)
941     {
942     case GL_RED_INTEGER:
943     case GL_RG_INTEGER:
944     case GL_RGB_INTEGER:
945     case GL_RGBA_INTEGER:
946         switch (m_type)
947         {
948         case GL_BYTE:
949         case GL_SHORT:
950         case GL_INT:
951             params["SAMPLER_TYPE"] = "isampler2DArray";
952             params["COL_TYPE"]     = "ivec4";
953             params["CONDITION"]    = "all(lessThan(uvec4(abs(colour - refcolour)).rgb, uvec3(2u)))";
954             break;
955         default:
956             params["SAMPLER_TYPE"] = "usampler2DArray";
957             params["COL_TYPE"]     = "uvec4";
958             params["CONDITION"]    = "all(lessThan(uvec4(abs(ivec4(colour) - ivec4(refcolour))).rgb, uvec3(2u)))";
959             break;
960         }
961         break;
962     default:
963         const tcu::StringTemplate fs_condition("all(lessThan((abs(colour - refcolour)).rgb, vec3(${EPS})))");
964         std::map<std::string, std::string> fs_condition_params;
965         fs_condition_params["EPS"] = std::to_string(getEps(m_internalFormat));
966         params["SAMPLER_TYPE"]     = "sampler2DArray";
967         params["COL_TYPE"]         = "vec4";
968         params["CONDITION"]        = fs_condition.specialize(fs_condition_params);
969         break;
970     }
971 
972     prog = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
973                                                                     << glu::VertexSource(vs_src.specialize(params))
974                                                                     << glu::FragmentSource(fs_src.specialize(params)));
975 
976     if (!prog->isOk())
977     {
978         m_testCtx.getLog() << tcu::TestLog::Message << "" << tcu::TestLog::EndMessage
979                            << tcu::TestLog::ShaderProgram(false, "")
980                            << tcu::TestLog::Shader(QP_SHADER_TYPE_VERTEX,
981                                                    prog->getShaderInfo(glu::SHADERTYPE_VERTEX, 0).source, false,
982                                                    prog->getShaderInfo(glu::SHADERTYPE_VERTEX, 0).infoLog)
983 
984                            << tcu::TestLog::Shader(QP_SHADER_TYPE_FRAGMENT,
985                                                    prog->getShaderInfo(glu::SHADERTYPE_FRAGMENT, 0).source, false,
986                                                    prog->getShaderInfo(glu::SHADERTYPE_FRAGMENT, 0).infoLog)
987                            << tcu::TestLog::EndShaderProgram;
988         TCU_FAIL("Shader creation failed");
989     }
990 
991     gl.glUseProgram(prog->getProgram());
992     gl.glUniform1i(gl.glGetUniformLocation(prog->getProgram(), "sampler"), 0);
993 }
994 
renderToSurf(int layer)995 tcu::Surface TexImage3DCase::renderToSurf(int layer)
996 {
997     glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
998     gl.glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
999     gl.glClear(GL_COLOR_BUFFER_BIT);
1000 
1001     static const float vertexPositions[4 * 3] = {
1002         -1.0, -1.0, -1.0f, 1.0, -1.0, 0.0f, -1.0, 1.0, 0.0f, 1.0, 1.0, 1.0f,
1003     };
1004 
1005     static const uint16_t indices[6] = {0, 1, 2, 2, 1, 3};
1006 
1007     const glu::VertexArrayBinding attrBindings[] = {glu::va::Float("pos", 3, 4, 0, &vertexPositions[0])};
1008 
1009     gl.glViewport(0, 0, m_subcuboid_w, m_subcuboid_h);
1010 
1011     gl.glUniform1i(gl.glGetUniformLocation(prog->getProgram(), "layer"), layer);
1012     glw::GLfloat refcol = 0.125f + layer * 0.125f;
1013     setRefcolour(gl, refcol);
1014     glu::draw(m_context.getRenderContext(), prog->getProgram(), DE_LENGTH_OF_ARRAY(attrBindings), &attrBindings[0],
1015               glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
1016 
1017     tcu::Surface dst;
1018     dst.setSize(m_subcuboid_w, m_subcuboid_h);
1019 
1020     glu::readPixels(m_context.getRenderContext(), 0, 0, dst.getAccess());
1021 
1022     return dst;
1023 }
1024 
cleanup(void)1025 void TexImage3DCase::cleanup(void)
1026 {
1027     glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
1028 
1029     gl.glDeleteTextures(1, &tex);
1030     delete[] m_src_data;
1031     delete prog;
1032 }
1033 
1034 class CompressedTexImageUtils
1035 {
1036 public:
1037     CompressedTexImageUtils(uint32_t internalFormat, int cuboid_w, int cuboid_h, int cuboid_d, int subcuboid_x0,
1038                             int subcuboid_y0, int subcuboid_z0, int subcuboid_w, int subcuboid_h, int subcuboid_d,
1039                             glu::GLSLVersion glsl_version);
1040     ~CompressedTexImageUtils(void);
1041 
1042 protected:
1043     int getImageSize(int width, int height, int depth);
1044     bool verify(tcu::Surface dst, tcu::Surface *errMask);
1045 
1046     glw::GLubyte *m_src_data;
1047     uint32_t tex;
1048     glu::ShaderProgram *prog;
1049 
1050     int m_bw; /* block width */
1051     int m_bh; /* block height */
1052     int m_bd; /* block depth */
1053     int m_bs; /* block size */
1054 
1055     uint32_t m_internalFormat;
1056     int m_cuboid_w;
1057     int m_cuboid_h;
1058     int m_cuboid_d;
1059     int m_subcuboid_x0;
1060     int m_subcuboid_y0;
1061     int m_subcuboid_z0;
1062     int m_subcuboid_w;
1063     int m_subcuboid_h;
1064     int m_subcuboid_d;
1065 
1066     glu::GLSLVersion m_glsl_version;
1067 };
1068 
CompressedTexImageUtils(uint32_t internalFormat,int cuboid_w,int cuboid_h,int cuboid_d,int subcuboid_x0,int subcuboid_y0,int subcuboid_z0,int subcuboid_w,int subcuboid_h,int subcuboid_d,glu::GLSLVersion glsl_version)1069 CompressedTexImageUtils::CompressedTexImageUtils(uint32_t internalFormat, int cuboid_w, int cuboid_h, int cuboid_d,
1070                                                  int subcuboid_x0, int subcuboid_y0, int subcuboid_z0, int subcuboid_w,
1071                                                  int subcuboid_h, int subcuboid_d, glu::GLSLVersion glsl_version)
1072     : m_internalFormat(internalFormat)
1073     , m_cuboid_w(cuboid_w)
1074     , m_cuboid_h(cuboid_h)
1075     , m_cuboid_d(cuboid_d)
1076     , m_subcuboid_x0(subcuboid_x0)
1077     , m_subcuboid_y0(subcuboid_y0)
1078     , m_subcuboid_z0(subcuboid_z0)
1079     , m_subcuboid_w(subcuboid_w)
1080     , m_subcuboid_h(subcuboid_h)
1081     , m_subcuboid_d(subcuboid_d)
1082     , m_glsl_version(glsl_version)
1083 {
1084 }
1085 
~CompressedTexImageUtils(void)1086 CompressedTexImageUtils::~CompressedTexImageUtils(void)
1087 {
1088 }
1089 
getImageSize(int width,int height,int depth)1090 int CompressedTexImageUtils::getImageSize(int width, int height, int depth)
1091 {
1092     return (width / m_bw + (width % m_bw > 0)) * (height / m_bh + (height % m_bh > 0)) *
1093            (depth / m_bd + (depth % m_bd > 0)) * m_bs;
1094 }
1095 
verify(tcu::Surface dst,tcu::Surface * errMask)1096 bool CompressedTexImageUtils::verify(tcu::Surface dst, tcu::Surface *errMask)
1097 {
1098     *errMask = tcu::Surface(dst.getWidth(), dst.getHeight());
1099     tcu::clear(errMask->getAccess(), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
1100     bool pass = true;
1101 
1102     for (int y = 0; y < dst.getHeight(); y++)
1103     {
1104         for (int x = 0; x < dst.getWidth(); x++)
1105         {
1106             if (dst.getPixel(x, y) != tcu::RGBA::green())
1107             {
1108                 pass = false;
1109                 errMask->setPixel(x, y, tcu::RGBA::red());
1110             }
1111         }
1112     }
1113 
1114     return pass;
1115 }
1116 
1117 class CompressedTexImage2DCase : public deqp::TestCase, public sglr::ContextWrapper, public CompressedTexImageUtils
1118 {
1119 public:
1120     CompressedTexImage2DCase(deqp::Context &context, const char *name, const char *desc, uint32_t internalFormat,
1121                              int cuboid_w, int cuboid_h, int subcuboid_x0, int subcuboid_y0, int subcuboid_w,
1122                              int subcuboid_h, glu::GLSLVersion glsl_version);
1123     ~CompressedTexImage2DCase(void);
1124     IterateResult iterate(void);
1125 
1126 protected:
1127     void generateSrcData_s3tc(void);
1128     void generateSrcData_astc(void);
1129     void createTexture(void);
1130     void createShader(void);
1131     tcu::Surface renderToSurf(void);
1132     void cleanup(void);
1133 };
1134 
CompressedTexImage2DCase(deqp::Context & context,const char * name,const char * desc,uint32_t internalFormat,int cuboid_w,int cuboid_h,int subcuboid_x0,int subcuboid_y0,int subcuboid_w,int subcuboid_h,glu::GLSLVersion glsl_version)1135 CompressedTexImage2DCase::CompressedTexImage2DCase(deqp::Context &context, const char *name, const char *desc,
1136                                                    uint32_t internalFormat, int cuboid_w, int cuboid_h,
1137                                                    int subcuboid_x0, int subcuboid_y0, int subcuboid_w, int subcuboid_h,
1138                                                    glu::GLSLVersion glsl_version)
1139     : TestCase(context, name, desc)
1140     , CompressedTexImageUtils(internalFormat, cuboid_w, cuboid_h, 1, subcuboid_x0, subcuboid_y0, 0, subcuboid_w,
1141                               subcuboid_h, 1, glsl_version)
1142 {
1143 }
1144 
~CompressedTexImage2DCase(void)1145 CompressedTexImage2DCase::~CompressedTexImage2DCase(void)
1146 {
1147 }
1148 
iterate(void)1149 CompressedTexImage2DCase::IterateResult CompressedTexImage2DCase::iterate(void)
1150 {
1151     glu::RenderContext &renderCtx   = TestCase::m_context.getRenderContext();
1152     const glu::ContextInfo &ctxInfo = m_context.getContextInfo();
1153     tcu::TestLog &log               = m_testCtx.getLog();
1154     tcu::Surface dst, errMask;
1155 
1156     bool pass = true;
1157 
1158     sglr::GLContext gl_ctx(renderCtx, log, sglr::GLCONTEXT_LOG_CALLS, tcu::IVec4(0, 0, m_subcuboid_w, m_subcuboid_h));
1159 
1160     setContext((sglr::Context *)&gl_ctx);
1161 
1162     if (!glu::contextSupports(renderCtx.getType(), glu::ApiType::core(4, 2)) &&
1163         !ctxInfo.isExtensionSupported("GL_ARB_compressed_texture_pixel_storage"))
1164     {
1165         m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED,
1166                                 "GL_ARB_compressed_texture_pixel_storage extension is not supported");
1167         return STOP;
1168     }
1169 
1170     switch (m_internalFormat)
1171     {
1172     case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1173         if (!ctxInfo.isExtensionSupported("GL_EXT_texture_compression_s3tc"))
1174         {
1175             m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED,
1176                                     "GL_EXT_texture_compression_s3tc extension is not supported");
1177             return STOP;
1178         }
1179 
1180         m_bw = 4;
1181         m_bh = 4;
1182         m_bd = 1;
1183         m_bs = 8;
1184 
1185         generateSrcData_s3tc();
1186         break;
1187     case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
1188         if (!ctxInfo.isExtensionSupported("GL_KHR_texture_compression_astc_ldr"))
1189         {
1190             m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED,
1191                                     "GL_KHR_texture_compression_astc_ldr extension is not supported");
1192             return STOP;
1193         }
1194         m_bw = 8;
1195         m_bh = 5;
1196         m_bd = 1;
1197         m_bs = 16;
1198 
1199         generateSrcData_astc();
1200         break;
1201     default:
1202         TCU_FAIL("Invalid internal format");
1203     }
1204 
1205     createTexture();
1206     createShader();
1207 
1208     dst  = renderToSurf();
1209     pass = verify(dst, &errMask);
1210 
1211     cleanup();
1212 
1213     if (pass)
1214     {
1215         m_testCtx.getLog() << tcu::TestLog::Message << "Image is valid" << tcu::TestLog::EndMessage
1216                            << tcu::TestLog::ImageSet("ImageVerification", "Image verification")
1217                            << tcu::TestLog::Image("Result", "Rendered result", dst.getAccess())
1218                            << tcu::TestLog::EndImageSet;
1219     }
1220     else
1221     {
1222         m_testCtx.getLog() << tcu::TestLog::Message << "Image is invalid" << tcu::TestLog::EndMessage
1223                            << tcu::TestLog::ImageSet("ErrorVerification", "Image verification")
1224                            << tcu::TestLog::Image("Result", "Rendered result", dst.getAccess())
1225                            << tcu::TestLog::Image("ErrorMask", "Error mask", errMask.getAccess())
1226                            << tcu::TestLog::EndImageSet;
1227     }
1228 
1229     m_testCtx.setTestResult(pass ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, pass ? "Pass" : "Fail");
1230 
1231     return STOP;
1232 }
1233 
generateSrcData_s3tc(void)1234 void CompressedTexImage2DCase::generateSrcData_s3tc(void)
1235 {
1236     uint64_t *src = new uint64_t[m_cuboid_w / m_bw * m_cuboid_h / m_bh];
1237 
1238     uint64_t col = 0x0;
1239 
1240     for (int y = 0; y < m_cuboid_h; y += m_bh)
1241     {
1242         for (int x = 0; x < m_cuboid_w; x += m_bw)
1243         {
1244             if (inrange(x, m_subcuboid_x0, m_subcuboid_x0 + m_subcuboid_w) &&
1245                 inrange(y, m_subcuboid_y0, m_subcuboid_y0 + m_subcuboid_h))
1246             {
1247                 col = 0xffff;
1248             }
1249             else
1250             {
1251                 col = 0x0;
1252             }
1253             int index  = (y / m_bh) * (m_cuboid_w / m_bw) + (x / m_bw);
1254             src[index] = col;
1255         }
1256     }
1257 
1258     m_src_data = (glw::GLubyte *)src;
1259 }
1260 
generateSrcData_astc(void)1261 void CompressedTexImage2DCase::generateSrcData_astc(void)
1262 {
1263     uint64_t col  = 0x0;
1264     uint64_t mask = 0xfffffffffffffdfc;
1265 
1266     int img_size = 2 * (m_cuboid_w / m_bw + (m_cuboid_w % m_bw > 0)) * (m_cuboid_h / m_bh + (m_cuboid_h % m_bh > 0));
1267 
1268     uint64_t *src = new uint64_t[img_size];
1269 
1270     for (int y = 0; y < m_cuboid_h; y += m_bh)
1271     {
1272         for (int x = 0; x < m_cuboid_w; x += m_bw)
1273         {
1274             if (inrange(x, m_subcuboid_x0, m_subcuboid_x0 + m_subcuboid_w) &&
1275                 inrange(y, m_subcuboid_y0, m_subcuboid_y0 + m_subcuboid_h))
1276             {
1277                 col = 0xffffffffffffffff; /* (1.0, 1.0, 1.0) */
1278             }
1279             else
1280             {
1281                 col = 0x0; /* (0.0, 0.0, 0.0) */
1282             }
1283             int index          = (y / m_bh) * (m_cuboid_w / m_bw + (m_cuboid_w % m_bw > 0)) + (x / m_bw);
1284             src[2 * index]     = mask;
1285             src[2 * index + 1] = col;
1286         }
1287     }
1288 
1289     m_src_data = (glw::GLubyte *)src;
1290 }
1291 
createTexture(void)1292 void CompressedTexImage2DCase::createTexture(void)
1293 {
1294     glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
1295 
1296     gl.glGenTextures(1, &tex);
1297     gl.glBindTexture(GL_TEXTURE_2D, tex);
1298     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1299     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1300 
1301     gl.glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_SIZE, m_bs);
1302     gl.glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH, m_bw);
1303     gl.glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_HEIGHT, m_bh);
1304 
1305     gl.glPixelStorei(GL_UNPACK_ROW_LENGTH, m_cuboid_w);
1306     gl.glPixelStorei(GL_UNPACK_SKIP_ROWS, m_subcuboid_y0);
1307     gl.glPixelStorei(GL_UNPACK_SKIP_PIXELS, m_subcuboid_x0);
1308 
1309     gl.glCompressedTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_subcuboid_w, m_subcuboid_h, 0,
1310                               getImageSize(m_subcuboid_w, m_subcuboid_h, m_subcuboid_d), m_src_data);
1311 
1312     gl.glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_SIZE, 0);
1313     gl.glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH, 0);
1314     gl.glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_HEIGHT, 0);
1315 
1316     gl.glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
1317     gl.glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
1318     gl.glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
1319 }
1320 
createShader(void)1321 void CompressedTexImage2DCase::createShader(void)
1322 {
1323     glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
1324 
1325     const tcu::StringTemplate vs_src(vs_template_src);
1326     const tcu::StringTemplate fs_src(fs_template_src);
1327 
1328     std::map<std::string, std::string> params;
1329     params["GLSL_VERSION"]   = getGLSLVersionDeclaration(m_glsl_version);
1330     params["TEXCOORDS_TYPE"] = "vec2";
1331     params["LAYER"]          = "";
1332     params["TEXCOORDS"]      = "pos.xy";
1333     params["SAMPLER_TYPE"]   = "sampler2D";
1334     params["COL_TYPE"]       = "vec4";
1335     params["CONDITION"]      = "colour.rgb == refcolour.rgb";
1336 
1337     prog = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
1338                                                                     << glu::VertexSource(vs_src.specialize(params))
1339                                                                     << glu::FragmentSource(fs_src.specialize(params)));
1340 
1341     if (!prog->isOk())
1342     {
1343         m_testCtx.getLog() << tcu::TestLog::Message << "" << tcu::TestLog::EndMessage
1344                            << tcu::TestLog::ShaderProgram(false, "")
1345                            << tcu::TestLog::Shader(QP_SHADER_TYPE_VERTEX,
1346                                                    prog->getShaderInfo(glu::SHADERTYPE_VERTEX, 0).source, false,
1347                                                    prog->getShaderInfo(glu::SHADERTYPE_VERTEX, 0).infoLog)
1348 
1349                            << tcu::TestLog::Shader(QP_SHADER_TYPE_FRAGMENT,
1350                                                    prog->getShaderInfo(glu::SHADERTYPE_FRAGMENT, 0).source, false,
1351                                                    prog->getShaderInfo(glu::SHADERTYPE_FRAGMENT, 0).infoLog)
1352                            << tcu::TestLog::EndShaderProgram;
1353         TCU_FAIL("Shader creation failed");
1354     }
1355 
1356     gl.glUseProgram(prog->getProgram());
1357     gl.glUniform1i(gl.glGetUniformLocation(prog->getProgram(), "sampler"), 0);
1358 }
1359 
renderToSurf(void)1360 tcu::Surface CompressedTexImage2DCase::renderToSurf(void)
1361 {
1362     glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
1363 
1364     gl.glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
1365     gl.glClear(GL_COLOR_BUFFER_BIT);
1366 
1367     static const float vertexPositions[4 * 3] = {
1368         -1.0, -1.0, -1.0f, 1.0, -1.0, 0.0f, -1.0, 1.0, 0.0f, 1.0, 1.0, 1.0f,
1369     };
1370 
1371     static const uint16_t indices[6] = {0, 1, 2, 2, 1, 3};
1372 
1373     const glu::VertexArrayBinding attrBindings[] = {glu::va::Float("pos", 3, 4, 0, &vertexPositions[0])};
1374 
1375     gl.glViewport(0, 0, m_subcuboid_w, m_subcuboid_h);
1376 
1377     glw::GLfloat refcol = 1.0f;
1378 
1379     gl.glUniform4f(gl.glGetUniformLocation(prog->getProgram(), "refcolour"), refcol, refcol, refcol, 1.0f);
1380 
1381     glu::draw(m_context.getRenderContext(), prog->getProgram(), DE_LENGTH_OF_ARRAY(attrBindings), &attrBindings[0],
1382               glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
1383 
1384     tcu::Surface dst;
1385     dst.setSize(m_subcuboid_w, m_subcuboid_h);
1386 
1387     glu::readPixels(m_context.getRenderContext(), 0, 0, dst.getAccess());
1388 
1389     return dst;
1390 }
1391 
cleanup(void)1392 void CompressedTexImage2DCase::cleanup(void)
1393 {
1394     glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
1395 
1396     gl.glDeleteTextures(1, &tex);
1397     delete[] m_src_data;
1398     delete prog;
1399 }
1400 
1401 class CompressedTexImage3DCase : public deqp::TestCase, public sglr::ContextWrapper, public CompressedTexImageUtils
1402 {
1403 public:
1404     CompressedTexImage3DCase(deqp::Context &context, const char *name, const char *desc, uint32_t internalFormat,
1405                              int cuboid_w, int cuboid_h, int cuboid_d, int subcuboid_x0, int subcuboid_y0,
1406                              int subcuboid_z0, int subcuboid_w, int subcuboid_h, int subcuboid_d,
1407                              glu::GLSLVersion glsl_version);
1408     ~CompressedTexImage3DCase(void);
1409     IterateResult iterate(void);
1410 
1411 protected:
1412     void generateSrcData_s3tc(void);
1413     void generateSrcData_astc(void);
1414     void createTexture(void);
1415     void createShader(void);
1416     tcu::Surface renderToSurf(int layer);
1417     void cleanup(void);
1418 };
1419 
CompressedTexImage3DCase(deqp::Context & context,const char * name,const char * desc,uint32_t internalFormat,int cuboid_w,int cuboid_h,int cuboid_d,int subcuboid_x0,int subcuboid_y0,int subcuboid_z0,int subcuboid_w,int subcuboid_h,int subcuboid_d,glu::GLSLVersion glsl_version)1420 CompressedTexImage3DCase::CompressedTexImage3DCase(deqp::Context &context, const char *name, const char *desc,
1421                                                    uint32_t internalFormat, int cuboid_w, int cuboid_h, int cuboid_d,
1422                                                    int subcuboid_x0, int subcuboid_y0, int subcuboid_z0,
1423                                                    int subcuboid_w, int subcuboid_h, int subcuboid_d,
1424                                                    glu::GLSLVersion glsl_version)
1425     : TestCase(context, name, desc)
1426     , CompressedTexImageUtils(internalFormat, cuboid_w, cuboid_h, cuboid_d, subcuboid_x0, subcuboid_y0, subcuboid_z0,
1427                               subcuboid_w, subcuboid_h, subcuboid_d, glsl_version)
1428 {
1429 }
1430 
~CompressedTexImage3DCase(void)1431 CompressedTexImage3DCase::~CompressedTexImage3DCase(void)
1432 {
1433 }
1434 
iterate(void)1435 CompressedTexImage3DCase::IterateResult CompressedTexImage3DCase::iterate(void)
1436 {
1437     glu::RenderContext &renderCtx   = TestCase::m_context.getRenderContext();
1438     const glu::ContextInfo &ctxInfo = m_context.getContextInfo();
1439     tcu::TestLog &log               = m_testCtx.getLog();
1440     tcu::Surface dst, errMask;
1441 
1442     bool pass = true;
1443 
1444     sglr::GLContext gl_ctx(renderCtx, log, sglr::GLCONTEXT_LOG_CALLS, tcu::IVec4(0, 0, m_subcuboid_w, m_subcuboid_h));
1445 
1446     setContext((sglr::Context *)&gl_ctx);
1447 
1448     if (!glu::contextSupports(renderCtx.getType(), glu::ApiType::core(4, 2)) &&
1449         !ctxInfo.isExtensionSupported("GL_ARB_compressed_texture_pixel_storage"))
1450     {
1451         m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED,
1452                                 "GL_ARB_compressed_texture_pixel_storage extension is not supported");
1453         return STOP;
1454     }
1455 
1456     switch (m_internalFormat)
1457     {
1458     case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1459         if (!ctxInfo.isExtensionSupported("GL_EXT_texture_compression_s3tc"))
1460         {
1461             m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED,
1462                                     "GL_EXT_texture_compression_s3tc extension is not supported");
1463             return STOP;
1464         }
1465 
1466         m_bw = 4;
1467         m_bh = 4;
1468         m_bd = 1;
1469         m_bs = 8;
1470 
1471         generateSrcData_s3tc();
1472         break;
1473     case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
1474         if (!ctxInfo.isExtensionSupported("GL_KHR_texture_compression_astc_ldr"))
1475         {
1476             m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED,
1477                                     "GL_KHR_texture_compression_astc_ldr extension is not supported");
1478             return STOP;
1479         }
1480         m_bw = 8;
1481         m_bh = 5;
1482         m_bd = 1;
1483         m_bs = 16;
1484 
1485         generateSrcData_astc();
1486         break;
1487     default:
1488         TCU_FAIL("Invalid internal format");
1489     }
1490 
1491     createTexture();
1492     createShader();
1493 
1494     for (int z = 0; z < m_subcuboid_d; z++)
1495     {
1496         dst = renderToSurf(z);
1497 
1498         bool layer_pass = verify(dst, &errMask);
1499 
1500         if (layer_pass)
1501         {
1502             m_testCtx.getLog() << tcu::TestLog::Message << "Layer " << z << " is valid" << tcu::TestLog::EndMessage
1503                                << tcu::TestLog::ImageSet("LayerVerification", "Layer verification")
1504                                << tcu::TestLog::Image("Result", "Rendered result", dst.getAccess())
1505                                << tcu::TestLog::EndImageSet;
1506         }
1507         else
1508         {
1509             m_testCtx.getLog() << tcu::TestLog::Message << "Layer " << z << " is invalid" << tcu::TestLog::EndMessage
1510                                << tcu::TestLog::ImageSet("ErrorVerification", "Layer verification")
1511                                << tcu::TestLog::Image("Result", "Rendered result", dst.getAccess())
1512                                << tcu::TestLog::Image("ErrorMask", "Error mask", errMask.getAccess())
1513                                << tcu::TestLog::EndImageSet;
1514         }
1515 
1516         pass &= layer_pass;
1517     }
1518 
1519     cleanup();
1520 
1521     if (pass)
1522     {
1523         m_testCtx.getLog() << tcu::TestLog::Message << "Image is valid" << tcu::TestLog::EndMessage;
1524     }
1525     else
1526     {
1527         m_testCtx.getLog() << tcu::TestLog::Message << "Image is invalid" << tcu::TestLog::EndMessage;
1528     }
1529 
1530     m_testCtx.setTestResult(pass ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, pass ? "Pass" : "Fail");
1531 
1532     return STOP;
1533 }
1534 
generateSrcData_s3tc()1535 void CompressedTexImage3DCase::generateSrcData_s3tc()
1536 {
1537     uint64_t *src = new uint64_t[m_cuboid_w / m_bw * m_cuboid_h / m_bh * m_cuboid_d / m_bd];
1538 
1539     uint64_t col_list[] = {
1540         0x18E3, /* (0.125, 0.125, 0.125) */
1541         0x39E7, /* (0.250, 0.250, 0.250) */
1542         0x5AEB, /* (0.375, 0.375, 0.375) */
1543         0x7BEF, /* (0.500, 0.500, 0.500) */
1544         0x9CF3, /* (0.625, 0.625, 0.625) */
1545         0xBDF7, /* (0.750, 0.750, 0.750) */
1546         0xDEFB, /* (0.875, 0.875, 0.875) */
1547         0xffff, /* (1.000, 1.000, 1.000) */
1548     };
1549 
1550     uint64_t col = 0x0;
1551 
1552     for (int z = 0; z < m_cuboid_d; z += m_bd)
1553     {
1554         for (int y = 0; y < m_cuboid_h; y += m_bh)
1555         {
1556             for (int x = 0; x < m_cuboid_w; x += m_bw)
1557             {
1558                 if (inrange(x, m_subcuboid_x0, m_subcuboid_x0 + m_subcuboid_w) &&
1559                     inrange(y, m_subcuboid_y0, m_subcuboid_y0 + m_subcuboid_h) &&
1560                     inrange(z, m_subcuboid_z0, m_subcuboid_z0 + m_subcuboid_d))
1561                     col = col_list[z % 8];
1562                 else
1563                     col = 0x0;
1564 
1565                 int index = (z / m_bd) * (m_cuboid_h / m_bh) * (m_cuboid_w / m_bw) + (y / m_bh) * (m_cuboid_w / m_bw) +
1566                             (x / m_bw);
1567                 src[index] = col;
1568             }
1569         }
1570     }
1571 
1572     m_src_data = (glw::GLubyte *)src;
1573 }
1574 
generateSrcData_astc(void)1575 void CompressedTexImage3DCase::generateSrcData_astc(void)
1576 {
1577     uint64_t col_list[] = {
1578         0xffff1fff1fff1fff, /* (0.125, 0.125, 0.125) */
1579         0xffff3fff3fff3fff, /* (0.250, 0.250, 0.250) */
1580         0xffff5fff5fff5fff, /* (0.375, 0.375, 0.375) */
1581         0xffff7fff7fff7fff, /* (0.500, 0.500, 0.500) */
1582         0xffff9fff9fff9fff, /* (0.625, 0.625, 0.625) */
1583         0xffffbfffbfffbfff, /* (0.750, 0.750, 0.750) */
1584         0xffffdfffdfffdfff, /* (0.875, 0.875, 0.875) */
1585         0xffffffffffffffff, /* (1.000, 1.000, 1.000) */
1586     };
1587     uint64_t col  = 0x0;
1588     uint64_t mask = 0xFFFFFFFFFFFFFDFC;
1589 
1590     int img_size = 2 * (m_cuboid_w / m_bw + (m_cuboid_w % m_bw > 0)) * (m_cuboid_h / m_bh + (m_cuboid_h % m_bh > 0)) *
1591                    (m_cuboid_d / m_bd + (m_cuboid_d % m_bd > 0));
1592 
1593     uint64_t *src = new uint64_t[img_size];
1594 
1595     for (int z = 0; z < m_cuboid_d; z += m_bd)
1596     {
1597         for (int y = 0; y < m_cuboid_h; y += m_bh)
1598         {
1599             for (int x = 0; x < m_cuboid_w; x += m_bw)
1600             {
1601                 if (inrange(x, m_subcuboid_x0, m_subcuboid_x0 + m_subcuboid_w) &&
1602                     inrange(y, m_subcuboid_y0, m_subcuboid_y0 + m_subcuboid_h) &&
1603                     inrange(z, m_subcuboid_z0, m_subcuboid_z0 + m_subcuboid_d))
1604                     col = col_list[z % 8];
1605                 else
1606                     col = 0x0;
1607 
1608                 int index = (z / m_bd) * (m_cuboid_h / m_bh + (m_cuboid_h % m_bh > 0)) *
1609                                 (m_cuboid_w / m_bw + (m_cuboid_w % m_bw > 0)) +
1610                             (y / m_bh) * (m_cuboid_w / m_bw + (m_cuboid_w % m_bw > 0)) + (x / m_bw);
1611                 src[2 * index]     = mask;
1612                 src[2 * index + 1] = col;
1613             }
1614         }
1615     }
1616 
1617     m_src_data = (glw::GLubyte *)src;
1618 }
1619 
createTexture(void)1620 void CompressedTexImage3DCase::createTexture(void)
1621 {
1622     glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
1623 
1624     gl.glGenTextures(1, &tex);
1625     gl.glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
1626     gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1627     gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1628 
1629     gl.glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_SIZE, m_bs);
1630     gl.glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH, m_bw);
1631     gl.glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_HEIGHT, m_bh);
1632     gl.glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_DEPTH, m_bd);
1633 
1634     gl.glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, m_cuboid_h);
1635     gl.glPixelStorei(GL_UNPACK_ROW_LENGTH, m_cuboid_w);
1636     gl.glPixelStorei(GL_UNPACK_SKIP_IMAGES, m_subcuboid_z0);
1637     gl.glPixelStorei(GL_UNPACK_SKIP_ROWS, m_subcuboid_y0);
1638     gl.glPixelStorei(GL_UNPACK_SKIP_PIXELS, m_subcuboid_x0);
1639 
1640     gl.glCompressedTexImage3D(GL_TEXTURE_2D_ARRAY, 0, m_internalFormat, m_subcuboid_w, m_subcuboid_h, m_subcuboid_d, 0,
1641                               getImageSize(m_subcuboid_w, m_subcuboid_h, m_subcuboid_d), m_src_data);
1642 
1643     gl.glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_SIZE, 0);
1644     gl.glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH, 0);
1645     gl.glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_HEIGHT, 0);
1646     gl.glPixelStorei(GL_UNPACK_COMPRESSED_BLOCK_DEPTH, 0);
1647 
1648     gl.glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
1649     gl.glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
1650     gl.glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0);
1651     gl.glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
1652     gl.glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
1653 }
1654 
createShader(void)1655 void CompressedTexImage3DCase::createShader(void)
1656 {
1657     glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
1658 
1659     const tcu::StringTemplate vs_src(vs_template_src);
1660     const tcu::StringTemplate fs_src(fs_template_src);
1661 
1662     std::map<std::string, std::string> params;
1663     params["GLSL_VERSION"]   = getGLSLVersionDeclaration(m_glsl_version);
1664     params["TEXCOORDS_TYPE"] = "vec3";
1665     params["LAYER"]          = "uniform int layer;";
1666     params["TEXCOORDS"]      = "vec3(pos.xy, layer)";
1667     params["SAMPLER_TYPE"]   = "sampler2DArray";
1668     params["COL_TYPE"]       = "vec4";
1669 
1670     const tcu::StringTemplate fs_condition("all(lessThan((abs(colour - refcolour)).rgb, vec3(${EPS})))");
1671     std::map<std::string, std::string> fs_condition_params;
1672     fs_condition_params["EPS"] = std::to_string(getEps(m_internalFormat));
1673     params["CONDITION"]        = fs_condition.specialize(fs_condition_params);
1674 
1675     prog = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
1676                                                                     << glu::VertexSource(vs_src.specialize(params))
1677                                                                     << glu::FragmentSource(fs_src.specialize(params)));
1678 
1679     if (!prog->isOk())
1680     {
1681         m_testCtx.getLog() << tcu::TestLog::Message << "" << tcu::TestLog::EndMessage
1682                            << tcu::TestLog::ShaderProgram(false, "")
1683                            << tcu::TestLog::Shader(QP_SHADER_TYPE_VERTEX,
1684                                                    prog->getShaderInfo(glu::SHADERTYPE_VERTEX, 0).source, false,
1685                                                    prog->getShaderInfo(glu::SHADERTYPE_VERTEX, 0).infoLog)
1686 
1687                            << tcu::TestLog::Shader(QP_SHADER_TYPE_FRAGMENT,
1688                                                    prog->getShaderInfo(glu::SHADERTYPE_FRAGMENT, 0).source, false,
1689                                                    prog->getShaderInfo(glu::SHADERTYPE_FRAGMENT, 0).infoLog)
1690                            << tcu::TestLog::EndShaderProgram;
1691         TCU_FAIL("Shader creation failed");
1692     }
1693 
1694     gl.glUseProgram(prog->getProgram());
1695     gl.glUniform1i(gl.glGetUniformLocation(prog->getProgram(), "sampler"), 0);
1696 }
1697 
renderToSurf(int layer)1698 tcu::Surface CompressedTexImage3DCase::renderToSurf(int layer)
1699 {
1700     glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
1701 
1702     gl.glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
1703     gl.glClear(GL_COLOR_BUFFER_BIT);
1704 
1705     static const float vertexPositions[4 * 3] = {
1706         -1.0, -1.0, -1.0f, 1.0, -1.0, 0.0f, -1.0, 1.0, 0.0f, 1.0, 1.0, 1.0f,
1707     };
1708 
1709     static const uint16_t indices[6] = {0, 1, 2, 2, 1, 3};
1710 
1711     const glu::VertexArrayBinding attrBindings[] = {glu::va::Float("pos", 3, 4, 0, &vertexPositions[0])};
1712 
1713     gl.glViewport(0, 0, m_subcuboid_w, m_subcuboid_h);
1714 
1715     gl.glUniform1i(gl.glGetUniformLocation(prog->getProgram(), "layer"), layer);
1716 
1717     glw::GLfloat refcols[8] = {0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1.0};
1718     glw::GLfloat refcol     = refcols[(layer + m_subcuboid_z0 % 8) % 8];
1719 
1720     gl.glUniform4f(gl.glGetUniformLocation(prog->getProgram(), "refcolour"), refcol, refcol, refcol, 1.0f);
1721 
1722     glu::draw(m_context.getRenderContext(), prog->getProgram(), DE_LENGTH_OF_ARRAY(attrBindings), &attrBindings[0],
1723               glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
1724 
1725     tcu::Surface dst;
1726     dst.setSize(m_subcuboid_w, m_subcuboid_h);
1727 
1728     glu::readPixels(m_context.getRenderContext(), 0, 0, dst.getAccess());
1729 
1730     return dst;
1731 }
1732 
cleanup(void)1733 void CompressedTexImage3DCase::cleanup(void)
1734 {
1735     glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
1736 
1737     gl.glDeleteTextures(1, &tex);
1738     delete[] m_src_data;
1739     delete prog;
1740 }
1741 
PixelStorageModesTests(deqp::Context & context,glu::GLSLVersion glsl_version)1742 PixelStorageModesTests::PixelStorageModesTests(deqp::Context &context, glu::GLSLVersion glsl_version)
1743     : TestCaseGroup(context, "pixelstoragemodes", "Pixel Storage Modes Tests")
1744     , m_glsl_version(glsl_version)
1745 {
1746 }
1747 
~PixelStorageModesTests(void)1748 PixelStorageModesTests::~PixelStorageModesTests(void)
1749 {
1750 }
1751 
init(void)1752 void PixelStorageModesTests::init(void)
1753 {
1754     const int cuboid_w    = 64;
1755     const int cuboid_h    = 64;
1756     const int cuboid_d    = 64;
1757     const int subcuboid_w = 32;
1758     const int subcuboid_h = 32;
1759     const int subcuboid_d = 8;
1760 
1761     struct
1762     {
1763         const char *name;
1764         uint32_t internalFmt;
1765     } internalFmts[] = {
1766         {
1767             "r8",
1768             GL_R8,
1769         },
1770         {
1771             "r8snorm",
1772             GL_R8_SNORM,
1773         },
1774         {
1775             "r16f",
1776             GL_R16F,
1777         },
1778         {
1779             "r32f",
1780             GL_R32F,
1781         },
1782         {
1783             "r8ui",
1784             GL_R8UI,
1785         },
1786         {
1787             "r8i",
1788             GL_R8I,
1789         },
1790         {
1791             "r16ui",
1792             GL_R16UI,
1793         },
1794         {
1795             "r16i",
1796             GL_R16I,
1797         },
1798         {
1799             "r32ui",
1800             GL_R32UI,
1801         },
1802         {
1803             "r32i",
1804             GL_R32I,
1805         },
1806         {
1807             "rg8",
1808             GL_RG8,
1809         },
1810         {
1811             "rg8snorm",
1812             GL_RG8_SNORM,
1813         },
1814         {
1815             "rg16f",
1816             GL_RG16F,
1817         },
1818         {
1819             "rg32f",
1820             GL_RG32F,
1821         },
1822         {
1823             "rg8ui",
1824             GL_RG8UI,
1825         },
1826         {
1827             "rg8i",
1828             GL_RG8I,
1829         },
1830         {
1831             "rg16ui",
1832             GL_RG16UI,
1833         },
1834         {
1835             "rg16i",
1836             GL_RG16I,
1837         },
1838         {
1839             "rg32ui",
1840             GL_RG32UI,
1841         },
1842         {
1843             "rg32i",
1844             GL_RG32I,
1845         },
1846         {
1847             "rgb8",
1848             GL_RGB8,
1849         },
1850         {
1851             "rgb565",
1852             GL_RGB565,
1853         },
1854         {
1855             "rgb8snorm",
1856             GL_RGB8_SNORM,
1857         },
1858         {
1859             "r11g11b10f",
1860             GL_R11F_G11F_B10F,
1861         },
1862         {
1863             "rgb16f",
1864             GL_RGB16F,
1865         },
1866         {
1867             "rgb32f",
1868             GL_RGB32F,
1869         },
1870         {
1871             "rgb8ui",
1872             GL_RGB8UI,
1873         },
1874         {
1875             "rgb8i",
1876             GL_RGB8I,
1877         },
1878         {
1879             "rgb16ui",
1880             GL_RGB16UI,
1881         },
1882         {
1883             "rgb16i",
1884             GL_RGB16I,
1885         },
1886         {
1887             "rgb32ui",
1888             GL_RGB32UI,
1889         },
1890         {
1891             "rgb32i",
1892             GL_RGB32I,
1893         },
1894         {
1895             "rgba8",
1896             GL_RGBA8,
1897         },
1898         {
1899             "rgba8snorm",
1900             GL_RGBA8_SNORM,
1901         },
1902         {
1903             "rgb5a1",
1904             GL_RGB5_A1,
1905         },
1906         {
1907             "rgba4",
1908             GL_RGBA4,
1909         },
1910         {
1911             "rgb10a2",
1912             GL_RGB10_A2,
1913         },
1914         {
1915             "rgba16f",
1916             GL_RGBA16F,
1917         },
1918         {
1919             "rgba32f",
1920             GL_RGBA32F,
1921         },
1922         {
1923             "rgba8ui",
1924             GL_RGBA8UI,
1925         },
1926         {
1927             "rgba8i",
1928             GL_RGBA8I,
1929         },
1930         {
1931             "rgb10a2ui",
1932             GL_RGB10_A2UI,
1933         },
1934         {
1935             "rgba16ui",
1936             GL_RGBA16UI,
1937         },
1938         {
1939             "rgba16i",
1940             GL_RGBA16I,
1941         },
1942         {
1943             "rgba32i",
1944             GL_RGBA32I,
1945         },
1946         {
1947             "rgba32ui",
1948             GL_RGBA32UI,
1949         },
1950     };
1951 
1952     struct
1953     {
1954         const char *name;
1955         uint32_t internalFmt;
1956         int bw;
1957         int bh;
1958         int bd;
1959     } internalFmts_compressed[] = {
1960         {"rgb_s3tc_dxt1", GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 1},
1961         {"rgba_astc_8x5", GL_COMPRESSED_RGBA_ASTC_8x5_KHR, 8, 5, 1},
1962     };
1963 
1964     tcu::TestCaseGroup *texImage2DGroup = new tcu::TestCaseGroup(m_testCtx, "teximage2d", "glTexImage2D cases");
1965     addChild(texImage2DGroup);
1966 
1967     for (int fmts = 0; fmts < DE_LENGTH_OF_ARRAY(internalFmts); fmts++)
1968     {
1969         tcu::TestCaseGroup *formatsGroup = new tcu::TestCaseGroup(m_testCtx, internalFmts[fmts].name, "");
1970         texImage2DGroup->addChild(formatsGroup);
1971         int bw             = 1;
1972         int bh             = 1;
1973         int skip_pixels[3] = {0, bw, bw * (subcuboid_w / (2 * bw))};
1974         int skip_rows[3]   = {0, bh, bh * (subcuboid_h / (2 * bh))};
1975 
1976         for (int r = 0; r < 3; r++)
1977         {
1978             for (int p = r; p < 3; p++)
1979             {
1980                 std::string skip_name = std::to_string(skip_pixels[p]) + "_" + std::to_string(skip_rows[r]);
1981                 std::string skip_desc =
1982                     "Skip " + std::to_string(skip_pixels[p]) + " pixels and " + std::to_string(skip_rows[r]) + " rows";
1983                 formatsGroup->addChild(new TexImage2DCase(
1984                     m_context, skip_name.c_str(), skip_desc.c_str(), internalFmts[fmts].internalFmt, cuboid_w, cuboid_h,
1985                     skip_pixels[p], skip_rows[r], subcuboid_w, subcuboid_h, m_glsl_version));
1986             }
1987         }
1988     }
1989 
1990     tcu::TestCaseGroup *texImage3DGroup = new tcu::TestCaseGroup(m_testCtx, "teximage3d", "glTexImage3D cases");
1991     addChild(texImage3DGroup);
1992 
1993     for (int fmts = 0; fmts < DE_LENGTH_OF_ARRAY(internalFmts); fmts++)
1994     {
1995         tcu::TestCaseGroup *formatsGroup = new tcu::TestCaseGroup(m_testCtx, internalFmts[fmts].name, "");
1996         texImage3DGroup->addChild(formatsGroup);
1997         int bw             = 1;
1998         int bh             = 1;
1999         int bd             = 1;
2000         int skip_pixels[3] = {0, bw, bw * (subcuboid_w / (2 * bw))};
2001         int skip_rows[3]   = {0, bh, bh * (subcuboid_h / (2 * bh))};
2002         int skip_images[3] = {0, bd, bd * (subcuboid_d / (2 * bd))};
2003 
2004         for (int i = 0; i < 3; i++)
2005         {
2006             for (int r = i; r < 3; r++)
2007             {
2008                 for (int p = r; p < 3; p++)
2009                 {
2010                     std::string skip_name = std::to_string(skip_pixels[p]) + "_" + std::to_string(skip_rows[r]) + "_" +
2011                                             std::to_string(skip_images[i]);
2012                     std::string skip_desc = "Skip " + std::to_string(skip_pixels[p]) + " pixels, " +
2013                                             std::to_string(skip_rows[r]) + " rows, and " +
2014                                             std::to_string(skip_images[i]) + " images";
2015                     formatsGroup->addChild(new TexImage3DCase(m_context, skip_name.c_str(), skip_desc.c_str(),
2016                                                               internalFmts[fmts].internalFmt, cuboid_w, cuboid_h,
2017                                                               cuboid_d, skip_pixels[p], skip_rows[r], skip_images[i],
2018                                                               subcuboid_w, subcuboid_h, subcuboid_d, m_glsl_version));
2019                 }
2020             }
2021         }
2022     }
2023 
2024     if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
2025     {
2026         tcu::TestCaseGroup *compressedTexImage2DGroup =
2027             new tcu::TestCaseGroup(m_testCtx, "compressedteximage2d", "glCompressedTexImage2D cases");
2028         addChild(compressedTexImage2DGroup);
2029 
2030         for (int fmts = 0; fmts < DE_LENGTH_OF_ARRAY(internalFmts_compressed); fmts++)
2031         {
2032             tcu::TestCaseGroup *formatsGroup =
2033                 new tcu::TestCaseGroup(m_testCtx, internalFmts_compressed[fmts].name, "");
2034             compressedTexImage2DGroup->addChild(formatsGroup);
2035             int bw             = internalFmts_compressed[fmts].bw;
2036             int bh             = internalFmts_compressed[fmts].bh;
2037             int skip_pixels[4] = {0, bw, bw * (subcuboid_w / (2 * bw)), bw * (subcuboid_w / bw)};
2038             int skip_rows[4]   = {0, bh, bh * (subcuboid_h / (2 * bh)), bh * (subcuboid_h / bh)};
2039             for (int r = 0; r < 4; r++)
2040             {
2041                 for (int p = 0; p < 4; p++)
2042                 {
2043                     std::string skip_name = std::to_string(skip_pixels[p]) + "_" + std::to_string(skip_rows[r]);
2044                     std::string skip_desc = "Skip " + std::to_string(skip_pixels[p]) + " pixels and " +
2045                                             std::to_string(skip_rows[r]) + " rows";
2046                     formatsGroup->addChild(new CompressedTexImage2DCase(
2047                         m_context, skip_name.c_str(), skip_desc.c_str(), internalFmts_compressed[fmts].internalFmt,
2048                         cuboid_w, cuboid_h, skip_pixels[p], skip_rows[r], subcuboid_w, subcuboid_h, m_glsl_version));
2049                 }
2050             }
2051         }
2052 
2053         tcu::TestCaseGroup *compressedTexImage3DGroup =
2054             new tcu::TestCaseGroup(m_testCtx, "compressedteximage3d", "glCompressedTexImage3D cases");
2055         addChild(compressedTexImage3DGroup);
2056 
2057         for (int fmts = 0; fmts < DE_LENGTH_OF_ARRAY(internalFmts_compressed); fmts++)
2058         {
2059             tcu::TestCaseGroup *formatsGroup =
2060                 new tcu::TestCaseGroup(m_testCtx, internalFmts_compressed[fmts].name, "");
2061             compressedTexImage3DGroup->addChild(formatsGroup);
2062             int bw             = internalFmts_compressed[fmts].bw;
2063             int bh             = internalFmts_compressed[fmts].bh;
2064             int bd             = internalFmts_compressed[fmts].bd;
2065             int skip_pixels[4] = {0, bw, bw * (subcuboid_w / (2 * bw)), bw * (subcuboid_w / bw)};
2066             int skip_rows[4]   = {0, bh, bh * (subcuboid_h / (2 * bh)), bh * (subcuboid_h / bh)};
2067             int skip_images[4] = {0, bd, bd * (subcuboid_d / (2 * bd)), bd * (subcuboid_d / bd)};
2068             for (int i = 0; i < 4; i++)
2069             {
2070                 for (int r = 0; r < 4; r++)
2071                 {
2072                     for (int p = 0; p < 4; p++)
2073                     {
2074                         std::string skip_name = std::to_string(skip_pixels[p]) + "_" + std::to_string(skip_rows[r]) +
2075                                                 "_" + std::to_string(skip_images[i]);
2076                         std::string skip_desc = "Skip " + std::to_string(skip_pixels[p]) + " pixels, " +
2077                                                 std::to_string(skip_rows[r]) + " rows, and " +
2078                                                 std::to_string(skip_images[i]) + " images";
2079                         formatsGroup->addChild(new CompressedTexImage3DCase(
2080                             m_context, skip_name.c_str(), skip_desc.c_str(), internalFmts_compressed[fmts].internalFmt,
2081                             cuboid_w, cuboid_h, cuboid_d, skip_pixels[p], skip_rows[r], skip_images[i], subcuboid_w,
2082                             subcuboid_h, subcuboid_d, m_glsl_version));
2083                     }
2084                 }
2085             }
2086         }
2087     }
2088 }
2089 
2090 } /* namespace glcts */
2091