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