1 /*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
5 * Copyright (c) 2015-2016 The Khronos Group Inc.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
22 */ /*-------------------------------------------------------------------*/
25 * \file gl3TextureSwizzleTests.cpp
26 * \brief Implements conformance tests for "Texture Swizzle" functionality.
27 */ /*-------------------------------------------------------------------*/
29 #include "gl3cTextureSwizzleTests.hpp"
30 #include "gluContextInfo.hpp"
31 #include "gluStrUtil.hpp"
32 #include "glwFunctions.hpp"
33 #include "tcuFloat.hpp"
34 #include "tcuTestLog.hpp"
39 #define ENABLE_DEBUG 0 /* Selects if debug callback is installed */
40 #define FUNCTIONAL_TEST_ALL_FORMATS 1 /* Selects if all formats should be tested */
41 #define FUNCTIONAL_TEST_ALL_TARGETS 1 /* Selects if all targets should be tested */
42 #define FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES 0 /* Selects if all texture access routines should be tested */
43 #define FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS 0 /* Selects if all swizzle combinations should be tested */
47 namespace TextureSwizzle
49 /* Static constants use by tests */
51 static const glw::GLhalf data_float16_one[] = { tcu::Float16(1.0).bits() };
52 static const glw::GLhalf data_float16_zero[] = { tcu::Float16(0.0).bits() };
53 static const glw::GLfloat data_float32_one[] = { 1.0f };
54 static const glw::GLfloat data_float32_zero[] = { 0.0f };
55 static const glw::GLbyte data_snorm8_zero[] = { 0 };
56 static const glw::GLbyte data_snorm8_one[] = { 127 };
57 static const glw::GLshort data_snorm16_one[] = { 32767 };
58 static const glw::GLshort data_snorm16_zero[] = { 0 };
59 static const glw::GLubyte data_unorm8_one[] = { 255 };
60 static const glw::GLubyte data_unorm8_zero[] = { 0 };
61 static const glw::GLushort data_unorm16_one[] = { 65535 };
62 static const glw::GLushort data_unorm16_zero[] = { 0 };
63 static const glw::GLbyte data_sint8_zero[] = { 0 };
64 static const glw::GLbyte data_sint8_one[] = { 1 };
65 static const glw::GLshort data_sint16_one[] = { 1 };
66 static const glw::GLshort data_sint16_zero[] = { 0 };
67 static const glw::GLint data_sint32_one[] = { 1 };
68 static const glw::GLint data_sint32_zero[] = { 0 };
69 static const glw::GLubyte data_uint8_one[] = { 1 };
70 static const glw::GLubyte data_uint8_zero[] = { 0 };
71 static const glw::GLushort data_uint16_one[] = { 1 };
72 static const glw::GLushort data_uint16_zero[] = { 0 };
73 static const glw::GLuint data_uint32_one[] = { 1 };
74 static const glw::GLuint data_uint32_zero[] = { 0 };
76 /* Source and expected data */
77 static const glw::GLubyte src_data_r8[] = { 123 };
78 static const glw::GLbyte src_data_r8_snorm[] = { -123 };
79 static const glw::GLushort src_data_r16[] = { 12345 };
80 static const glw::GLshort src_data_r16_snorm[] = { -12345 };
81 static const glw::GLubyte src_data_rg8[] = { 123, 231 };
82 static const glw::GLbyte src_data_rg8_snorm[] = { -123, -23 };
83 static const glw::GLushort src_data_rg16[] = { 12345, 54321 };
84 static const glw::GLshort src_data_rg16_snorm[] = { -12345, -23451 };
85 static const glw::GLubyte src_data_r3_g3_b2[] = { 236 }; /* 255, 109, 0 */
86 static const glw::GLushort src_data_rgb4[] = { 64832 }; /* 5_6_5: 255, 170, 0 */
87 static const glw::GLushort src_data_rgb5[] = { 64832 };
88 static const glw::GLubyte src_data_rgb8[] = { 3, 2, 1 };
89 static const glw::GLbyte src_data_rgb8_snorm[] = { -1, -2, -3 };
90 static const glw::GLushort src_data_rgb16[] = { 65535, 32767, 16383 };
91 static const glw::GLshort src_data_rgb16_snorm[] = { -32767, -16383, -8191 };
92 static const glw::GLushort src_data_rgba4[] = { 64005 }; /* 255, 170, 0, 85 */
93 static const glw::GLushort src_data_rgb5_a1[] = { 64852 };
94 static const glw::GLubyte src_data_rgba8[] = { 0, 64, 128, 255 };
95 static const glw::GLbyte src_data_rgba8_snorm[] = { -127, -63, -32, -16 };
96 static const glw::GLuint src_data_rgb10_a2[] = { 4291823615u };
97 static const glw::GLushort exp_data_rgb10_a2ui[] = { 1023, 256, 511, 3 };
98 static const glw::GLushort src_data_rgba16[] = { 65535, 32767, 16383, 8191 };
99 static const glw::GLshort src_data_rgba16_snorm[] = { -32767, -16383, -8191, -4091 };
100 static const glw::GLubyte exp_data_srgb8_alpha8[] = { 13, 1, 255, 32 }; /* See 4.5 core 8.24 */
101 static const glw::GLubyte src_data_srgb8_alpha8[] = { 64, 8, 255, 32 };
102 static const glw::GLhalf src_data_r16f[] = { tcu::Float16(1.0).bits() };
103 static const glw::GLhalf src_data_rg16f[] = { tcu::Float16(1.0).bits(), tcu::Float16(-1.0).bits() };
104 static const glw::GLhalf src_data_rgb16f[] = { tcu::Float16(1.0).bits(), tcu::Float16(-1.0).bits(),
105 tcu::Float16(2.0).bits() };
106 static const glw::GLhalf src_data_rgba16f[] = { tcu::Float16(1.0).bits(), tcu::Float16(-1.0).bits(),
107 tcu::Float16(2.0).bits(), tcu::Float16(-2.0).bits() };
108 static const glw::GLfloat src_data_r32f[] = { 1.0f };
109 static const glw::GLfloat src_data_rg32f[] = { 1.0f, -1.0f };
110 static const glw::GLfloat src_data_rgb32f[] = { 1.0f, -1.0f, 2.0f };
111 static const glw::GLfloat src_data_rgba32f[] = { 1.0f, -1.0f, 2.0f, -2.0f };
113 static const tcu::Float<deUint32, 5, 6, 15, tcu::FLOAT_SUPPORT_DENORM> r11f(0.5);
114 static const tcu::Float<deUint32, 5, 6, 15, tcu::FLOAT_SUPPORT_DENORM> g11f(0.75);
115 static const tcu::Float<deUint32, 5, 5, 15, tcu::FLOAT_SUPPORT_DENORM> b10f(0.25);
117 static const glw::GLhalf exp_data_r11f_g11f_b10f[] = { tcu::Float16(0.5).bits(), tcu::Float16(0.75).bits(),
118 tcu::Float16(0.25).bits() };
119 static const glw::GLuint src_data_r11f_g11f_b10f[] = { (r11f.bits()) | (g11f.bits() << 11) | (b10f.bits() << 22) };
120 static const glw::GLfloat exp_data_rgb9_e5[] = { 31.0f, 23.0f, 32.0f };
121 static const glw::GLuint src_data_rgb9_e5[] = { 2885775608u };
122 static const glw::GLbyte src_data_r8i[] = { -127 };
123 static const glw::GLubyte src_data_r8ui[] = { 128 };
124 static const glw::GLshort src_data_r16i[] = { -32767 };
125 static const glw::GLushort src_data_r16ui[] = { 32768 };
126 static const glw::GLint src_data_r32i[] = { -1 };
127 static const glw::GLuint src_data_r32ui[] = { 1 };
128 static const glw::GLbyte src_data_rg8i[] = { -127, -126 };
129 static const glw::GLubyte src_data_rg8ui[] = { 128, 129 };
130 static const glw::GLshort src_data_rg16i[] = { -32767, -32766 };
131 static const glw::GLushort src_data_rg16ui[] = { 32768, 32769 };
132 static const glw::GLint src_data_rg32i[] = { -1, -2 };
133 static const glw::GLuint src_data_rg32ui[] = { 1, 2 };
134 static const glw::GLbyte src_data_rgb8i[] = { -127, -126, -125 };
135 static const glw::GLubyte src_data_rgb8ui[] = { 128, 129, 130 };
136 static const glw::GLshort src_data_rgb16i[] = { -32767, -32766, -32765 };
137 static const glw::GLushort src_data_rgb16ui[] = { 32768, 32769, 32770 };
138 static const glw::GLint src_data_rgb32i[] = { -1, -2, -3 };
139 static const glw::GLuint src_data_rgb32ui[] = { 1, 2, 3 };
140 static const glw::GLbyte src_data_rgba8i[] = { -127, -126, -125, -124 };
141 static const glw::GLubyte src_data_rgba8ui[] = { 128, 129, 130, 131 };
142 static const glw::GLshort src_data_rgba16i[] = { -32767, -32766, -32765, -32764 };
143 static const glw::GLushort src_data_rgba16ui[] = { 32768, 32769, 32770, 32771 };
144 static const glw::GLint src_data_rgba32i[] = { -1, -2, -3, -4 };
145 static const glw::GLuint src_data_rgba32ui[] = { 1, 2, 3, 4 };
146 static const glw::GLushort src_data_depth_component16[] = { 32768 };
147 static const glw::GLfloat exp_data_depth_component32[] = { 1.0f };
148 static const glw::GLuint src_data_depth_component32[] = { 4294967295u };
149 static const glw::GLfloat src_data_depth_component32f[] = { 0.75f };
150 static const glw::GLuint src_data_depth24_stencil8[] = { 4294967041u /* 1.0, 1 */ };
151 static const glw::GLuint src_data_depth32f_stencil8[] = { 1065353216, 1 /* 1.0f, 1 */ };
153 /* Texture channels */
154 static const glw::GLchar* channels[] = { "r", "g", "b", "a" };
156 /* Enumerations of cube map faces */
157 static const glw::GLenum cube_map_faces[] = { GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
158 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, GL_TEXTURE_CUBE_MAP_POSITIVE_X,
159 GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Z };
160 static const size_t n_cube_map_faces = sizeof(cube_map_faces) / sizeof(cube_map_faces[0]);
163 static const glw::GLenum states[] = { GL_TEXTURE_SWIZZLE_R, GL_TEXTURE_SWIZZLE_G, GL_TEXTURE_SWIZZLE_B,
164 GL_TEXTURE_SWIZZLE_A };
165 static const size_t n_states = sizeof(states) / sizeof(states[0]);
167 /* Sampler descriptor */
170 const glw::GLchar* m_basic_type;
171 const glw::GLchar* m_sampler_prefix;
173 static const _sampler isampler = { "int", "i" };
174 static const _sampler usampler = { "uint", "u" };
175 static const _sampler sampler = { "float", "" };
177 /* Output channel descriptor */
180 glw::GLenum m_internal_format;
181 const glw::GLvoid* m_expected_data;
184 /* Output channel descriptors for one and zero */
185 static const _out_ch_desc zero_ch = { GL_ZERO, 0 };
186 static const _out_ch_desc one_ch = { GL_ONE, 0 };
187 static const _out_ch_desc float16_zero = { GL_R16F, data_float16_zero };
188 static const _out_ch_desc float16_one = { GL_R16F, data_float16_one };
189 static const _out_ch_desc float32_zero = { GL_R32F, data_float32_zero };
190 static const _out_ch_desc float32_one = { GL_R32F, data_float32_one };
191 static const _out_ch_desc sint8_zero = { GL_R8I, data_sint8_zero };
192 static const _out_ch_desc sint8_one = { GL_R8I, data_sint8_one };
193 static const _out_ch_desc sint16_zero = { GL_R16I, data_sint16_zero };
194 static const _out_ch_desc sint16_one = { GL_R16I, data_sint16_one };
195 static const _out_ch_desc sint32_zero = { GL_R32I, data_sint32_zero };
196 static const _out_ch_desc sint32_one = { GL_R32I, data_sint32_one };
197 static const _out_ch_desc snorm8_zero = { GL_R8_SNORM, data_snorm8_zero };
198 static const _out_ch_desc snorm8_one = { GL_R8_SNORM, data_snorm8_one };
199 static const _out_ch_desc snorm16_zero = { GL_R16_SNORM, data_snorm16_zero };
200 static const _out_ch_desc snorm16_one = { GL_R16_SNORM, data_snorm16_one };
201 static const _out_ch_desc uint8_zero = { GL_R8UI, data_uint8_zero };
202 static const _out_ch_desc uint8_one = { GL_R8UI, data_uint8_one };
203 static const _out_ch_desc uint16_zero = { GL_R16UI, data_uint16_zero };
204 static const _out_ch_desc uint16_one = { GL_R16UI, data_uint16_one };
205 static const _out_ch_desc uint32_zero = { GL_R32UI, data_uint32_zero };
206 static const _out_ch_desc uint32_one = { GL_R32UI, data_uint32_one };
207 static const _out_ch_desc unorm8_zero = { GL_R8, data_unorm8_zero };
208 static const _out_ch_desc unorm8_one = { GL_R8, data_unorm8_one };
209 static const _out_ch_desc unorm16_zero = { GL_R16, data_unorm16_zero };
210 static const _out_ch_desc unorm16_one = { GL_R16, data_unorm16_one };
212 /* Texture format descriptor. Maps texture format with output channel descriptors, source data and sampler descriptor */
213 struct _texture_format
215 const glu::ApiType m_minimum_gl_context;
216 glw::GLenum m_internal_format;
217 glw::GLenum m_format;
219 glw::GLenum m_ds_mode;
220 const _sampler& m_sampler;
221 _out_ch_desc m_red_ch;
222 _out_ch_desc m_green_ch;
223 _out_ch_desc m_blue_ch;
224 _out_ch_desc m_alpha_ch;
225 const glw::GLvoid* m_source_data;
226 const _out_ch_desc& m_zero_ch;
227 const _out_ch_desc& m_one_ch;
229 static const _texture_format texture_formats[] = {
230 /* 0 */ { glu::ApiType::core(3, 0),
243 { glu::ApiType::core(3, 1),
249 { GL_R8_SNORM, DE_NULL },
256 { glu::ApiType::core(3, 0),
269 { glu::ApiType::core(3, 1),
275 { GL_R16_SNORM, DE_NULL },
282 { glu::ApiType::core(3, 0),
295 { glu::ApiType::core(3, 1),
301 { GL_R8_SNORM, DE_NULL },
302 { GL_R8_SNORM, DE_NULL },
308 { glu::ApiType::core(3, 0),
321 { glu::ApiType::core(3, 1),
327 { GL_R16_SNORM, DE_NULL },
328 { GL_R16_SNORM, DE_NULL },
334 /* 8 */ { glu::ApiType::core(4, 4),
337 GL_UNSIGNED_BYTE_3_3_2,
347 { glu::ApiType::core(4, 4),
350 GL_UNSIGNED_SHORT_5_6_5,
360 { glu::ApiType::core(4, 4),
363 GL_UNSIGNED_SHORT_5_6_5,
373 { glu::ApiType::core(3, 0),
386 { glu::ApiType::core(3, 1),
392 { GL_R8_SNORM, DE_NULL },
393 { GL_R8_SNORM, DE_NULL },
394 { GL_R8_SNORM, DE_NULL },
399 { glu::ApiType::core(4, 4),
412 { glu::ApiType::core(4, 4),
425 { glu::ApiType::core(3, 0),
438 /* 16 */ { glu::ApiType::core(3, 1),
444 { GL_R16_SNORM, DE_NULL },
445 { GL_R16_SNORM, DE_NULL },
446 { GL_R16_SNORM, DE_NULL },
448 src_data_rgb16_snorm,
451 { glu::ApiType::core(4, 4),
454 GL_UNSIGNED_SHORT_4_4_4_4,
464 { glu::ApiType::core(4, 2),
467 GL_UNSIGNED_SHORT_4_4_4_4,
477 { glu::ApiType::core(4, 2),
480 GL_UNSIGNED_SHORT_5_5_5_1,
490 { glu::ApiType::core(3, 0),
503 { glu::ApiType::core(3, 1),
509 { GL_R8_SNORM, DE_NULL },
510 { GL_R8_SNORM, DE_NULL },
511 { GL_R8_SNORM, DE_NULL },
512 { GL_R8_SNORM, DE_NULL },
513 src_data_rgba8_snorm,
516 { glu::ApiType::core(3, 0),
519 GL_UNSIGNED_INT_10_10_10_2,
529 { glu::ApiType::core(3, 3),
532 GL_UNSIGNED_INT_10_10_10_2,
535 { GL_R16UI, exp_data_rgb10_a2ui + 0 },
536 { GL_R16UI, exp_data_rgb10_a2ui + 1 },
537 { GL_R16UI, exp_data_rgb10_a2ui + 2 },
538 { GL_R16UI, exp_data_rgb10_a2ui + 3 },
542 /* 24 */ { glu::ApiType::core(4, 4),
555 { glu::ApiType::core(3, 0),
568 { glu::ApiType::core(3, 1),
574 { GL_R16_SNORM, DE_NULL },
575 { GL_R16_SNORM, DE_NULL },
576 { GL_R16_SNORM, DE_NULL },
577 { GL_R16_SNORM, src_data_rgba16_snorm + 3 },
578 src_data_rgba16_snorm,
581 { glu::ApiType::core(3, 0),
587 { GL_R8, exp_data_srgb8_alpha8 + 0 },
588 { GL_R8, exp_data_srgb8_alpha8 + 1 },
589 { GL_R8, exp_data_srgb8_alpha8 + 2 },
591 src_data_srgb8_alpha8,
594 { glu::ApiType::core(3, 0),
600 { GL_R8, exp_data_srgb8_alpha8 + 0 },
601 { GL_R8, exp_data_srgb8_alpha8 + 1 },
602 { GL_R8, exp_data_srgb8_alpha8 + 2 },
603 { GL_R8, exp_data_srgb8_alpha8 + 3 },
604 src_data_srgb8_alpha8,
607 { glu::ApiType::core(3, 0),
613 { GL_R16F, src_data_r16f + 0 },
620 { glu::ApiType::core(3, 0),
626 { GL_R16F, src_data_rg16f + 0 },
627 { GL_R16F, src_data_rg16f + 1 },
633 { glu::ApiType::core(3, 0),
639 { GL_R16F, src_data_rgb16f + 0 },
640 { GL_R16F, src_data_rgb16f + 1 },
641 { GL_R16F, src_data_rgb16f + 2 },
646 /* 32 */ { glu::ApiType::core(3, 0),
652 { GL_R16F, src_data_rgba16f + 0 },
653 { GL_R16F, src_data_rgba16f + 1 },
654 { GL_R16F, src_data_rgba16f + 2 },
655 { GL_R16F, src_data_rgba16f + 3 },
659 { glu::ApiType::core(3, 0),
665 { GL_R32F, src_data_r32f + 0 },
672 { glu::ApiType::core(3, 0),
678 { GL_R32F, src_data_rg32f + 0 },
679 { GL_R32F, src_data_rg32f + 1 },
685 { glu::ApiType::core(3, 0),
691 { GL_R32F, src_data_rgb32f + 0 },
692 { GL_R32F, src_data_rgb32f + 1 },
693 { GL_R32F, src_data_rgb32f + 2 },
698 { glu::ApiType::core(3, 0),
704 { GL_R32F, src_data_rgba32f + 0 },
705 { GL_R32F, src_data_rgba32f + 1 },
706 { GL_R32F, src_data_rgba32f + 2 },
707 { GL_R32F, src_data_rgba32f + 3 },
711 { glu::ApiType::core(3, 0),
714 GL_UNSIGNED_INT_10F_11F_11F_REV,
717 { GL_R16F, exp_data_r11f_g11f_b10f + 0 },
718 { GL_R16F, exp_data_r11f_g11f_b10f + 1 },
719 { GL_R16F, exp_data_r11f_g11f_b10f + 2 },
721 src_data_r11f_g11f_b10f,
724 { glu::ApiType::core(3, 0),
727 GL_UNSIGNED_INT_5_9_9_9_REV,
730 { GL_R32F, exp_data_rgb9_e5 + 0 },
731 { GL_R32F, exp_data_rgb9_e5 + 1 },
732 { GL_R32F, exp_data_rgb9_e5 + 2 },
737 { glu::ApiType::core(3, 0),
743 { GL_R8I, src_data_r8i },
750 /* 40 */ { glu::ApiType::core(3, 0),
756 { GL_R8UI, src_data_r8ui },
763 { glu::ApiType::core(3, 0),
769 { GL_R16I, src_data_r16i },
776 { glu::ApiType::core(3, 0),
782 { GL_R16UI, src_data_r16ui },
789 { glu::ApiType::core(3, 0),
795 { GL_R32I, src_data_r32i },
802 { glu::ApiType::core(3, 0),
808 { GL_R32UI, src_data_r32ui },
815 { glu::ApiType::core(3, 0),
821 { GL_R8I, src_data_rg8i + 0 },
822 { GL_R8I, src_data_rg8i + 1 },
828 { glu::ApiType::core(3, 0),
834 { GL_R8UI, src_data_rg8ui + 0 },
835 { GL_R8UI, src_data_rg8ui + 1 },
841 { glu::ApiType::core(3, 0),
847 { GL_R16I, src_data_rg16i + 0 },
848 { GL_R16I, src_data_rg16i + 1 },
854 /* 48 */ { glu::ApiType::core(3, 0),
860 { GL_R16UI, src_data_rg16ui + 0 },
861 { GL_R16UI, src_data_rg16ui + 1 },
867 { glu::ApiType::core(3, 0),
873 { GL_R32I, src_data_rg32i + 0 },
874 { GL_R32I, src_data_rg32i + 1 },
880 { glu::ApiType::core(3, 0),
886 { GL_R32UI, src_data_rg32ui + 0 },
887 { GL_R32UI, src_data_rg32ui + 1 },
893 { glu::ApiType::core(3, 0),
899 { GL_R8I, src_data_rgb8i + 0 },
900 { GL_R8I, src_data_rgb8i + 1 },
901 { GL_R8I, src_data_rgb8i + 2 },
906 { glu::ApiType::core(3, 0),
912 { GL_R8UI, src_data_rgb8ui + 0 },
913 { GL_R8UI, src_data_rgb8ui + 1 },
914 { GL_R8UI, src_data_rgb8ui + 2 },
919 { glu::ApiType::core(3, 0),
925 { GL_R16I, src_data_rgb16i + 0 },
926 { GL_R16I, src_data_rgb16i + 1 },
927 { GL_R16I, src_data_rgb16i + 2 },
932 { glu::ApiType::core(3, 0),
938 { GL_R16UI, src_data_rgb16ui + 0 },
939 { GL_R16UI, src_data_rgb16ui + 1 },
940 { GL_R16UI, src_data_rgb16ui + 2 },
945 { glu::ApiType::core(3, 0),
951 { GL_R32I, src_data_rgb32i + 0 },
952 { GL_R32I, src_data_rgb32i + 1 },
953 { GL_R32I, src_data_rgb32i + 2 },
958 /* 56 */ { glu::ApiType::core(3, 0),
964 { GL_R32UI, src_data_rgb32ui + 0 },
965 { GL_R32UI, src_data_rgb32ui + 1 },
966 { GL_R32UI, src_data_rgb32ui + 2 },
971 { glu::ApiType::core(3, 0),
977 { GL_R8I, src_data_rgba8i + 0 },
978 { GL_R8I, src_data_rgba8i + 1 },
979 { GL_R8I, src_data_rgba8i + 2 },
980 { GL_R8I, src_data_rgba8i + 3 },
984 { glu::ApiType::core(3, 0),
990 { GL_R8UI, src_data_rgba8ui + 0 },
991 { GL_R8UI, src_data_rgba8ui + 1 },
992 { GL_R8UI, src_data_rgba8ui + 2 },
993 { GL_R8UI, src_data_rgba8ui + 3 },
997 { glu::ApiType::core(3, 0),
1003 { GL_R16I, src_data_rgba16i + 0 },
1004 { GL_R16I, src_data_rgba16i + 1 },
1005 { GL_R16I, src_data_rgba16i + 2 },
1006 { GL_R16I, src_data_rgba16i + 3 },
1010 { glu::ApiType::core(3, 0),
1016 { GL_R16UI, src_data_rgba16ui + 0 },
1017 { GL_R16UI, src_data_rgba16ui + 1 },
1018 { GL_R16UI, src_data_rgba16ui + 2 },
1019 { GL_R16UI, src_data_rgba16ui + 3 },
1023 { glu::ApiType::core(3, 0),
1029 { GL_R32I, src_data_rgba32i + 0 },
1030 { GL_R32I, src_data_rgba32i + 1 },
1031 { GL_R32I, src_data_rgba32i + 2 },
1032 { GL_R32I, src_data_rgba32i + 3 },
1036 { glu::ApiType::core(3, 0),
1042 { GL_R32UI, src_data_rgba32ui + 0 },
1043 { GL_R32UI, src_data_rgba32ui + 1 },
1044 { GL_R32UI, src_data_rgba32ui + 2 },
1045 { GL_R32UI, src_data_rgba32ui + 3 },
1049 { glu::ApiType::core(3, 0),
1050 GL_DEPTH_COMPONENT16,
1055 { GL_R16, src_data_depth_component16 },
1059 src_data_depth_component16,
1062 /* 64 */ { glu::ApiType::core(3, 0),
1063 GL_DEPTH_COMPONENT24,
1068 { GL_R32F, exp_data_depth_component32 },
1072 src_data_depth_component32,
1075 { glu::ApiType::core(3, 0),
1076 GL_DEPTH_COMPONENT32,
1081 { GL_R32F, exp_data_depth_component32 },
1085 src_data_depth_component32,
1088 { glu::ApiType::core(3, 0),
1089 GL_DEPTH_COMPONENT32F,
1094 { GL_R32F, src_data_depth_component32f },
1098 src_data_depth_component32f,
1101 { glu::ApiType::core(3, 0),
1102 GL_DEPTH24_STENCIL8,
1104 GL_UNSIGNED_INT_24_8,
1107 { GL_R32F, exp_data_depth_component32 },
1111 src_data_depth24_stencil8,
1114 { glu::ApiType::core(3, 0),
1115 GL_DEPTH32F_STENCIL8,
1117 GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
1120 { GL_R32F, exp_data_depth_component32 },
1124 src_data_depth32f_stencil8,
1127 { glu::ApiType::core(4, 3), GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_STENCIL_INDEX, usampler,
1128 one_ch, zero_ch, zero_ch, one_ch, src_data_depth24_stencil8, uint8_zero, uint8_one },
1129 { glu::ApiType::core(4, 3), GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
1130 GL_STENCIL_INDEX, usampler, one_ch, zero_ch, zero_ch, one_ch, src_data_depth32f_stencil8, uint8_zero, uint8_one }
1132 static const size_t n_texture_formats = sizeof(texture_formats) / sizeof(texture_formats[0]);
1134 /* Texture access routine descriptors */
1135 struct _texture_access
1137 const glw::GLchar* m_name;
1138 size_t m_n_coordinates;
1139 bool m_use_derivaties;
1140 bool m_use_integral_coordinates;
1143 bool m_support_multisampling;
1145 static const _texture_access texture_access[] = { { "texture", 0, false, false, false, false, false },
1146 { "textureProj", 1, false, false, false, false, false },
1147 { "textureLod", 0, false, false, true, false, false },
1148 { "textureOffset", 0, false, false, false, true, false },
1149 { "texelFetch", 0, false, true, true, false, true },
1150 { "texelFetchOffset", 0, false, true, true, true, false },
1151 { "textureProjOffset", 1, false, false, false, true, false },
1152 { "textureLodOffset", 0, false, false, true, true, false },
1153 { "textureProjLod", 1, false, false, true, false, false },
1154 { "textureProjLodOffset", 1, false, false, true, true, false },
1155 { "textureGrad", 0, true, false, false, false, false },
1156 { "textureGradOffset", 0, true, false, false, true, false },
1157 { "textureProjGrad", 1, true, false, false, false, false },
1158 { "textureProjGradOffset", 1, true, false, false, true, false } };
1159 static const size_t n_texture_access = sizeof(texture_access) / sizeof(texture_access[0]);
1161 /* Texture target descriptor */
1162 struct _texture_target
1164 size_t m_n_array_coordinates;
1165 size_t m_n_coordinates;
1166 size_t m_n_derivatives;
1167 const glw::GLchar* m_sampler_type;
1168 bool m_support_integral_coordinates;
1170 bool m_support_offset;
1171 bool m_supports_proj;
1172 bool m_require_multisampling;
1173 glw::GLenum m_target;
1176 static const _texture_target texture_targets[] = {
1177 { 0, 1, 1, "1D", true, true, true, true, false, GL_TEXTURE_1D },
1178 { 0, 2, 2, "2D", true, true, true, true, false, GL_TEXTURE_2D },
1179 { 0, 3, 3, "3D", true, true, true, true, false, GL_TEXTURE_3D },
1180 { 1, 1, 1, "1DArray", true, true, true, false, false, GL_TEXTURE_1D_ARRAY },
1181 { 1, 2, 2, "2DArray", true, true, true, false, false, GL_TEXTURE_2D_ARRAY },
1182 { 0, 2, 2, "2DRect", true, false, true, true, false, GL_TEXTURE_RECTANGLE },
1183 { 0, 3, 3, "Cube", false, true, false, false, false, GL_TEXTURE_CUBE_MAP },
1184 { 0, 2, 2, "2DMS", true, false, true, true, true, GL_TEXTURE_2D_MULTISAMPLE },
1185 { 1, 2, 2, "2DMSArray", true, false, true, true, true, GL_TEXTURE_2D_MULTISAMPLE_ARRAY },
1187 static const size_t n_texture_targets = sizeof(texture_targets) / sizeof(texture_targets[0]);
1189 /* Swizzle valid values */
1190 static const glw::GLint valid_values[] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, GL_ONE, GL_ZERO };
1191 static const size_t n_valid_values = sizeof(valid_values) / sizeof(valid_values[0]);
1194 const _out_ch_desc& get_descriptor_for_channel(const _texture_format& format, const size_t channel);
1198 /** Debuging procedure. Logs parameters.
1200 * @param source As specified in GL spec.
1201 * @param type As specified in GL spec.
1202 * @param id As specified in GL spec.
1203 * @param severity As specified in GL spec.
1205 * @param message As specified in GL spec.
1206 * @param info Pointer to instance of deqp::Context used by test.
1208 void GLW_APIENTRY debug_proc(glw::GLenum source, glw::GLenum type, glw::GLuint id, glw::GLenum severity,
1209 glw::GLsizei /* length */, const glw::GLchar* message, void* info)
1211 Context* ctx = (Context*)info;
1213 const glw::GLchar* source_str = "Unknown";
1214 const glw::GLchar* type_str = "Unknown";
1215 const glw::GLchar* severity_str = "Unknown";
1219 case GL_DEBUG_SOURCE_API:
1222 case GL_DEBUG_SOURCE_APPLICATION:
1225 case GL_DEBUG_SOURCE_OTHER:
1228 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1231 case GL_DEBUG_SOURCE_THIRD_PARTY:
1234 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1243 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1244 type_str = "DEPRECATED_BEHAVIOR";
1246 case GL_DEBUG_TYPE_ERROR:
1249 case GL_DEBUG_TYPE_MARKER:
1250 type_str = "MARKER";
1252 case GL_DEBUG_TYPE_OTHER:
1255 case GL_DEBUG_TYPE_PERFORMANCE:
1256 type_str = "PERFORMANCE";
1258 case GL_DEBUG_TYPE_POP_GROUP:
1259 type_str = "POP_GROUP";
1261 case GL_DEBUG_TYPE_PORTABILITY:
1262 type_str = "PORTABILITY";
1264 case GL_DEBUG_TYPE_PUSH_GROUP:
1265 type_str = "PUSH_GROUP";
1267 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1268 type_str = "UNDEFINED_BEHAVIOR";
1276 case GL_DEBUG_SEVERITY_HIGH:
1279 case GL_DEBUG_SEVERITY_LOW:
1282 case GL_DEBUG_SEVERITY_MEDIUM:
1285 case GL_DEBUG_SEVERITY_NOTIFICATION:
1292 ctx->getTestContext().getLog() << tcu::TestLog::Message << "DEBUG_INFO: " << std::setw(3) << source_str << "|"
1293 << severity_str << "|" << std::setw(18) << type_str << "|" << std::setw(12) << id
1294 << ": " << message << tcu::TestLog::EndMessage;
1297 #endif /* ENABLE_DEBUG */
1299 /** Extracts value of each channel from source data of given format
1301 * @param format_idx Index of format
1302 * @param out_ch_rgba Storage for values
1304 void calculate_values_from_source(size_t format_idx, double out_ch_rgba[4])
1306 const _texture_format& format = texture_formats[format_idx];
1309 double ch_rgba[4] = { 0.0, 0.0, 0.0, 0.0 };
1310 double& ch_r = ch_rgba[0];
1311 double& ch_g = ch_rgba[1];
1312 double& ch_b = ch_rgba[2];
1313 double& ch_a = ch_rgba[3];
1314 size_t n_channels = 0;
1315 bool is_norm = true;
1317 /* Select n_channels and is_norm */
1318 switch (format.m_format)
1320 case GL_RED_INTEGER:
1338 case GL_RGB_INTEGER:
1347 case GL_RGBA_INTEGER:
1357 TCU_FAIL("Unsupported format");
1360 /* Calculate rgba values */
1361 if ((GL_SRGB8 == format.m_internal_format) || (GL_SRGB8_ALPHA8 == format.m_internal_format))
1363 const glw::GLubyte* ptr = (const glw::GLubyte*)src_data_srgb8_alpha8;
1364 const glw::GLubyte r = ptr[0];
1365 const glw::GLubyte g = ptr[1];
1366 const glw::GLubyte b = ptr[2];
1367 const glw::GLubyte a = ptr[3];
1379 else if (GL_UNSIGNED_BYTE_3_3_2 == format.m_type)
1381 const glw::GLubyte* ptr = (const glw::GLubyte*)format.m_source_data;
1382 const glw::GLubyte r = (glw::GLubyte)((*ptr) >> 5);
1383 const glw::GLubyte g = ((*ptr) >> 2) & 7;
1384 const glw::GLubyte b = (*ptr) & 3;
1394 else if (GL_UNSIGNED_SHORT_5_6_5 == format.m_type)
1396 const glw::GLushort* ptr = (const glw::GLushort*)format.m_source_data;
1397 const glw::GLubyte r = (glw::GLubyte)((*ptr) >> 11);
1398 const glw::GLubyte g = (glw::GLubyte)((*ptr) >> 5) & 63;
1399 const glw::GLubyte b = (*ptr) & 31;
1409 else if (GL_UNSIGNED_SHORT_4_4_4_4 == format.m_type)
1411 const glw::GLushort* ptr = (const glw::GLushort*)format.m_source_data;
1412 const glw::GLubyte r = (glw::GLubyte)((*ptr) >> 12);
1413 const glw::GLubyte g = (glw::GLubyte)(((*ptr) >> 8) & 15);
1414 const glw::GLubyte b = (glw::GLubyte)(((*ptr) >> 4) & 15);
1415 const glw::GLubyte a = (glw::GLubyte)((*ptr) & 15);
1427 else if (GL_UNSIGNED_SHORT_5_5_5_1 == format.m_type)
1429 const glw::GLushort* ptr = (const glw::GLushort*)format.m_source_data;
1430 const glw::GLubyte r = (glw::GLubyte)((*ptr) >> 11);
1431 const glw::GLubyte g = ((*ptr) >> 6) & 31;
1432 const glw::GLubyte b = ((*ptr) >> 1) & 31;
1433 const glw::GLubyte a = (*ptr) & 1;
1445 else if (GL_UNSIGNED_INT_10_10_10_2 == format.m_type)
1447 const glw::GLuint* ptr = (const glw::GLuint*)format.m_source_data;
1448 const glw::GLushort r = (glw::GLushort)((*ptr) >> 22);
1449 const glw::GLushort g = ((*ptr) >> 12) & 1023;
1450 const glw::GLushort b = ((*ptr) >> 2) & 1023;
1451 const glw::GLushort a = (*ptr) & 3;
1458 if (true == is_norm)
1466 else if (GL_UNSIGNED_INT_10F_11F_11F_REV == format.m_type)
1468 ch_r = r11f.asDouble();
1469 ch_g = g11f.asDouble();
1470 ch_b = b10f.asDouble();
1472 else if (GL_UNSIGNED_INT_5_9_9_9_REV == format.m_type)
1474 TCU_FAIL("Not supported: GL_UNSIGNED_INT_5_9_9_9_REV");
1476 else if (GL_UNSIGNED_INT_24_8 == format.m_type)
1478 TCU_FAIL("Not supported: GL_UNSIGNED_INT_24_8");
1480 else if (GL_FLOAT_32_UNSIGNED_INT_24_8_REV == format.m_type)
1482 TCU_FAIL("Not supported: GL_FLOAT_32_UNSIGNED_INT_24_8_REV");
1484 else if (GL_BYTE == format.m_type)
1486 const glw::GLbyte* ptr = (const glw::GLbyte*)format.m_source_data;
1488 for (size_t i = 0; i < n_channels; ++i)
1490 const glw::GLbyte val = ptr[i];
1491 double& ch = ch_rgba[i];
1494 if (true == is_norm)
1498 else if (GL_UNSIGNED_BYTE == format.m_type)
1500 const glw::GLubyte* ptr = (const glw::GLubyte*)format.m_source_data;
1502 for (size_t i = 0; i < n_channels; ++i)
1504 const glw::GLubyte val = ptr[i];
1505 double& ch = ch_rgba[i];
1508 if (true == is_norm)
1512 else if (GL_SHORT == format.m_type)
1514 const glw::GLshort* ptr = (const glw::GLshort*)format.m_source_data;
1516 for (size_t i = 0; i < n_channels; ++i)
1518 const glw::GLshort val = ptr[i];
1519 double& ch = ch_rgba[i];
1522 if (true == is_norm)
1526 else if (GL_UNSIGNED_SHORT == format.m_type)
1528 const glw::GLushort* ptr = (const glw::GLushort*)format.m_source_data;
1530 for (size_t i = 0; i < n_channels; ++i)
1532 const glw::GLushort val = ptr[i];
1533 double& ch = ch_rgba[i];
1536 if (true == is_norm)
1540 else if (GL_INT == format.m_type)
1542 const glw::GLint* ptr = (const glw::GLint*)format.m_source_data;
1544 for (size_t i = 0; i < n_channels; ++i)
1546 const glw::GLint val = ptr[i];
1547 double& ch = ch_rgba[i];
1550 if (true == is_norm)
1554 else if (GL_UNSIGNED_INT == format.m_type)
1556 const glw::GLuint* ptr = (const glw::GLuint*)format.m_source_data;
1558 for (size_t i = 0; i < n_channels; ++i)
1560 const glw::GLuint val = ptr[i];
1561 double& ch = ch_rgba[i];
1564 if (true == is_norm)
1568 else if (GL_FLOAT == format.m_type)
1570 const glw::GLfloat* ptr = (const glw::GLfloat*)format.m_source_data;
1572 for (size_t i = 0; i < n_channels; ++i)
1574 const glw::GLfloat val = ptr[i];
1575 double& ch = ch_rgba[i];
1580 else if (GL_HALF_FLOAT == format.m_type)
1582 const glw::GLhalf* ptr = (const glw::GLhalf*)format.m_source_data;
1584 for (size_t i = 0; i < n_channels; ++i)
1586 const glw::GLhalf val = ptr[i];
1587 double& ch = ch_rgba[i];
1589 tcu::Float16 f16(val);
1590 ch = f16.asDouble();
1595 TCU_FAIL("Invalid enum");
1599 memcpy(out_ch_rgba, ch_rgba, 4 * sizeof(double));
1602 /** Calculate maximum uint value for given size of storage
1604 * @param size Size of storage in bits
1606 * @return Calculated max
1608 double calculate_max_for_size(size_t size)
1610 double power = pow(2.0, double(size));
1615 /** Converts from double to given T
1617 * @tparam Requested type of value
1619 * @param out_expected_data Storage for converted value
1620 * @param value Value to be converted
1622 template <typename T>
1623 void convert(void* out_expected_data, double value)
1625 T* ptr = (T*)out_expected_data;
1630 /** Calcualte range of expected values
1632 * @param source_format_idx Index of source format
1633 * @param output_format_idx Index of output format
1634 * @param index_of_swizzled_channel Index of swizzled channel
1635 * @param source_size Size of source storage in bits
1636 * @param output_size Size of output storage in bits
1637 * @param out_expected_data_low Lowest acceptable value
1638 * @param out_expected_data_top Highest acceptable value
1639 * @param out_expected_data_size Number of bytes used to store out values
1641 void calculate_expected_value(size_t source_format_idx, size_t output_format_idx, size_t index_of_swizzled_channel,
1642 glw::GLint source_size, glw::GLint output_size, void* out_expected_data_low,
1643 void* out_expected_data_top, size_t& out_expected_data_size)
1645 const _texture_format& output_format = texture_formats[output_format_idx];
1646 const _texture_format& source_format = texture_formats[source_format_idx];
1647 const _out_ch_desc& desc = get_descriptor_for_channel(source_format, index_of_swizzled_channel);
1648 const glw::GLvoid* expected_data = desc.m_expected_data;
1649 bool is_signed = false;
1650 double range_low = 0.0f;
1651 double range_top = 0.0f;
1652 size_t texel_size = 0;
1654 /* Select range, texel size and is_signed */
1655 switch (output_format.m_type)
1667 case GL_UNSIGNED_BYTE:
1678 range_low = -32767.0;
1679 range_top = 32767.0;
1685 case GL_UNSIGNED_SHORT:
1687 range_top = 65535.0;
1696 /* Halfs are not calculated, range will not be used */
1703 range_low = -2147483647.0;
1704 range_top = 2147483647.0;
1710 case GL_UNSIGNED_INT:
1712 range_top = 4294967295.0;
1721 /* Float are not calculated, range will not be used */
1726 TCU_FAIL("Invalid enum");
1730 /* Signed formats use one bit less */
1731 if (true == is_signed)
1737 /* If expected data is hardcoded just copy data to low and top */
1738 if (DE_NULL != expected_data)
1740 memcpy(out_expected_data_top, expected_data, texel_size);
1741 memcpy(out_expected_data_low, expected_data, texel_size);
1742 out_expected_data_size = texel_size;
1746 /* Get source values */
1748 calculate_values_from_source(source_format_idx, ch_rgba);
1750 /* Calculate expected value */
1751 const float max_internal = float(calculate_max_for_size(source_size));
1752 const float max_output = float(calculate_max_for_size(output_size));
1753 const float temp_internal = float(ch_rgba[index_of_swizzled_channel]) * max_internal;
1754 const float stor_internal_low =
1755 deFloatFloor(temp_internal - 1.0f); /* Offset by 1 to avoid rounding done by FPU */
1756 const float stor_internal_top =
1757 deFloatCeil(temp_internal + 1.0f); /* Offset by 1 to avoid rounding done by FPU */
1758 const float read_internal_low = stor_internal_low / max_internal;
1759 const float read_internal_top = stor_internal_top / max_internal;
1760 const float temp_output_low = read_internal_low * max_output;
1761 const float temp_output_top = read_internal_top * max_output;
1762 double stor_output_low = floor(temp_output_low);
1763 double stor_output_top = ceil(temp_output_top);
1765 /* Clamp to limits of output format */
1766 stor_output_low = de::clamp(stor_output_low, range_low, range_top);
1767 stor_output_top = de::clamp(stor_output_top, range_low, range_top);
1770 switch (output_format.m_type)
1773 convert<glw::GLbyte>(out_expected_data_low, stor_output_low);
1774 convert<glw::GLbyte>(out_expected_data_top, stor_output_top);
1776 case GL_UNSIGNED_BYTE:
1777 convert<glw::GLubyte>(out_expected_data_low, stor_output_low);
1778 convert<glw::GLubyte>(out_expected_data_top, stor_output_top);
1781 convert<glw::GLshort>(out_expected_data_low, stor_output_low);
1782 convert<glw::GLshort>(out_expected_data_top, stor_output_top);
1784 case GL_UNSIGNED_SHORT:
1785 convert<glw::GLushort>(out_expected_data_low, stor_output_low);
1786 convert<glw::GLushort>(out_expected_data_top, stor_output_top);
1789 convert<glw::GLint>(out_expected_data_low, stor_output_low);
1790 convert<glw::GLint>(out_expected_data_top, stor_output_top);
1792 case GL_UNSIGNED_INT:
1793 convert<glw::GLuint>(out_expected_data_low, stor_output_low);
1794 convert<glw::GLuint>(out_expected_data_top, stor_output_top);
1797 TCU_FAIL("Invalid enum");
1800 out_expected_data_size = texel_size;
1804 /** Gets index of internal format in texture_fomrats
1806 * @param internal_format Internal format to be found
1808 * @return Found index. -1 when format is not available. 0 when GL_ZERO is requested.
1810 size_t get_index_of_format(glw::GLenum internal_format)
1812 if (GL_ZERO == internal_format)
1817 for (size_t i = 0; i < n_texture_formats; ++i)
1819 if (texture_formats[i].m_internal_format == internal_format)
1825 TCU_FAIL("Unknown internal format");
1829 /** Gets index of target in texture_targets
1831 * @param target target to be found
1833 * @return Found index. -1 when format is not available. 0 when GL_ZERO is requested.
1835 size_t get_index_of_target(glw::GLenum target)
1837 if (GL_ZERO == target)
1842 for (size_t i = 0; i < n_texture_targets; ++i)
1844 if (texture_targets[i].m_target == target)
1850 TCU_FAIL("Unknown texture target");
1854 /* Constants used by get_swizzled_channel_idx */
1855 static const size_t CHANNEL_INDEX_ONE = 4;
1856 static const size_t CHANNEL_INDEX_ZERO = 5;
1858 /** Get index of channel that will be accessed after "swizzle" is applied
1860 * @param channel_idx Index of channel before "swizzle" is applied
1861 * @param swizzle_set Set of swizzle states
1863 * @return Index of "swizzled" channel
1865 size_t get_swizzled_channel_idx(const size_t channel_idx, const glw::GLint swizzle_set[4])
1867 const glw::GLint swizzle = swizzle_set[channel_idx];
1886 channel = CHANNEL_INDEX_ONE;
1889 channel = CHANNEL_INDEX_ZERO;
1892 TCU_FAIL("Invalid value");
1899 /** Gets descriptor of output channel from texture format descriptor
1901 * @param format Format descriptor
1902 * @param channel Index of "swizzled" channel
1904 * @return Descriptor of output channel
1906 const _out_ch_desc& get_descriptor_for_channel(const _texture_format& format, const size_t channel)
1908 const _out_ch_desc* desc = 0;
1912 case CHANNEL_INDEX_ONE:
1913 desc = &format.m_one_ch;
1915 case CHANNEL_INDEX_ZERO:
1916 desc = &format.m_zero_ch;
1919 desc = &format.m_red_ch;
1922 desc = &format.m_green_ch;
1925 desc = &format.m_blue_ch;
1928 desc = &format.m_alpha_ch;
1931 TCU_FAIL("Invalid value");
1935 switch (desc->m_internal_format)
1938 desc = &format.m_one_ch;
1941 desc = &format.m_zero_ch;
1950 /** Gets internal_format of output channel for given texture format
1952 * @param format Format descriptor
1953 * @param channel Index of "swizzled" channel
1955 * @return Internal format
1957 glw::GLenum get_internal_format_for_channel(const _texture_format& format, const size_t channel)
1959 return get_descriptor_for_channel(format, channel).m_internal_format;
1964 * @param context Test context
1966 Utils::programInfo::programInfo(deqp::Context& context)
1967 : m_context(context), m_fragment_shader_id(0), m_program_object_id(0), m_vertex_shader_id(0)
1969 /* Nothing to be done here */
1975 Utils::programInfo::~programInfo()
1977 /* GL entry points */
1978 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1980 /* Make sure program object is no longer used by GL */
1983 /* Clean program object */
1984 if (0 != m_program_object_id)
1986 gl.deleteProgram(m_program_object_id);
1987 m_program_object_id = 0;
1991 if (0 != m_fragment_shader_id)
1993 gl.deleteShader(m_fragment_shader_id);
1994 m_fragment_shader_id = 0;
1997 if (0 != m_vertex_shader_id)
1999 gl.deleteShader(m_vertex_shader_id);
2000 m_vertex_shader_id = 0;
2006 * @param fragment_shader_code Fragment shader source code
2007 * @param vertex_shader_code Vertex shader source code
2009 void Utils::programInfo::build(const glw::GLchar* fragment_shader_code, const glw::GLchar* vertex_shader_code)
2011 /* GL entry points */
2012 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2014 /* Create shader objects and compile */
2015 if (0 != fragment_shader_code)
2017 m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER);
2018 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
2020 compile(m_fragment_shader_id, fragment_shader_code);
2023 if (0 != vertex_shader_code)
2025 m_vertex_shader_id = gl.createShader(GL_VERTEX_SHADER);
2026 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
2028 compile(m_vertex_shader_id, vertex_shader_code);
2031 /* Create program object */
2032 m_program_object_id = gl.createProgram();
2033 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram");
2041 * @param shader_id Shader object id
2042 * @param shader_code Shader source code
2044 void Utils::programInfo::compile(glw::GLuint shader_id, const glw::GLchar* shader_code) const
2046 /* GL entry points */
2047 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2049 /* Compilation status */
2050 glw::GLint status = GL_FALSE;
2052 /* Set source code */
2053 gl.shaderSource(shader_id, 1 /* count */, &shader_code, 0);
2054 GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource");
2057 gl.compileShader(shader_id);
2058 GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader");
2060 /* Get compilation status */
2061 gl.getShaderiv(shader_id, GL_COMPILE_STATUS, &status);
2062 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
2064 /* Log compilation error */
2065 if (GL_TRUE != status)
2067 glw::GLint length = 0;
2068 std::vector<glw::GLchar> message;
2070 /* Error log length */
2071 gl.getShaderiv(shader_id, GL_INFO_LOG_LENGTH, &length);
2072 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
2074 /* Prepare storage */
2075 message.resize(length);
2078 gl.getShaderInfoLog(shader_id, length, 0, &message[0]);
2079 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog");
2082 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to compile shader:\n"
2083 << &message[0] << "\nShader source\n"
2084 << shader_code << tcu::TestLog::EndMessage;
2086 TCU_FAIL("Failed to compile shader");
2090 /** Attach shaders and link program
2093 void Utils::programInfo::link() const
2095 /* GL entry points */
2096 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2099 glw::GLint status = GL_FALSE;
2101 /* Attach shaders */
2102 if (0 != m_fragment_shader_id)
2104 gl.attachShader(m_program_object_id, m_fragment_shader_id);
2105 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
2108 if (0 != m_vertex_shader_id)
2110 gl.attachShader(m_program_object_id, m_vertex_shader_id);
2111 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
2115 gl.linkProgram(m_program_object_id);
2116 GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram");
2118 /* Get link status */
2119 gl.getProgramiv(m_program_object_id, GL_LINK_STATUS, &status);
2120 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
2122 /* Log link error */
2123 if (GL_TRUE != status)
2125 glw::GLint length = 0;
2126 std::vector<glw::GLchar> message;
2128 /* Get error log length */
2129 gl.getProgramiv(m_program_object_id, GL_INFO_LOG_LENGTH, &length);
2130 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
2132 message.resize(length);
2135 gl.getProgramInfoLog(m_program_object_id, length, 0, &message[0]);
2136 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog");
2139 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to link program:\n"
2140 << &message[0] << tcu::TestLog::EndMessage;
2142 TCU_FAIL("Failed to link program");
2146 /** Replace first occurance of <token> with <text> in <string> starting at <search_posistion>
2148 * @param token Token string
2149 * @param search_position Position at which find will start, it is updated to position at which replaced text ends
2150 * @param text String that will be used as replacement for <token>
2151 * @param string String to work on
2153 void Utils::replaceToken(const glw::GLchar* token, size_t& search_position, const glw::GLchar* text,
2154 std::string& string)
2156 const size_t text_length = strlen(text);
2157 const size_t token_length = strlen(token);
2158 const size_t token_position = string.find(token, search_position);
2160 string.replace(token_position, token_length, text, text_length);
2162 search_position = token_position + text_length;
2167 * @param context Rendering context.
2169 APIErrorsTest::APIErrorsTest(deqp::Context& context)
2170 : TestCase(context, "api_errors", "Verifies that errors are generated as specified"), m_id(0)
2172 /* Left blank intentionally */
2175 /** Deinitialization **/
2176 void APIErrorsTest::deinit()
2180 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2182 gl.deleteTextures(1, &m_id);
2187 /** Executes test iteration.
2189 * @return Returns STOP.
2191 tcu::TestNode::IterateResult APIErrorsTest::iterate()
2193 static const glw::GLint invalid_values[] = { 0x1902, 0x1907, -1, 2 };
2194 static const size_t n_invalid_values = sizeof(invalid_values) / sizeof(invalid_values[0]);
2197 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2199 gl.genTextures(1, &m_id);
2200 GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
2202 gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_id);
2203 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2206 * - INVALID_ENUM is generated by TexParameter* routines when <pname> is
2207 * one of [TEXTURE_SWIZZLE_R, TEXTURE_SWIZZLE_G, TEXTURE_SWIZZLE_B,
2208 * TEXTURE_SWIZZLE_A] and <param> is not one of [RED, GREEN, BLUE, ALPHA, ZERO,
2211 for (size_t i = 0; i < n_states; ++i)
2213 for (size_t j = 0; j < n_valid_values; ++j)
2215 const glw::GLenum state = states[i];
2216 const glw::GLint value = valid_values[j];
2218 gl.texParameteri(GL_TEXTURE_CUBE_MAP, state, value);
2219 verifyError(GL_NO_ERROR);
2222 for (size_t j = 0; j < n_invalid_values; ++j)
2224 const glw::GLenum state = states[i];
2225 const glw::GLint value = invalid_values[j];
2227 gl.texParameteri(GL_TEXTURE_CUBE_MAP, state, value);
2228 verifyError(GL_INVALID_ENUM);
2233 * - INVALID_ENUM is generated by TexParameter*v routines when <pname> is
2234 * TEXTURE_SWIZZLE_RGBA and any of four values pointed by <param> is not one of
2235 * [RED, GREEN, BLUE, ALPHA, ZERO, ONE].
2237 for (size_t i = 0; i < 4 /* number of channels */; ++i)
2239 for (size_t j = 0; j < n_valid_values; ++j)
2241 const glw::GLint value = valid_values[j];
2243 glw::GLint param[4] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA };
2247 gl.texParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_RGBA, param);
2248 verifyError(GL_NO_ERROR);
2251 for (size_t j = 0; j < n_invalid_values; ++j)
2253 const glw::GLint value = invalid_values[j];
2255 glw::GLint param[4] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA };
2259 gl.texParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_RGBA, param);
2260 verifyError(GL_INVALID_ENUM);
2264 /* Set result - exceptions are thrown in case of any error */
2265 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
2271 /** Verifies that proper error was generated
2273 * @param expected_error
2275 void APIErrorsTest::verifyError(const glw::GLenum expected_error)
2278 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2280 const glw::GLenum error = gl.getError();
2282 if (expected_error != error)
2284 TCU_FAIL("Got invalid error");
2290 * @param context Rendering context.
2292 IntialStateTest::IntialStateTest(deqp::Context& context)
2293 : TestCase(context, "intial_state", "Verifies that initial states are as specified"), m_id(0)
2295 /* Left blank intentionally */
2298 /** Deinitialization **/
2299 void IntialStateTest::deinit()
2303 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2305 gl.deleteTextures(1, &m_id);
2310 /** Executes test iteration.
2312 * @return Returns STOP.
2314 tcu::TestNode::IterateResult IntialStateTest::iterate()
2317 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2319 gl.genTextures(1, &m_id);
2320 GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
2322 for (size_t tex_tgt_idx = 0; tex_tgt_idx < n_texture_targets; ++tex_tgt_idx)
2324 const glw::GLenum target = texture_targets[tex_tgt_idx].m_target;
2326 gl.bindTexture(target, m_id);
2327 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2329 verifyValues(target);
2334 /* Set result - exceptions are thrown in case of any error */
2335 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
2341 /** Verifies that proper error was generated
2343 * @param expected_error
2345 void IntialStateTest::verifyValues(const glw::GLenum texture_target)
2348 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2351 glw::GLint green = 0;
2352 glw::GLint blue = 0;
2353 glw::GLint alpha = 0;
2354 glw::GLint param[4] = { 0 };
2356 gl.getTexParameterIiv(texture_target, GL_TEXTURE_SWIZZLE_R, &red);
2357 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexParameterIiv");
2358 gl.getTexParameterIiv(texture_target, GL_TEXTURE_SWIZZLE_G, &green);
2359 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexParameterIiv");
2360 gl.getTexParameterIiv(texture_target, GL_TEXTURE_SWIZZLE_B, &blue);
2361 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexParameterIiv");
2362 gl.getTexParameterIiv(texture_target, GL_TEXTURE_SWIZZLE_A, &alpha);
2363 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexParameterIiv");
2364 gl.getTexParameterIiv(texture_target, GL_TEXTURE_SWIZZLE_RGBA, param);
2365 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexParameterIiv");
2369 TCU_FAIL("Got invalid initial state for TEXTURE_SWIZZLE_R");
2371 if (GL_GREEN != green)
2373 TCU_FAIL("Got invalid initial state for TEXTURE_SWIZZLE_G");
2375 if (GL_BLUE != blue)
2377 TCU_FAIL("Got invalid initial state for TEXTURE_SWIZZLE_B");
2379 if (GL_ALPHA != alpha)
2381 TCU_FAIL("Got invalid initial state for TEXTURE_SWIZZLE_A");
2384 if (GL_RED != param[0])
2386 TCU_FAIL("Got invalid initial red state for TEXTURE_SWIZZLE_RGBA");
2388 if (GL_GREEN != param[1])
2390 TCU_FAIL("Got invalid initial green state for TEXTURE_SWIZZLE_RGBA");
2392 if (GL_BLUE != param[2])
2394 TCU_FAIL("Got invalid initial blue state for TEXTURE_SWIZZLE_RGBA");
2396 if (GL_ALPHA != param[3])
2398 TCU_FAIL("Got invalid initial alpha state for TEXTURE_SWIZZLE_RGBA");
2402 /* Constants used by SmokeTest */
2403 const glw::GLsizei SmokeTest::m_depth = 1;
2404 const glw::GLsizei SmokeTest::m_height = 1;
2405 const glw::GLsizei SmokeTest::m_width = 1;
2406 const glw::GLsizei SmokeTest::m_output_height = 8;
2407 const glw::GLsizei SmokeTest::m_output_width = 8;
2411 * @param context Rendering context.
2413 SmokeTest::SmokeTest(deqp::Context& context)
2414 : TestCase(context, "smoke", "Verifies that all swizzle combinations work with all texture access routines")
2415 , m_is_ms_supported(false)
2416 , m_prepare_fbo_id(0)
2418 , m_source_tex_id(0)
2422 /* Left blank intentionally */
2427 * @param context Rendering context.
2429 SmokeTest::SmokeTest(deqp::Context& context, const glw::GLchar* name, const glw::GLchar* description)
2430 : TestCase(context, name, description)
2431 , m_is_ms_supported(false)
2432 , m_prepare_fbo_id(0)
2434 , m_source_tex_id(0)
2438 /* Left blank intentionally */
2441 /** Deinitialization **/
2442 void SmokeTest::deinit()
2446 if (m_prepare_fbo_id != 0)
2448 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2449 gl.deleteFramebuffers(1, &m_prepare_fbo_id);
2451 m_prepare_fbo_id = 0;
2454 if (m_test_fbo_id != 0)
2456 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2457 gl.deleteFramebuffers(1, &m_test_fbo_id);
2464 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2465 gl.deleteVertexArrays(1, &m_vao_id);
2471 /** Executes test iteration.
2473 * @return Returns STOP.
2475 tcu::TestNode::IterateResult SmokeTest::iterate()
2477 static const glw::GLenum tested_format = GL_RGBA32UI;
2478 static const glw::GLenum tested_target = GL_TEXTURE_2D_ARRAY;
2480 const size_t format_idx = get_index_of_format(tested_format);
2481 const size_t tgt_idx = get_index_of_target(tested_target);
2483 glw::GLint source_channel_sizes[4] = { 0 };
2488 if (false == isTargetSupported(tgt_idx))
2490 throw tcu::NotSupportedError("Texture target is not support by implementation", "", __FILE__, __LINE__);
2493 /* Prepare and fill source texture */
2494 prepareSourceTexture(format_idx, tgt_idx, source_channel_sizes);
2495 if (false == fillSourceTexture(format_idx, tgt_idx))
2497 TCU_FAIL("Failed to prepare source texture");
2500 /* Iterate over all cases */
2501 for (size_t access_idx = 0; access_idx < n_texture_access; ++access_idx)
2503 /* Skip invalid cases */
2504 if (false == isTargetSuppByAccess(access_idx, tgt_idx))
2509 for (size_t r = 0; r < n_valid_values; ++r)
2511 for (size_t g = 0; g < n_valid_values; ++g)
2513 for (size_t b = 0; b < n_valid_values; ++b)
2515 for (size_t a = 0; a < n_valid_values; ++a)
2517 for (size_t channel_idx = 0; channel_idx < 4; ++channel_idx)
2519 const testCase test_case = { channel_idx,
2527 { source_channel_sizes[0], source_channel_sizes[1],
2528 source_channel_sizes[2], source_channel_sizes[3] } };
2530 executeTestCase(test_case);
2532 deinitOutputTexture();
2533 } /* iteration over channels */
2534 } /* iteration over swizzle combinations */
2538 } /* iteration over access routines */
2540 /* Set result - exceptions are thrown in case of any error */
2541 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
2547 /** Deinitialization of output texture **/
2548 void SmokeTest::deinitOutputTexture()
2550 if (m_out_tex_id != 0)
2552 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2553 gl.deleteTextures(1, &m_out_tex_id);
2559 /** Deinitialization of textures **/
2560 void SmokeTest::deinitTextures()
2562 deinitOutputTexture();
2564 if (m_source_tex_id != 0)
2566 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2567 gl.deleteTextures(1, &m_source_tex_id);
2569 m_source_tex_id = 0;
2573 /** Captures and verifies contents of output texture
2575 * @param test_case Test case instance
2576 * @param output_format_index Index of format used by output texture
2577 * @parma output_channel_size Size of storage used by output texture in bits
2578 * @param index_of_swizzled_channel Index of swizzled channel
2580 void SmokeTest::captureAndVerify(const testCase& test_case, size_t output_format_index, glw::GLint output_channel_size,
2581 size_t index_of_swizzled_channel)
2583 const _texture_format& output_format = texture_formats[output_format_index];
2586 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2588 /* Storage for image data */
2589 glw::GLubyte result_image[m_output_width * m_output_height * 4 /* channles */ * sizeof(glw::GLuint)];
2591 /* Get image data */
2592 gl.bindTexture(GL_TEXTURE_2D, m_out_tex_id);
2593 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2595 gl.getTexImage(GL_TEXTURE_2D, 0 /* level */, output_format.m_format, output_format.m_type, result_image);
2596 GLU_EXPECT_NO_ERROR(gl.getError(), "getTexImage");
2598 /* Unbind output texture */
2599 gl.bindTexture(GL_TEXTURE_2D, 0);
2600 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2603 verifyOutputImage(test_case, output_format_index, output_channel_size, index_of_swizzled_channel, result_image);
2606 /** Draws four points
2608 * @param target Target of source texture
2609 * @param texture_swizzle Set of texture swizzle values
2610 * @param use_rgba_enum If texture swizzle states should be set with RGBA enum or separe calls
2612 void SmokeTest::draw(glw::GLenum target, const glw::GLint* texture_swizzle, bool use_rgba_enum)
2614 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2616 /* Prepare source texture */
2617 gl.activeTexture(GL_TEXTURE0);
2618 GLU_EXPECT_NO_ERROR(gl.getError(), "ActiveTexture");
2620 gl.bindTexture(target, m_source_tex_id);
2621 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2623 /* Set texture swizzle */
2624 if (true == use_rgba_enum)
2626 gl.texParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, texture_swizzle);
2627 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteriv");
2631 gl.texParameteri(target, GL_TEXTURE_SWIZZLE_R, texture_swizzle[0]);
2632 gl.texParameteri(target, GL_TEXTURE_SWIZZLE_G, texture_swizzle[1]);
2633 gl.texParameteri(target, GL_TEXTURE_SWIZZLE_B, texture_swizzle[2]);
2634 gl.texParameteri(target, GL_TEXTURE_SWIZZLE_A, texture_swizzle[3]);
2635 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
2639 gl.clear(GL_COLOR_BUFFER_BIT);
2640 GLU_EXPECT_NO_ERROR(gl.getError(), "Clear");
2643 gl.drawArrays(GL_TRIANGLE_STRIP, 0 /* first */, 4 /* count */);
2644 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
2646 /* Revert texture swizzle */
2647 gl.texParameteri(target, GL_TEXTURE_SWIZZLE_R, GL_RED);
2648 gl.texParameteri(target, GL_TEXTURE_SWIZZLE_G, GL_GREEN);
2649 gl.texParameteri(target, GL_TEXTURE_SWIZZLE_B, GL_BLUE);
2650 gl.texParameteri(target, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);
2651 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
2653 /* Unbind source texture */
2654 gl.bindTexture(target, 0);
2655 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2658 /** Executes test case
2660 * @param test_case Test case instance
2662 void SmokeTest::executeTestCase(const testCase& test_case)
2664 const _texture_format& source_format = texture_formats[test_case.m_source_texture_format_index];
2665 const glw::GLint red = test_case.m_texture_swizzle_red;
2666 const glw::GLint green = test_case.m_texture_swizzle_green;
2667 const glw::GLint blue = test_case.m_texture_swizzle_blue;
2668 const glw::GLint alpha = test_case.m_texture_swizzle_alpha;
2669 const glw::GLint param[4] = { red, green, blue, alpha };
2670 const size_t channel = get_swizzled_channel_idx(test_case.m_channel_index, param);
2671 glw::GLint out_channel_size = 0;
2672 const glw::GLenum out_internal_format = get_internal_format_for_channel(source_format, channel);
2673 const size_t out_format_idx = get_index_of_format(out_internal_format);
2676 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2678 /* Prepare output */
2679 prepareOutputTexture(out_format_idx);
2681 gl.bindTexture(GL_TEXTURE_2D, m_out_tex_id);
2682 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2684 gl.bindFramebuffer(GL_FRAMEBUFFER, m_test_fbo_id);
2685 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
2687 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_out_tex_id, 0 /* level */);
2688 GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture2D");
2691 gl.viewport(0 /* x */, 0 /* y */, m_output_width, m_output_height);
2692 GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
2694 /* Get internal storage size of output texture */
2695 gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0 /* level */, GL_TEXTURE_RED_SIZE, &out_channel_size);
2696 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
2698 /* Unbind output texture */
2699 gl.bindTexture(GL_TEXTURE_2D, 0);
2700 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2702 prepareAndTestProgram(test_case, out_format_idx, out_channel_size, channel, true);
2703 prepareAndTestProgram(test_case, out_format_idx, out_channel_size, channel, false);
2706 gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
2707 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
2710 /** Fills source texture
2712 * @param format_idx Index of format
2713 * @param target_idx Index of target
2715 * @return True if operation was successful, false other wise
2717 bool SmokeTest::fillSourceTexture(size_t format_idx, size_t target_idx)
2719 static const glw::GLuint rgba32ui[4] = { 0x3fffffff, 0x7fffffff, 0xbfffffff, 0xffffffff };
2721 const glw::GLenum target = texture_targets[target_idx].m_target;
2722 const _texture_format& texture_format = texture_formats[format_idx];
2725 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2726 const glw::GLvoid* data = 0;
2728 /* Bind texture and FBO */
2729 gl.bindTexture(target, m_source_tex_id);
2730 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2733 switch (texture_format.m_internal_format)
2736 data = (const glw::GLubyte*)rgba32ui;
2740 TCU_FAIL("Invalid enum");
2744 /* Attach texture */
2747 case GL_TEXTURE_2D_ARRAY:
2748 gl.texSubImage3D(target, 0 /* level */, 0 /* x */, 0 /* y */, 0 /* z */, m_width, m_height, m_depth,
2749 texture_format.m_format, texture_format.m_type, data);
2753 TCU_FAIL("Invalid enum");
2758 gl.bindTexture(target, 0);
2759 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2765 /** Gets source of fragment shader
2767 * @param test_case Test case instance
2768 * @param output_format_index Index of output format
2769 * @param is_tested_stage Selects if fragment or vertex shader makes texture access
2771 * @return Source of shader
2773 std::string SmokeTest::getFragmentShader(const testCase& test_case, size_t output_format_index, bool is_tested_stage)
2775 static const glw::GLchar* fs_blank_template = "#version 330 core\n"
2777 "flat in BASIC_TYPE result;\n"
2779 "out BASIC_TYPE out_color;\n"
2783 " out_color = result;\n"
2787 static const glw::GLchar* fs_test_template = "#version 330 core\n"
2789 "uniform PREFIXsamplerSAMPLER_TYPE sampler;\n"
2791 "out BASIC_TYPE out_color;\n"
2795 " BASIC_TYPE result = TEXTURE_ACCESS(sampler, ARGUMENTS).CHANNEL;\n"
2797 " out_color = result;\n"
2802 const std::string& arguments = prepareArguments(test_case);
2803 const _texture_access& access = texture_access[test_case.m_texture_access_index];
2804 const glw::GLchar* channel = channels[test_case.m_channel_index];
2805 const _texture_format& output_format = texture_formats[output_format_index];
2806 const _texture_format& source_format = texture_formats[test_case.m_source_texture_format_index];
2807 const _texture_target& target = texture_targets[test_case.m_source_texture_target_index];
2810 size_t position = 0;
2812 if (is_tested_stage)
2814 fs = fs_test_template;
2816 Utils::replaceToken("PREFIX", position, source_format.m_sampler.m_sampler_prefix, fs);
2817 Utils::replaceToken("SAMPLER_TYPE", position, target.m_sampler_type, fs);
2818 Utils::replaceToken("BASIC_TYPE", position, output_format.m_sampler.m_basic_type, fs);
2819 Utils::replaceToken("BASIC_TYPE", position, source_format.m_sampler.m_basic_type, fs);
2820 Utils::replaceToken("TEXTURE_ACCESS", position, access.m_name, fs);
2821 Utils::replaceToken("ARGUMENTS", position, arguments.c_str(), fs);
2822 Utils::replaceToken("CHANNEL", position, channel, fs);
2826 fs = fs_blank_template;
2828 Utils::replaceToken("BASIC_TYPE", position, source_format.m_sampler.m_basic_type, fs);
2829 Utils::replaceToken("BASIC_TYPE", position, output_format.m_sampler.m_basic_type, fs);
2835 /** Gets source of vertex shader
2837 * @param test_case Test case instance
2838 * @param is_tested_stage Selects if vertex or fragment shader makes texture access
2840 * @return Source of shader
2842 std::string SmokeTest::getVertexShader(const testCase& test_case, bool is_tested_stage)
2844 static const glw::GLchar* vs_blank_template = "#version 330 core\n"
2848 " switch (gl_VertexID)\n"
2850 " case 0: gl_Position = vec4(-1.0, 1.0, 0.0, 1.0); break; \n"
2851 " case 1: gl_Position = vec4( 1.0, 1.0, 0.0, 1.0); break; \n"
2852 " case 2: gl_Position = vec4(-1.0,-1.0, 0.0, 1.0); break; \n"
2853 " case 3: gl_Position = vec4( 1.0,-1.0, 0.0, 1.0); break; \n"
2858 static const glw::GLchar* vs_test_template = "#version 330 core\n"
2860 "uniform PREFIXsamplerSAMPLER_TYPE sampler;\n"
2862 "flat out BASIC_TYPE result;\n"
2866 " result = TEXTURE_ACCESS(sampler, ARGUMENTS).CHANNEL;\n"
2868 " switch (gl_VertexID)\n"
2870 " case 0: gl_Position = vec4(-1.0, 1.0, 0.0, 1.0); break; \n"
2871 " case 1: gl_Position = vec4( 1.0, 1.0, 0.0, 1.0); break; \n"
2872 " case 2: gl_Position = vec4(-1.0,-1.0, 0.0, 1.0); break; \n"
2873 " case 3: gl_Position = vec4( 1.0,-1.0, 0.0, 1.0); break; \n"
2880 if (is_tested_stage)
2883 const std::string& arguments = prepareArguments(test_case);
2884 const _texture_access& access = texture_access[test_case.m_texture_access_index];
2885 const glw::GLchar* channel = channels[test_case.m_channel_index];
2886 const _texture_format& source_format = texture_formats[test_case.m_source_texture_format_index];
2887 const _texture_target& target = texture_targets[test_case.m_source_texture_target_index];
2889 size_t position = 0;
2891 vs = vs_test_template;
2893 Utils::replaceToken("PREFIX", position, source_format.m_sampler.m_sampler_prefix, vs);
2894 Utils::replaceToken("SAMPLER_TYPE", position, target.m_sampler_type, vs);
2895 Utils::replaceToken("BASIC_TYPE", position, source_format.m_sampler.m_basic_type, vs);
2896 Utils::replaceToken("TEXTURE_ACCESS", position, access.m_name, vs);
2897 Utils::replaceToken("ARGUMENTS", position, arguments.c_str(), vs);
2898 Utils::replaceToken("CHANNEL", position, channel, vs);
2902 vs = vs_blank_template;
2908 /** Check if target is supported
2910 * @param target_idx Index of target
2912 * @return true if target is supported, false otherwise
2914 bool SmokeTest::isTargetSupported(size_t target_idx)
2916 const _texture_target& target = texture_targets[target_idx];
2918 bool is_supported = true;
2920 switch (target.m_target)
2922 case GL_TEXTURE_2D_MULTISAMPLE:
2923 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
2924 is_supported = m_is_ms_supported;
2931 return is_supported;
2934 /** Check if target is supported by access routine
2936 * @param access_idx Index of access routine
2937 * @param target_idx Index of target
2939 * @return true if target is supported, false otherwise
2941 bool SmokeTest::isTargetSuppByAccess(size_t access_idx, size_t target_idx)
2943 const _texture_access& access = texture_access[access_idx];
2944 const _texture_target& source_target = texture_targets[target_idx];
2946 if ((false == source_target.m_support_integral_coordinates) && (true == access.m_use_integral_coordinates))
2948 /* Cases are not valid, texelFetch* is not supported by the target */
2952 if ((false == source_target.m_support_offset) && (true == access.m_use_offsets))
2954 /* Cases are not valid, texture*Offset is not supported by the target */
2958 if ((false == source_target.m_support_lod) && (true == access.m_use_lod))
2960 /* Access is one of texture*Lod* or texelFetch* */
2961 /* Target is one of MS or rect */
2963 if ((true == source_target.m_require_multisampling) && (true == access.m_support_multisampling))
2966 /* One of MS targets */
2970 /* Cases are not valid, either lod or sample is required but target does not supported that */
2974 if ((false == source_target.m_supports_proj) && (1 == access.m_n_coordinates))
2976 /* Cases are not valid, textureProj* is not supported by the target */
2980 if ((true == source_target.m_require_multisampling) && (false == access.m_support_multisampling))
2982 /* Cases are not valid, texelFetch* is not supported by the target */
2989 /** Check if target is supported by format
2991 * @param format_idx Index of format
2992 * @param target_idx Index of target
2994 * @return true if target is supported, false otherwise
2996 bool SmokeTest::isTargetSuppByFormat(size_t format_idx, size_t target_idx)
2998 const _texture_format& format = texture_formats[format_idx];
2999 const _texture_target& source_target = texture_targets[target_idx];
3001 bool is_supported = true;
3003 switch (format.m_internal_format)
3005 case GL_DEPTH_COMPONENT16:
3006 case GL_DEPTH_COMPONENT24:
3007 case GL_DEPTH_COMPONENT32:
3008 case GL_DEPTH_COMPONENT32F:
3009 case GL_DEPTH24_STENCIL8:
3010 case GL_DEPTH32F_STENCIL8:
3011 switch (source_target.m_target)
3014 case GL_TEXTURE_2D_MULTISAMPLE:
3015 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
3016 is_supported = false;
3024 switch (source_target.m_target)
3026 case GL_TEXTURE_2D_MULTISAMPLE:
3027 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
3028 is_supported = false;
3039 return is_supported;
3042 /** Logs details of test case
3044 * @parma test_case Test case instance
3046 void SmokeTest::logTestCaseDetials(const testCase& test_case)
3048 const glw::GLenum target = texture_targets[test_case.m_source_texture_target_index].m_target;
3049 const _texture_format& source_format = texture_formats[test_case.m_source_texture_format_index];
3050 const glw::GLint red = test_case.m_texture_swizzle_red;
3051 const glw::GLint green = test_case.m_texture_swizzle_green;
3052 const glw::GLint blue = test_case.m_texture_swizzle_blue;
3053 const glw::GLint alpha = test_case.m_texture_swizzle_alpha;
3054 const glw::GLint param[4] = { red, green, blue, alpha };
3055 const size_t channel = get_swizzled_channel_idx(test_case.m_channel_index, param);
3056 const glw::GLenum out_internal_format = get_internal_format_for_channel(source_format, channel);
3057 const size_t out_format_idx = get_index_of_format(out_internal_format);
3058 const _texture_format& output_format = texture_formats[out_format_idx];
3060 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case details. Source texture: Target: "
3061 << glu::getTextureTargetStr(target)
3062 << ". Format: " << glu::getTextureFormatName(source_format.m_internal_format)
3063 << ", " << glu::getTextureFormatName(source_format.m_format) << ", "
3064 << glu::getTypeStr(source_format.m_type)
3065 << ", DS: " << glu::getTextureDepthStencilModeName(source_format.m_ds_mode)
3066 << ". Swizzle: [" << glu::getTextureSwizzleStr(red) << ", "
3067 << glu::getTextureSwizzleStr(green) << ", " << glu::getTextureSwizzleStr(blue)
3068 << ", " << glu::getTextureSwizzleStr(alpha)
3069 << "]. Channel: " << channels[test_case.m_channel_index]
3070 << ". Access: " << texture_access[test_case.m_texture_access_index].m_name
3071 << ". Output texture: Format: "
3072 << glu::getTextureFormatName(output_format.m_internal_format) << ", "
3073 << glu::getTextureFormatName(output_format.m_format) << ", "
3074 << glu::getTypeStr(output_format.m_type) << "." << tcu::TestLog::EndMessage;
3077 /** Prepares program then draws and verifies resutls for both ways of setting texture swizzle
3079 * @param test_case Test case instance
3080 * @param output_format_index Index of format used by output texture
3081 * @parma output_channel_size Size of storage used by output texture in bits
3082 * @param index_of_swizzled_channel Index of swizzled channel
3083 * @param test_vertex_stage Selects if vertex or fragment shader should execute texture access
3085 void SmokeTest::prepareAndTestProgram(const testCase& test_case, size_t output_format_index,
3086 glw::GLint output_channel_size, size_t index_of_swizzled_channel,
3087 bool test_vertex_stage)
3089 const _texture_target& source_target = texture_targets[test_case.m_source_texture_target_index];
3090 const glw::GLint red = test_case.m_texture_swizzle_red;
3091 const glw::GLint green = test_case.m_texture_swizzle_green;
3092 const glw::GLint blue = test_case.m_texture_swizzle_blue;
3093 const glw::GLint alpha = test_case.m_texture_swizzle_alpha;
3094 const glw::GLint param[4] = { red, green, blue, alpha };
3097 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3099 /* Prepare program */
3100 const std::string& fs = getFragmentShader(test_case, output_format_index, !test_vertex_stage);
3101 const std::string& vs = getVertexShader(test_case, test_vertex_stage);
3103 Utils::programInfo program(m_context);
3104 program.build(fs.c_str(), vs.c_str());
3106 gl.useProgram(program.m_program_object_id);
3107 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
3109 /* Prepare sampler */
3110 glw::GLint location = gl.getUniformLocation(program.m_program_object_id, "sampler");
3111 GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformLocation");
3115 TCU_FAIL("Uniform is not available");
3118 gl.uniform1i(location, 0 /* texture unit */);
3119 GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i");
3121 draw(source_target.m_target, param, false);
3122 captureAndVerify(test_case, output_format_index, output_channel_size, index_of_swizzled_channel);
3124 draw(source_target.m_target, param, true);
3125 captureAndVerify(test_case, output_format_index, output_channel_size, index_of_swizzled_channel);
3128 /** Prepares arguments for texture access routine call
3130 * @param test_case Test case instance
3132 * @return Source code
3134 std::string SmokeTest::prepareArguments(const testCase& test_case)
3136 const _texture_access& access = texture_access[test_case.m_texture_access_index];
3137 const _texture_target& target = texture_targets[test_case.m_source_texture_target_index];
3139 std::string arguments = "COORDINATESLODDERIVATIVESOFFSETSSAMPLE";
3140 const std::string& coordinates = prepareCoordinates(test_case);
3142 size_t position = 0;
3144 Utils::replaceToken("COORDINATES", position, coordinates.c_str(), arguments);
3146 if ((true == access.m_use_lod) && (true == target.m_support_lod))
3148 Utils::replaceToken("LODDERIVATIVES", position, ", int(0)", arguments);
3150 else if (true == access.m_use_derivaties)
3152 const std::string& derivatives_0 = prepareDerivatives(test_case, 0);
3153 const std::string& derivatives_1 = prepareDerivatives(test_case, 1);
3154 const size_t start_pos = position;
3156 Utils::replaceToken("LODDERIVATIVES", position, ", XXXXX, XXXXX", arguments);
3157 position = start_pos + 2;
3158 Utils::replaceToken("XXXXX", position, derivatives_0.c_str(), arguments);
3159 Utils::replaceToken("XXXXX", position, derivatives_1.c_str(), arguments);
3163 Utils::replaceToken("LODDERIVATIVES", position, "", arguments);
3166 if (true == access.m_use_offsets)
3168 const std::string& offsets = prepareOffsets(test_case);
3169 const size_t start_pos = position;
3171 Utils::replaceToken("OFFSETS", position, ", XXXXX", arguments);
3172 position = start_pos + 2;
3173 Utils::replaceToken("XXXXX", position, offsets.c_str(), arguments);
3177 Utils::replaceToken("OFFSETS", position, "", arguments);
3180 if ((true == target.m_require_multisampling) && (true == access.m_support_multisampling))
3182 const std::string& sample = prepareSample();
3183 const size_t start_pos = position;
3185 Utils::replaceToken("SAMPLE", position, ", XX", arguments);
3186 position = start_pos + 2;
3187 Utils::replaceToken("XX", position, sample.c_str(), arguments);
3191 Utils::replaceToken("SAMPLE", position, "", arguments);
3197 /** Prepares coordinate for texture access routine call
3199 * @param test_case Test case instance
3201 * @return Source code
3203 std::string SmokeTest::prepareCoordinates(const testCase& test_case)
3205 const _texture_access& access = texture_access[test_case.m_texture_access_index];
3206 const _texture_target& target = texture_targets[test_case.m_source_texture_target_index];
3208 const glw::GLchar* type = 0;
3210 std::string coordinates = "TYPE(VAL_LIST)";
3212 if (false == access.m_use_integral_coordinates)
3214 switch (access.m_n_coordinates + target.m_n_array_coordinates + target.m_n_coordinates)
3229 TCU_FAIL("Invalid value");
3235 switch (access.m_n_coordinates + target.m_n_array_coordinates + target.m_n_coordinates)
3250 TCU_FAIL("Invalid value");
3255 size_t position = 0;
3257 Utils::replaceToken("TYPE", position, type, coordinates);
3259 for (size_t i = 0; i < target.m_n_coordinates; ++i)
3261 size_t start_position = position;
3263 Utils::replaceToken("VAL_LIST", position, "0, VAL_LIST", coordinates);
3265 position = start_position + 1;
3268 for (size_t i = 0; i < target.m_n_array_coordinates; ++i)
3270 size_t start_position = position;
3272 Utils::replaceToken("VAL_LIST", position, "0, VAL_LIST", coordinates);
3274 position = start_position + 1;
3277 for (size_t i = 0; i < access.m_n_coordinates; ++i)
3279 size_t start_position = position;
3281 Utils::replaceToken("VAL_LIST", position, "1, VAL_LIST", coordinates);
3283 position = start_position + 1;
3286 Utils::replaceToken(", VAL_LIST", position, "", coordinates);
3291 /** Prepares derivatives for texture access routine call
3293 * @param test_case Test case instance
3295 * @return Source code
3297 std::string SmokeTest::prepareDerivatives(const testCase& test_case, size_t index)
3299 const _texture_target& target = texture_targets[test_case.m_source_texture_target_index];
3301 const glw::GLchar* type = 0;
3303 std::string derivatives = "TYPE(VAL_LIST)";
3305 switch (target.m_n_derivatives)
3320 TCU_FAIL("Invalid value");
3324 size_t position = 0;
3326 Utils::replaceToken("TYPE", position, type, derivatives);
3328 for (size_t i = 0; i < target.m_n_derivatives; ++i)
3330 size_t start_position = position;
3334 Utils::replaceToken("VAL_LIST", position, "1.0, VAL_LIST", derivatives);
3338 Utils::replaceToken("VAL_LIST", position, "0.0, VAL_LIST", derivatives);
3341 position = start_position + 1;
3344 Utils::replaceToken(", VAL_LIST", position, "", derivatives);
3349 /** Prepares offsets for texture access routine call
3351 * @param test_case Test case instance
3353 * @return Source code
3355 std::string SmokeTest::prepareOffsets(const testCase& test_case)
3357 const _texture_target& target = texture_targets[test_case.m_source_texture_target_index];
3359 const glw::GLchar* type = DE_NULL;
3361 std::string offsets = "TYPE(VAL_LIST)";
3363 switch (target.m_n_derivatives)
3378 TCU_FAIL("Invalid value");
3382 size_t position = 0;
3384 Utils::replaceToken("TYPE", position, type, offsets);
3386 for (size_t i = 0; i < target.m_n_coordinates; ++i)
3388 size_t start_position = position;
3390 Utils::replaceToken("VAL_LIST", position, "0, VAL_LIST", offsets);
3392 position = start_position + 1;
3395 Utils::replaceToken(", VAL_LIST", position, "", offsets);
3400 /** Prepares output texture
3402 * @param format_idx Index of texture format
3404 void SmokeTest::prepareOutputTexture(size_t format_idx)
3406 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3408 const _texture_format& format = texture_formats[format_idx];
3410 gl.genTextures(1, &m_out_tex_id);
3411 GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
3413 gl.bindTexture(GL_TEXTURE_2D, m_out_tex_id);
3414 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
3416 gl.texImage2D(GL_TEXTURE_2D, 0 /* level */, format.m_internal_format, m_output_width, m_output_height,
3417 0 /* border */, format.m_format, format.m_type, 0 /* pixels */);
3418 GLU_EXPECT_NO_ERROR(gl.getError(), "TexImage2D");
3420 gl.bindTexture(GL_TEXTURE_2D, 0);
3421 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
3424 /** Prepares sample for texture access routine call
3426 * @return Source code
3428 std::string SmokeTest::prepareSample()
3430 glw::GLsizei samples = 1;
3431 std::stringstream stream;
3433 /* Get max number of samples */
3434 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3436 gl.getIntegerv(GL_MAX_SAMPLES, &samples);
3437 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
3439 stream << samples - 1;
3441 return stream.str();
3444 /** Prepares source texture
3446 * @param format_idx Index of texture format
3447 * @param target_idx Index of texture target
3448 * @param out_sizes Sizes of storage used for texture channels
3450 void SmokeTest::prepareSourceTexture(size_t format_idx, size_t target_idx, glw::GLint out_sizes[4])
3452 static const glw::GLint border = 0;
3453 static const glw::GLint level = 0;
3456 const glw::GLenum target = texture_targets[target_idx].m_target;
3457 const _texture_format& texture_format = texture_formats[format_idx];
3460 glw::GLenum error = 0;
3461 const glw::GLenum format = texture_format.m_format;
3462 const glw::GLchar* function_name = "unknown";
3463 const glw::GLenum internal_format = texture_format.m_internal_format;
3464 glw::GLsizei samples = 1;
3465 glw::GLenum target_get_prm = target;
3466 const glw::GLenum type = texture_format.m_type;
3469 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3471 /* Get max number of samples */
3472 gl.getIntegerv(GL_MAX_SAMPLES, &samples);
3473 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
3475 /* Generate and bind */
3476 gl.genTextures(1, &m_source_tex_id);
3477 GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
3479 gl.bindTexture(target, m_source_tex_id);
3480 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
3482 /* Allocate storage */
3487 gl.texImage1D(target, level, internal_format, m_width, border, format, type, 0 /* pixels */);
3488 error = gl.getError();
3489 function_name = "TexImage1D";
3493 case GL_TEXTURE_1D_ARRAY:
3495 case GL_TEXTURE_RECTANGLE:
3496 gl.texImage2D(target, level, internal_format, m_width, m_height, border, format, type, 0 /* pixels */);
3497 error = gl.getError();
3498 function_name = "TexImage2D";
3502 case GL_TEXTURE_2D_ARRAY:
3504 gl.texImage3D(target, level, internal_format, m_width, m_height, m_depth, border, format, type, 0 /* pixels */);
3505 error = gl.getError();
3506 function_name = "TexImage3D";
3510 case GL_TEXTURE_CUBE_MAP:
3511 for (size_t i = 0; i < n_cube_map_faces; ++i)
3513 gl.texImage2D(cube_map_faces[i], level, internal_format, m_width, m_height, border, format, type,
3516 error = gl.getError();
3517 function_name = "TexImage2D";
3519 target_get_prm = cube_map_faces[0];
3523 case GL_TEXTURE_2D_MULTISAMPLE:
3524 gl.texImage2DMultisample(target, samples, internal_format, m_width, m_height,
3525 GL_FALSE /* fixedsamplelocation */);
3526 error = gl.getError();
3527 function_name = "TexImage2DMultisample";
3531 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
3532 gl.texImage3DMultisample(target, samples, internal_format, m_width, m_height, m_depth,
3533 GL_FALSE /* fixedsamplelocation */);
3534 error = gl.getError();
3535 function_name = "TexImage3DMultisample";
3540 TCU_FAIL("Invalid enum");
3545 GLU_EXPECT_NO_ERROR(error, function_name);
3547 /* Make texture complete and set ds texture mode */
3548 if ((GL_TEXTURE_2D_MULTISAMPLE != target) && (GL_TEXTURE_2D_MULTISAMPLE_ARRAY != target) &&
3549 (GL_TEXTURE_RECTANGLE != target))
3551 gl.texParameteri(target, GL_TEXTURE_BASE_LEVEL, 0);
3552 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
3554 gl.texParameteri(target, GL_TEXTURE_MAX_LEVEL, 0);
3555 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
3557 gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3558 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
3560 gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3561 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
3564 if (texture_format.m_ds_mode == GL_STENCIL_INDEX)
3566 gl.texParameteri(target, GL_DEPTH_STENCIL_TEXTURE_MODE, texture_format.m_ds_mode);
3567 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
3570 /* Get internal storage sizes */
3571 switch (internal_format)
3573 case GL_DEPTH24_STENCIL8:
3574 case GL_DEPTH32F_STENCIL8:
3576 gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_STENCIL_SIZE, out_sizes + 1);
3577 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3581 case GL_DEPTH_COMPONENT16:
3582 case GL_DEPTH_COMPONENT24:
3583 case GL_DEPTH_COMPONENT32:
3584 case GL_DEPTH_COMPONENT32F:
3586 gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_DEPTH_SIZE, out_sizes + 0);
3587 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3593 gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_RED_SIZE, out_sizes + 0);
3594 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3596 gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_GREEN_SIZE, out_sizes + 1);
3597 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3599 gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_BLUE_SIZE, out_sizes + 2);
3600 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3602 gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_ALPHA_SIZE, out_sizes + 3);
3603 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3608 /* Unbind texture */
3609 gl.bindTexture(target, 0);
3610 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
3613 /** Initializes frame buffer and vertex array
3616 void SmokeTest::testInit()
3619 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3621 glw::GLint major = 0;
3622 glw::GLint minor = 0;
3624 gl.getIntegerv(GL_MAJOR_VERSION, &major);
3625 gl.getIntegerv(GL_MINOR_VERSION, &minor);
3627 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
3631 m_is_ms_supported = true;
3633 else if (4 == major)
3637 m_is_ms_supported = true;
3641 /* Context is below 4.3 */
3642 if (false == m_is_ms_supported)
3644 m_is_ms_supported = m_context.getContextInfo().isExtensionSupported("GL_ARB_texture_storage_multisample");
3649 gl.debugMessageCallback(debug_proc, &m_context);
3650 GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback");
3652 #endif /* ENABLE_DEBUG */
3655 gl.genFramebuffers(1, &m_prepare_fbo_id);
3656 GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
3658 gl.genFramebuffers(1, &m_test_fbo_id);
3659 GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
3661 /* Prepare blank VAO */
3662 gl.genVertexArrays(1, &m_vao_id);
3663 GLU_EXPECT_NO_ERROR(gl.getError(), "genVertexArrays");
3665 gl.bindVertexArray(m_vao_id);
3666 GLU_EXPECT_NO_ERROR(gl.getError(), "bindVertexArray");
3669 /** Verifies contents of output image
3671 * @param test_case Test case instance
3674 * @param index_of_swizzled_channel Index of swizzled channel
3675 * @param data Image contents
3677 void SmokeTest::verifyOutputImage(const testCase& test_case, size_t /* output_format_index */,
3678 glw::GLint /* output_channel_size */, size_t index_of_swizzled_channel,
3679 const glw::GLubyte* data)
3681 static const glw::GLuint rgba32ui[6] = { 0x3fffffff, 0x7fffffff, 0xbfffffff, 0xffffffff, 1, 0 };
3683 const _texture_format& source_format = texture_formats[test_case.m_source_texture_format_index];
3686 switch (source_format.m_internal_format)
3690 glw::GLuint expected_value = rgba32ui[index_of_swizzled_channel];
3691 const glw::GLuint* image = (glw::GLuint*)data;
3693 for (size_t i = 0; i < m_output_width * m_output_height; ++i)
3695 if (image[i] != expected_value)
3697 TCU_FAIL("Found pixel with wrong value");
3704 TCU_FAIL("Invalid enum");
3711 * @param context Rendering context.
3713 FunctionalTest::FunctionalTest(deqp::Context& context)
3714 : SmokeTest(context, "functional",
3715 "Verifies that swizzle is respected for textures of different formats and targets")
3717 /* Left blank intentionally */
3720 /** Executes test iteration.
3722 * @return Returns STOP.
3724 tcu::TestNode::IterateResult FunctionalTest::iterate()
3727 #if FUNCTIONAL_TEST_ALL_FORMATS == 0
3729 static const glw::GLenum tested_formats[] = { GL_R8, GL_R3_G3_B2, GL_RGBA16, GL_R11F_G11F_B10F,
3730 GL_RGB9_E5, GL_DEPTH32F_STENCIL8 };
3731 static const size_t n_tested_formats = sizeof(tested_formats) / sizeof(tested_formats[0]);
3733 #endif /* FUNCTIONAL_TEST_ALL_FORMATS == 0 */
3735 #if FUNCTIONAL_TEST_ALL_TARGETS == 0
3737 static const glw::GLenum tested_targets[] = { GL_TEXTURE_1D, GL_TEXTURE_2D_MULTISAMPLE_ARRAY };
3738 static const size_t n_tested_targets = sizeof(tested_targets) / sizeof(tested_targets[0]);
3740 #endif /* FUNCTIONAL_TEST_ALL_TARGETS == 0 */
3742 #if FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES == 0
3744 static const size_t access_idx = 4; /* 4 - index of "texelFetch" entry in texture_access_routines */
3746 #endif /* FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES == 0 */
3748 #if FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS == 0
3750 static const size_t tested_swizzle_combinations[][4] = { { 3, 2, 1,
3751 0 }, /* values are indices of entries in valid_values */
3756 static const size_t n_tested_swizzle_combinations =
3757 sizeof(tested_swizzle_combinations) / sizeof(tested_swizzle_combinations[0]);
3759 #endif /* FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS == 0 */
3762 bool test_result = true;
3763 glw::GLint source_channel_sizes[4] = { 0 };
3768 /* Iterate over all cases */
3770 #if FUNCTIONAL_TEST_ALL_FORMATS
3772 for (size_t format_idx = 0; format_idx < n_texture_formats; ++format_idx)
3775 /* Check that format is supported by context. */
3776 if (!glu::contextSupports(m_context.getRenderContext().getType(),
3777 texture_formats[format_idx].m_minimum_gl_context))
3782 #else /* FUNCTIONAL_TEST_ALL_FORMATS */
3784 for (size_t tested_format_idx = 0; tested_format_idx < n_tested_formats; ++tested_format_idx)
3786 const size_t format_idx = get_index_of_format(tested_formats[tested_format_idx]);
3788 #endif /* FUNCTIONAL_TEST_ALL_FORMATS */
3790 #if FUNCTIONAL_TEST_ALL_TARGETS
3792 for (size_t tgt_idx = 0; tgt_idx < n_texture_targets; ++tgt_idx)
3795 #else /* FUNCTIONAL_TEST_ALL_TARGETS */
3797 for (size_t tested_tgt_idx = 0; tested_tgt_idx < n_tested_targets; ++tested_tgt_idx)
3799 const size_t tgt_idx = get_index_of_target(tested_targets[tested_tgt_idx]);
3801 #endif /* FUNCTIONAL_TEST_ALL_TARGETS */
3803 /* Skip not supported targets */
3804 if (false == isTargetSupported(tgt_idx))
3809 /* Skip invalid cases */
3810 if (false == isTargetSuppByFormat(format_idx, tgt_idx))
3817 prepareSourceTexture(format_idx, tgt_idx, source_channel_sizes);
3819 /* Skip formats not supported by FBO */
3820 if (false == fillSourceTexture(format_idx, tgt_idx))
3826 #if FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES
3828 for (size_t access_idx = 0; access_idx < n_texture_access; ++access_idx)
3830 /* Skip invalid cases */
3831 if (false == isTargetSuppByAccess(access_idx, tgt_idx))
3835 #else /* FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES */
3836 /* Skip invalid cases */
3837 if (false == isTargetSuppByAccess(access_idx, tgt_idx))
3842 #endif /* FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES */
3844 #if FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS
3846 for (size_t r = 0; r < n_valid_values; ++r)
3848 for (size_t g = 0; g < n_valid_values; ++g)
3850 for (size_t b = 0; b < n_valid_values; ++b)
3852 for (size_t a = 0; a < n_valid_values; ++a)
3855 #else /* FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS */
3857 for (size_t tested_swizzle_idx = 0; tested_swizzle_idx < n_tested_swizzle_combinations;
3858 ++tested_swizzle_idx)
3860 const size_t r = tested_swizzle_combinations[tested_swizzle_idx][0];
3861 const size_t g = tested_swizzle_combinations[tested_swizzle_idx][1];
3862 const size_t b = tested_swizzle_combinations[tested_swizzle_idx][2];
3863 const size_t a = tested_swizzle_combinations[tested_swizzle_idx][3];
3865 #endif /* FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS */
3867 for (size_t channel_idx = 0; channel_idx < 4; ++channel_idx)
3869 const testCase test_case = { channel_idx,
3877 { source_channel_sizes[0], source_channel_sizes[1],
3878 source_channel_sizes[2],
3879 source_channel_sizes[3] } };
3881 executeTestCase(test_case);
3883 deinitOutputTexture();
3884 } /* iteration over channels */
3886 #if FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS
3888 /* iteration over swizzle combinations */
3894 #else /* FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS */
3896 } /* iteration over swizzle combinations */
3898 #endif /* FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS */
3900 #if FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES
3902 } /* iteration over access routines - only when enabled */
3904 #endif /* FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES */
3907 catch (wrongResults& exc)
3909 logTestCaseDetials(exc.m_test_case);
3910 m_context.getTestContext().getLog() << tcu::TestLog::Message << exc.what() << tcu::TestLog::EndMessage;
3912 test_result = false;
3920 } /* iteration over texture targets */
3922 } /* iteration over texture formats */
3925 if (true == test_result)
3927 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
3931 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
3938 /** Fills multisampled source texture
3940 * @param format_idx Index of format
3941 * @param target_idx Index of target
3943 * @return True if operation was successful, false other wise
3945 bool FunctionalTest::fillMSTexture(size_t format_idx, size_t target_idx)
3947 const glw::GLenum target = texture_targets[target_idx].m_target;
3950 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3953 gl.bindFramebuffer(GL_FRAMEBUFFER, m_prepare_fbo_id);
3954 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
3956 /* Attach texture */
3959 case GL_TEXTURE_2D_MULTISAMPLE:
3961 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, m_source_tex_id, 0 /* level */);
3962 GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture2D");
3966 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
3968 gl.framebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_source_tex_id, 0 /* level */, 0 /* layer */);
3969 GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture2D");
3974 TCU_FAIL("Invalid enum");
3979 const glw::GLenum status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
3980 GLU_EXPECT_NO_ERROR(gl.getError(), "CheckFramebufferStatus");
3982 if (GL_FRAMEBUFFER_UNSUPPORTED == status)
3985 gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
3986 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
3990 else if (GL_FRAMEBUFFER_COMPLETE != status)
3992 TCU_FAIL("Framebuffer is incomplete. Format is supported");
3996 gl.viewport(0 /* x */, 0 /* y */, m_output_width, m_output_height);
3997 GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
3999 Utils::programInfo program(m_context);
4000 prepareProgram(format_idx, program);
4002 gl.useProgram(program.m_program_object_id);
4003 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
4006 gl.clear(GL_COLOR_BUFFER_BIT);
4007 GLU_EXPECT_NO_ERROR(gl.getError(), "Clear");
4010 gl.drawArrays(GL_TRIANGLE_STRIP, 0 /* first */, 4 /* count */);
4011 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
4014 gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
4015 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
4021 /** Fills source texture
4023 * @param format_idx Index of format
4024 * @param target_idx Index of target
4026 * @return True if operation was successful, false other wise
4028 bool FunctionalTest::fillSourceTexture(size_t format_idx, size_t target_idx)
4030 const glw::GLenum target = texture_targets[target_idx].m_target;
4031 const _texture_format& format = texture_formats[format_idx];
4034 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4040 gl.bindTexture(target, m_source_tex_id);
4041 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
4043 /* Attach texture */
4047 gl.texSubImage1D(target, 0 /* level */, 0 /* x */, m_width, format.m_format, format.m_type,
4048 format.m_source_data);
4049 GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage1D");
4053 case GL_TEXTURE_1D_ARRAY:
4055 case GL_TEXTURE_RECTANGLE:
4056 gl.texSubImage2D(target, 0 /* level */, 0 /* x */, 0 /* y */, m_width, m_height, format.m_format, format.m_type,
4057 format.m_source_data);
4058 GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D");
4062 case GL_TEXTURE_2D_ARRAY:
4064 gl.texSubImage3D(target, 0 /* level */, 0 /* x */, 0 /* y */, 0 /* z */, m_width, m_height, m_depth,
4065 format.m_format, format.m_type, format.m_source_data);
4066 GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage3D");
4070 case GL_TEXTURE_CUBE_MAP:
4071 for (size_t i = 0; i < n_cube_map_faces; ++i)
4073 gl.texSubImage2D(cube_map_faces[i], 0 /* level */, 0 /* x */, 0 /* y */, m_width, m_height, format.m_format,
4074 format.m_type, format.m_source_data);
4075 GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D");
4080 case GL_TEXTURE_2D_MULTISAMPLE:
4081 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
4082 result = fillMSTexture(format_idx, target_idx);
4087 TCU_FAIL("Invalid enum");
4092 gl.bindTexture(target, 0);
4093 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
4099 /** Prepares program used to fill multisampled texture
4101 * @param format_idx Index of texture format
4102 * @param program Instance of program that will be prepared
4104 void FunctionalTest::prepareProgram(size_t format_idx, Utils::programInfo& program)
4106 static const glw::GLchar* fs_template = "#version 330 core\n"
4108 "out PREFIXvec4 out_color;\n"
4112 " out_color = PREFIXvec4(VALUES);\n"
4116 const _texture_format& format = texture_formats[format_idx];
4117 const std::string& values = prepareValues(format_idx);
4118 const std::string& vs = getVertexShader(testCase(), false); /* Get blank VS */
4120 std::string fs = fs_template;
4121 size_t position = 0;
4123 Utils::replaceToken("PREFIX", position, format.m_sampler.m_sampler_prefix, fs);
4124 Utils::replaceToken("PREFIX", position, format.m_sampler.m_sampler_prefix, fs);
4125 Utils::replaceToken("VALUES", position, values.c_str(), fs);
4127 program.build(fs.c_str(), vs.c_str());
4130 /** Prepares hardcoded values used by program to fill multisampled textures
4132 * @param format_idx Index of texture format
4134 * @return Shader source
4136 std::string FunctionalTest::prepareValues(size_t format_idx)
4138 double ch_rgba[4] = { 0.0, 0.0, 0.0, 0.0 };
4140 calculate_values_from_source(format_idx, ch_rgba);
4142 /* Prepare string */
4143 std::stringstream stream;
4144 stream << ch_rgba[0] << ", " << ch_rgba[1] << ", " << ch_rgba[2] << ", " << ch_rgba[3];
4146 return stream.str();
4149 /** Verifies if value is in <low:top> range
4151 * @tparam T Type oo values
4153 * @param value Value to check
4154 * @param low Lowest acceptable value
4155 * @param top Highest acceptable value
4157 * @return true if value is in range, false otherwise
4159 template <typename T>
4160 bool isInRange(const void* value, const void* low, const void* top)
4162 const T* v_ptr = (const T*)value;
4163 const T* l_ptr = (const T*)low;
4164 const T* t_ptr = (const T*)top;
4166 if ((*v_ptr > *t_ptr) || (*v_ptr < *l_ptr))
4174 /** Verifies contents of output image
4176 * @param test_case Test case instance
4177 * @param output_format_index Index of format used by output texture
4178 * @parma output_channel_size Size of storage used by output texture in bits
4179 * @param index_of_swizzled_channel Index of swizzled channel
4180 * @param data Image contents
4182 void FunctionalTest::verifyOutputImage(const testCase& test_case, size_t output_format_index,
4183 glw::GLint output_channel_size, size_t index_of_swizzled_channel,
4184 const glw::GLubyte* data)
4186 const _texture_format& output_format = texture_formats[output_format_index];
4188 glw::GLubyte expected_data_low[8] = { 0 };
4189 glw::GLubyte expected_data_top[8] = { 0 };
4190 size_t texel_size = 0;
4192 calculate_expected_value(test_case.m_source_texture_format_index, output_format_index, index_of_swizzled_channel,
4193 test_case.m_texture_sizes[index_of_swizzled_channel], output_channel_size,
4194 expected_data_low, expected_data_top, texel_size);
4196 for (size_t i = 0; i < m_output_height * m_output_width; ++i)
4198 const size_t offset = i * texel_size;
4199 const glw::GLvoid* pointer = data + offset;
4203 switch (output_format.m_type)
4206 res = isInRange<glw::GLbyte>(pointer, expected_data_low, expected_data_top);
4208 case GL_UNSIGNED_BYTE:
4209 res = isInRange<glw::GLubyte>(pointer, expected_data_low, expected_data_top);
4212 res = isInRange<glw::GLshort>(pointer, expected_data_low, expected_data_top);
4214 case GL_UNSIGNED_SHORT:
4215 res = isInRange<glw::GLushort>(pointer, expected_data_low, expected_data_top);
4218 res = isInRange<glw::GLbyte>(pointer, expected_data_low, expected_data_top);
4221 res = isInRange<glw::GLint>(pointer, expected_data_low, expected_data_top);
4223 case GL_UNSIGNED_INT:
4224 res = isInRange<glw::GLhalf>(pointer, expected_data_low, expected_data_top);
4227 res = isInRange<glw::GLfloat>(pointer, expected_data_low, expected_data_top);
4230 TCU_FAIL("Invalid enum");
4236 throw wrongResults(test_case);
4244 * @param context Rendering context.
4246 TextureSwizzleTests::TextureSwizzleTests(deqp::Context& context)
4247 : TestCaseGroup(context, "texture_swizzle", "Verifies \"texture_swizzle\" functionality")
4249 /* Left blank on purpose */
4252 /** Initializes a texture_storage_multisample test group.
4255 void TextureSwizzleTests::init(void)
4257 addChild(new TextureSwizzle::APIErrorsTest(m_context));
4258 addChild(new TextureSwizzle::IntialStateTest(m_context));
4259 addChild(new TextureSwizzle::SmokeTest(m_context));
4260 addChild(new TextureSwizzle::FunctionalTest(m_context));
4262 } /* glcts namespace */