• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2015-2016 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */ /*!
20  * \file
21  * \brief
22  */ /*-------------------------------------------------------------------*/
23 
24 /**
25  * \file  gl3TextureSwizzleTests.cpp
26  * \brief Implements conformance tests for "Texture Swizzle" functionality.
27  */ /*-------------------------------------------------------------------*/
28 
29 #include "gl3cTextureSwizzleTests.hpp"
30 #include "gluContextInfo.hpp"
31 #include "gluStrUtil.hpp"
32 #include "glwFunctions.hpp"
33 #include "tcuFloat.hpp"
34 #include "tcuTestLog.hpp"
35 
36 #include "deMath.h"
37 #include <cmath>
38 
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 */
44 
45 namespace gl3cts
46 {
47 namespace TextureSwizzle
48 {
49 /* Static constants use by tests */
50 /* One and zero */
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 };
75 
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 };
112 
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);
116 
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 */ };
152 
153 /* Texture channels */
154 static const glw::GLchar* channels[] = { "r", "g", "b", "a" };
155 
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]);
161 
162 /* Swizzle states */
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]);
166 
167 /* Sampler descriptor */
168 struct _sampler
169 {
170 	const glw::GLchar* m_basic_type;
171 	const glw::GLchar* m_sampler_prefix;
172 };
173 static const _sampler isampler = { "int", "i" };
174 static const _sampler usampler = { "uint", "u" };
175 static const _sampler sampler  = { "float", "" };
176 
177 /* Output channel descriptor */
178 struct _out_ch_desc
179 {
180 	glw::GLenum		   m_internal_format;
181 	const glw::GLvoid* m_expected_data;
182 };
183 
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 };
211 
212 /* Texture format descriptor. Maps texture format with output channel descriptors, source data and sampler descriptor */
213 struct _texture_format
214 {
215 	const glu::ApiType  m_minimum_gl_context;
216 	glw::GLenum			m_internal_format;
217 	glw::GLenum			m_format;
218 	glw::GLenum			m_type;
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;
228 };
229 static const _texture_format texture_formats[] = {
230 	/* 0  */ { glu::ApiType::core(3, 0),
231 			   GL_R8,
232 			   GL_RED,
233 			   GL_UNSIGNED_BYTE,
234 			   GL_DEPTH_COMPONENT,
235 			   sampler,
236 			   { GL_R8, DE_NULL },
237 			   zero_ch,
238 			   zero_ch,
239 			   one_ch,
240 			   src_data_r8,
241 			   unorm8_zero,
242 			   unorm8_one },
243 	{ glu::ApiType::core(3, 1),
244 	  GL_R8_SNORM,
245 	  GL_RED,
246 	  GL_BYTE,
247 	  GL_DEPTH_COMPONENT,
248 	  sampler,
249 	  { GL_R8_SNORM, DE_NULL },
250 	  zero_ch,
251 	  zero_ch,
252 	  one_ch,
253 	  src_data_r8_snorm,
254 	  snorm8_zero,
255 	  snorm8_one },
256 	{ glu::ApiType::core(3, 0),
257 	  GL_R16,
258 	  GL_RED,
259 	  GL_UNSIGNED_SHORT,
260 	  GL_DEPTH_COMPONENT,
261 	  sampler,
262 	  { GL_R16, DE_NULL },
263 	  zero_ch,
264 	  zero_ch,
265 	  one_ch,
266 	  src_data_r16,
267 	  unorm16_zero,
268 	  unorm16_one },
269 	{ glu::ApiType::core(3, 1),
270 	  GL_R16_SNORM,
271 	  GL_RED,
272 	  GL_SHORT,
273 	  GL_DEPTH_COMPONENT,
274 	  sampler,
275 	  { GL_R16_SNORM, DE_NULL },
276 	  zero_ch,
277 	  zero_ch,
278 	  one_ch,
279 	  src_data_r16_snorm,
280 	  snorm16_zero,
281 	  snorm16_one },
282 	{ glu::ApiType::core(3, 0),
283 	  GL_RG8,
284 	  GL_RG,
285 	  GL_UNSIGNED_BYTE,
286 	  GL_DEPTH_COMPONENT,
287 	  sampler,
288 	  { GL_R8, DE_NULL },
289 	  { GL_R8, DE_NULL },
290 	  zero_ch,
291 	  one_ch,
292 	  src_data_rg8,
293 	  unorm8_zero,
294 	  unorm8_one },
295 	{ glu::ApiType::core(3, 1),
296 	  GL_RG8_SNORM,
297 	  GL_RG,
298 	  GL_BYTE,
299 	  GL_DEPTH_COMPONENT,
300 	  sampler,
301 	  { GL_R8_SNORM, DE_NULL },
302 	  { GL_R8_SNORM, DE_NULL },
303 	  zero_ch,
304 	  one_ch,
305 	  src_data_rg8_snorm,
306 	  snorm8_zero,
307 	  snorm8_one },
308 	{ glu::ApiType::core(3, 0),
309 	  GL_RG16,
310 	  GL_RG,
311 	  GL_UNSIGNED_SHORT,
312 	  GL_DEPTH_COMPONENT,
313 	  sampler,
314 	  { GL_R16, DE_NULL },
315 	  { GL_R16, DE_NULL },
316 	  zero_ch,
317 	  one_ch,
318 	  src_data_rg16,
319 	  unorm16_zero,
320 	  unorm16_one },
321 	{ glu::ApiType::core(3, 1),
322 	  GL_RG16_SNORM,
323 	  GL_RG,
324 	  GL_SHORT,
325 	  GL_DEPTH_COMPONENT,
326 	  sampler,
327 	  { GL_R16_SNORM, DE_NULL },
328 	  { GL_R16_SNORM, DE_NULL },
329 	  zero_ch,
330 	  one_ch,
331 	  src_data_rg16_snorm,
332 	  snorm16_zero,
333 	  snorm16_one },
334 	/* 8  */ { glu::ApiType::core(4, 4),
335 			   GL_R3_G3_B2,
336 			   GL_RGB,
337 			   GL_UNSIGNED_BYTE_3_3_2,
338 			   GL_DEPTH_COMPONENT,
339 			   sampler,
340 			   { GL_R8, DE_NULL },
341 			   { GL_R8, DE_NULL },
342 			   { GL_R8, DE_NULL },
343 			   one_ch,
344 			   src_data_r3_g3_b2,
345 			   unorm8_zero,
346 			   unorm8_one },
347 	{ glu::ApiType::core(4, 4),
348 	  GL_RGB4,
349 	  GL_RGB,
350 	  GL_UNSIGNED_SHORT_5_6_5,
351 	  GL_DEPTH_COMPONENT,
352 	  sampler,
353 	  { GL_R8, DE_NULL },
354 	  { GL_R8, DE_NULL },
355 	  { GL_R8, DE_NULL },
356 	  one_ch,
357 	  src_data_rgb4,
358 	  unorm8_zero,
359 	  unorm8_one },
360 	{ glu::ApiType::core(4, 4),
361 	  GL_RGB5,
362 	  GL_RGB,
363 	  GL_UNSIGNED_SHORT_5_6_5,
364 	  GL_DEPTH_COMPONENT,
365 	  sampler,
366 	  { GL_R8, DE_NULL },
367 	  { GL_R8, DE_NULL },
368 	  { GL_R8, DE_NULL },
369 	  one_ch,
370 	  src_data_rgb5,
371 	  unorm8_zero,
372 	  unorm8_one },
373 	{ glu::ApiType::core(3, 0),
374 	  GL_RGB8,
375 	  GL_RGB,
376 	  GL_UNSIGNED_BYTE,
377 	  GL_DEPTH_COMPONENT,
378 	  sampler,
379 	  { GL_R8, DE_NULL },
380 	  { GL_R8, DE_NULL },
381 	  { GL_R8, DE_NULL },
382 	  one_ch,
383 	  src_data_rgb8,
384 	  unorm8_zero,
385 	  unorm8_one },
386 	{ glu::ApiType::core(3, 1),
387 	  GL_RGB8_SNORM,
388 	  GL_RGB,
389 	  GL_BYTE,
390 	  GL_DEPTH_COMPONENT,
391 	  sampler,
392 	  { GL_R8_SNORM, DE_NULL },
393 	  { GL_R8_SNORM, DE_NULL },
394 	  { GL_R8_SNORM, DE_NULL },
395 	  one_ch,
396 	  src_data_rgb8_snorm,
397 	  snorm8_zero,
398 	  snorm8_one },
399 	{ glu::ApiType::core(4, 4),
400 	  GL_RGB10,
401 	  GL_RGB,
402 	  GL_UNSIGNED_SHORT,
403 	  GL_DEPTH_COMPONENT,
404 	  sampler,
405 	  { GL_R16, DE_NULL },
406 	  { GL_R16, DE_NULL },
407 	  { GL_R16, DE_NULL },
408 	  one_ch,
409 	  src_data_rgb16,
410 	  unorm16_zero,
411 	  unorm16_one },
412 	{ glu::ApiType::core(4, 4),
413 	  GL_RGB12,
414 	  GL_RGB,
415 	  GL_UNSIGNED_SHORT,
416 	  GL_DEPTH_COMPONENT,
417 	  sampler,
418 	  { GL_R16, DE_NULL },
419 	  { GL_R16, DE_NULL },
420 	  { GL_R16, DE_NULL },
421 	  one_ch,
422 	  src_data_rgb16,
423 	  unorm16_zero,
424 	  unorm16_one },
425 	{ glu::ApiType::core(3, 0),
426 	  GL_RGB16,
427 	  GL_RGB,
428 	  GL_UNSIGNED_SHORT,
429 	  GL_DEPTH_COMPONENT,
430 	  sampler,
431 	  { GL_R16, DE_NULL },
432 	  { GL_R16, DE_NULL },
433 	  { GL_R16, DE_NULL },
434 	  one_ch,
435 	  src_data_rgb16,
436 	  unorm16_zero,
437 	  unorm16_one },
438 	/* 16 */ { glu::ApiType::core(3, 1),
439 			   GL_RGB16_SNORM,
440 			   GL_RGB,
441 			   GL_SHORT,
442 			   GL_DEPTH_COMPONENT,
443 			   sampler,
444 			   { GL_R16_SNORM, DE_NULL },
445 			   { GL_R16_SNORM, DE_NULL },
446 			   { GL_R16_SNORM, DE_NULL },
447 			   one_ch,
448 			   src_data_rgb16_snorm,
449 			   snorm16_zero,
450 			   snorm16_one },
451 	{ glu::ApiType::core(4, 4),
452 	  GL_RGBA2,
453 	  GL_RGBA,
454 	  GL_UNSIGNED_SHORT_4_4_4_4,
455 	  GL_DEPTH_COMPONENT,
456 	  sampler,
457 	  { GL_R8, DE_NULL },
458 	  { GL_R8, DE_NULL },
459 	  { GL_R8, DE_NULL },
460 	  { GL_R8, DE_NULL },
461 	  src_data_rgba4,
462 	  unorm8_zero,
463 	  unorm8_one },
464 	{ glu::ApiType::core(4, 2),
465 	  GL_RGBA4,
466 	  GL_RGBA,
467 	  GL_UNSIGNED_SHORT_4_4_4_4,
468 	  GL_DEPTH_COMPONENT,
469 	  sampler,
470 	  { GL_R8, DE_NULL },
471 	  { GL_R8, DE_NULL },
472 	  { GL_R8, DE_NULL },
473 	  { GL_R8, DE_NULL },
474 	  src_data_rgba4,
475 	  unorm8_zero,
476 	  unorm8_one },
477 	{ glu::ApiType::core(4, 2),
478 	  GL_RGB5_A1,
479 	  GL_RGBA,
480 	  GL_UNSIGNED_SHORT_5_5_5_1,
481 	  GL_DEPTH_COMPONENT,
482 	  sampler,
483 	  { GL_R8, DE_NULL },
484 	  { GL_R8, DE_NULL },
485 	  { GL_R8, DE_NULL },
486 	  { GL_R8, DE_NULL },
487 	  src_data_rgb5_a1,
488 	  unorm8_zero,
489 	  unorm8_one },
490 	{ glu::ApiType::core(3, 0),
491 	  GL_RGBA8,
492 	  GL_RGBA,
493 	  GL_UNSIGNED_BYTE,
494 	  GL_DEPTH_COMPONENT,
495 	  sampler,
496 	  { GL_R8, DE_NULL },
497 	  { GL_R8, DE_NULL },
498 	  { GL_R8, DE_NULL },
499 	  { GL_R8, DE_NULL },
500 	  src_data_rgba8,
501 	  unorm8_zero,
502 	  unorm8_one },
503 	{ glu::ApiType::core(3, 1),
504 	  GL_RGBA8_SNORM,
505 	  GL_RGBA,
506 	  GL_BYTE,
507 	  GL_DEPTH_COMPONENT,
508 	  sampler,
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,
514 	  snorm8_zero,
515 	  snorm8_one },
516 	{ glu::ApiType::core(3, 0),
517 	  GL_RGB10_A2,
518 	  GL_RGBA,
519 	  GL_UNSIGNED_INT_10_10_10_2,
520 	  GL_DEPTH_COMPONENT,
521 	  sampler,
522 	  { GL_R16, DE_NULL },
523 	  { GL_R16, DE_NULL },
524 	  { GL_R16, DE_NULL },
525 	  { GL_R16, DE_NULL },
526 	  src_data_rgb10_a2,
527 	  unorm16_zero,
528 	  unorm16_one },
529 	{ glu::ApiType::core(3, 3),
530 	  GL_RGB10_A2UI,
531 	  GL_RGBA_INTEGER,
532 	  GL_UNSIGNED_INT_10_10_10_2,
533 	  GL_DEPTH_COMPONENT,
534 	  usampler,
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 },
539 	  src_data_rgb10_a2,
540 	  uint16_zero,
541 	  uint16_one },
542 	/* 24 */ { glu::ApiType::core(4, 4),
543 			   GL_RGBA12,
544 			   GL_RGBA,
545 			   GL_UNSIGNED_SHORT,
546 			   GL_DEPTH_COMPONENT,
547 			   sampler,
548 			   { GL_R16, DE_NULL },
549 			   { GL_R16, DE_NULL },
550 			   { GL_R16, DE_NULL },
551 			   { GL_R16, DE_NULL },
552 			   src_data_rgba16,
553 			   unorm16_zero,
554 			   unorm16_one },
555 	{ glu::ApiType::core(3, 0),
556 	  GL_RGBA16,
557 	  GL_RGBA,
558 	  GL_UNSIGNED_SHORT,
559 	  GL_DEPTH_COMPONENT,
560 	  sampler,
561 	  { GL_R16, DE_NULL },
562 	  { GL_R16, DE_NULL },
563 	  { GL_R16, DE_NULL },
564 	  { GL_R16, DE_NULL },
565 	  src_data_rgba16,
566 	  unorm16_zero,
567 	  unorm16_one },
568 	{ glu::ApiType::core(3, 1),
569 	  GL_RGBA16_SNORM,
570 	  GL_RGBA,
571 	  GL_SHORT,
572 	  GL_DEPTH_COMPONENT,
573 	  sampler,
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,
579 	  snorm16_zero,
580 	  snorm16_one },
581 	{ glu::ApiType::core(3, 0),
582 	  GL_SRGB8,
583 	  GL_RGB,
584 	  GL_UNSIGNED_BYTE,
585 	  GL_DEPTH_COMPONENT,
586 	  sampler,
587 	  { GL_R8, exp_data_srgb8_alpha8 + 0 },
588 	  { GL_R8, exp_data_srgb8_alpha8 + 1 },
589 	  { GL_R8, exp_data_srgb8_alpha8 + 2 },
590 	  one_ch,
591 	  src_data_srgb8_alpha8,
592 	  unorm8_zero,
593 	  unorm8_one },
594 	{ glu::ApiType::core(3, 0),
595 	  GL_SRGB8_ALPHA8,
596 	  GL_RGBA,
597 	  GL_UNSIGNED_BYTE,
598 	  GL_DEPTH_COMPONENT,
599 	  sampler,
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,
605 	  unorm8_zero,
606 	  unorm8_one },
607 	{ glu::ApiType::core(3, 0),
608 	  GL_R16F,
609 	  GL_RED,
610 	  GL_HALF_FLOAT,
611 	  GL_DEPTH_COMPONENT,
612 	  sampler,
613 	  { GL_R16F, src_data_r16f + 0 },
614 	  zero_ch,
615 	  zero_ch,
616 	  one_ch,
617 	  src_data_r16f,
618 	  float16_zero,
619 	  float16_one },
620 	{ glu::ApiType::core(3, 0),
621 	  GL_RG16F,
622 	  GL_RG,
623 	  GL_HALF_FLOAT,
624 	  GL_DEPTH_COMPONENT,
625 	  sampler,
626 	  { GL_R16F, src_data_rg16f + 0 },
627 	  { GL_R16F, src_data_rg16f + 1 },
628 	  zero_ch,
629 	  one_ch,
630 	  src_data_rg16f,
631 	  float16_zero,
632 	  float16_one },
633 	{ glu::ApiType::core(3, 0),
634 	  GL_RGB16F,
635 	  GL_RGB,
636 	  GL_HALF_FLOAT,
637 	  GL_DEPTH_COMPONENT,
638 	  sampler,
639 	  { GL_R16F, src_data_rgb16f + 0 },
640 	  { GL_R16F, src_data_rgb16f + 1 },
641 	  { GL_R16F, src_data_rgb16f + 2 },
642 	  one_ch,
643 	  src_data_rgb16f,
644 	  float16_zero,
645 	  float16_one },
646 	/* 32 */ { glu::ApiType::core(3, 0),
647 			   GL_RGBA16F,
648 			   GL_RGBA,
649 			   GL_HALF_FLOAT,
650 			   GL_DEPTH_COMPONENT,
651 			   sampler,
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 },
656 			   src_data_rgba16f,
657 			   float16_zero,
658 			   float16_one },
659 	{ glu::ApiType::core(3, 0),
660 	  GL_R32F,
661 	  GL_RED,
662 	  GL_FLOAT,
663 	  GL_DEPTH_COMPONENT,
664 	  sampler,
665 	  { GL_R32F, src_data_r32f + 0 },
666 	  zero_ch,
667 	  zero_ch,
668 	  one_ch,
669 	  src_data_r32f,
670 	  float32_zero,
671 	  float32_one },
672 	{ glu::ApiType::core(3, 0),
673 	  GL_RG32F,
674 	  GL_RG,
675 	  GL_FLOAT,
676 	  GL_DEPTH_COMPONENT,
677 	  sampler,
678 	  { GL_R32F, src_data_rg32f + 0 },
679 	  { GL_R32F, src_data_rg32f + 1 },
680 	  zero_ch,
681 	  one_ch,
682 	  src_data_rg32f,
683 	  float32_zero,
684 	  float32_one },
685 	{ glu::ApiType::core(3, 0),
686 	  GL_RGB32F,
687 	  GL_RGB,
688 	  GL_FLOAT,
689 	  GL_DEPTH_COMPONENT,
690 	  sampler,
691 	  { GL_R32F, src_data_rgb32f + 0 },
692 	  { GL_R32F, src_data_rgb32f + 1 },
693 	  { GL_R32F, src_data_rgb32f + 2 },
694 	  one_ch,
695 	  src_data_rgb32f,
696 	  float32_zero,
697 	  float32_one },
698 	{ glu::ApiType::core(3, 0),
699 	  GL_RGBA32F,
700 	  GL_RGBA,
701 	  GL_FLOAT,
702 	  GL_DEPTH_COMPONENT,
703 	  sampler,
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 },
708 	  src_data_rgba32f,
709 	  float32_zero,
710 	  float32_one },
711 	{ glu::ApiType::core(3, 0),
712 	  GL_R11F_G11F_B10F,
713 	  GL_RGB,
714 	  GL_UNSIGNED_INT_10F_11F_11F_REV,
715 	  GL_DEPTH_COMPONENT,
716 	  sampler,
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 },
720 	  one_ch,
721 	  src_data_r11f_g11f_b10f,
722 	  float16_zero,
723 	  float16_one },
724 	{ glu::ApiType::core(3, 0),
725 	  GL_RGB9_E5,
726 	  GL_RGB,
727 	  GL_UNSIGNED_INT_5_9_9_9_REV,
728 	  GL_DEPTH_COMPONENT,
729 	  sampler,
730 	  { GL_R32F, exp_data_rgb9_e5 + 0 },
731 	  { GL_R32F, exp_data_rgb9_e5 + 1 },
732 	  { GL_R32F, exp_data_rgb9_e5 + 2 },
733 	  one_ch,
734 	  src_data_rgb9_e5,
735 	  float32_zero,
736 	  float32_one },
737 	{ glu::ApiType::core(3, 0),
738 	  GL_R8I,
739 	  GL_RED_INTEGER,
740 	  GL_BYTE,
741 	  GL_DEPTH_COMPONENT,
742 	  isampler,
743 	  { GL_R8I, src_data_r8i },
744 	  zero_ch,
745 	  zero_ch,
746 	  one_ch,
747 	  src_data_r8i,
748 	  sint8_zero,
749 	  sint8_one },
750 	/* 40 */ { glu::ApiType::core(3, 0),
751 			   GL_R8UI,
752 			   GL_RED_INTEGER,
753 			   GL_UNSIGNED_BYTE,
754 			   GL_DEPTH_COMPONENT,
755 			   usampler,
756 			   { GL_R8UI, src_data_r8ui },
757 			   zero_ch,
758 			   zero_ch,
759 			   one_ch,
760 			   src_data_r8ui,
761 			   uint8_zero,
762 			   uint8_one },
763 	{ glu::ApiType::core(3, 0),
764 	  GL_R16I,
765 	  GL_RED_INTEGER,
766 	  GL_SHORT,
767 	  GL_DEPTH_COMPONENT,
768 	  isampler,
769 	  { GL_R16I, src_data_r16i },
770 	  zero_ch,
771 	  zero_ch,
772 	  one_ch,
773 	  src_data_r16i,
774 	  sint16_zero,
775 	  sint16_one },
776 	{ glu::ApiType::core(3, 0),
777 	  GL_R16UI,
778 	  GL_RED_INTEGER,
779 	  GL_UNSIGNED_SHORT,
780 	  GL_DEPTH_COMPONENT,
781 	  usampler,
782 	  { GL_R16UI, src_data_r16ui },
783 	  zero_ch,
784 	  zero_ch,
785 	  one_ch,
786 	  src_data_r16ui,
787 	  uint16_zero,
788 	  uint16_one },
789 	{ glu::ApiType::core(3, 0),
790 	  GL_R32I,
791 	  GL_RED_INTEGER,
792 	  GL_INT,
793 	  GL_DEPTH_COMPONENT,
794 	  isampler,
795 	  { GL_R32I, src_data_r32i },
796 	  zero_ch,
797 	  zero_ch,
798 	  one_ch,
799 	  src_data_r32i,
800 	  sint32_zero,
801 	  sint32_one },
802 	{ glu::ApiType::core(3, 0),
803 	  GL_R32UI,
804 	  GL_RED_INTEGER,
805 	  GL_UNSIGNED_INT,
806 	  GL_DEPTH_COMPONENT,
807 	  usampler,
808 	  { GL_R32UI, src_data_r32ui },
809 	  zero_ch,
810 	  zero_ch,
811 	  one_ch,
812 	  src_data_r32ui,
813 	  uint32_zero,
814 	  uint32_one },
815 	{ glu::ApiType::core(3, 0),
816 	  GL_RG8I,
817 	  GL_RG_INTEGER,
818 	  GL_BYTE,
819 	  GL_DEPTH_COMPONENT,
820 	  isampler,
821 	  { GL_R8I, src_data_rg8i + 0 },
822 	  { GL_R8I, src_data_rg8i + 1 },
823 	  zero_ch,
824 	  one_ch,
825 	  src_data_rg8i,
826 	  sint8_zero,
827 	  sint8_one },
828 	{ glu::ApiType::core(3, 0),
829 	  GL_RG8UI,
830 	  GL_RG_INTEGER,
831 	  GL_UNSIGNED_BYTE,
832 	  GL_DEPTH_COMPONENT,
833 	  usampler,
834 	  { GL_R8UI, src_data_rg8ui + 0 },
835 	  { GL_R8UI, src_data_rg8ui + 1 },
836 	  zero_ch,
837 	  one_ch,
838 	  src_data_rg8ui,
839 	  uint8_zero,
840 	  uint8_one },
841 	{ glu::ApiType::core(3, 0),
842 	  GL_RG16I,
843 	  GL_RG_INTEGER,
844 	  GL_SHORT,
845 	  GL_DEPTH_COMPONENT,
846 	  isampler,
847 	  { GL_R16I, src_data_rg16i + 0 },
848 	  { GL_R16I, src_data_rg16i + 1 },
849 	  zero_ch,
850 	  one_ch,
851 	  src_data_rg16i,
852 	  sint16_zero,
853 	  sint16_one },
854 	/* 48 */ { glu::ApiType::core(3, 0),
855 			   GL_RG16UI,
856 			   GL_RG_INTEGER,
857 			   GL_UNSIGNED_SHORT,
858 			   GL_DEPTH_COMPONENT,
859 			   usampler,
860 			   { GL_R16UI, src_data_rg16ui + 0 },
861 			   { GL_R16UI, src_data_rg16ui + 1 },
862 			   zero_ch,
863 			   one_ch,
864 			   src_data_rg16ui,
865 			   uint16_zero,
866 			   uint16_one },
867 	{ glu::ApiType::core(3, 0),
868 	  GL_RG32I,
869 	  GL_RG_INTEGER,
870 	  GL_INT,
871 	  GL_DEPTH_COMPONENT,
872 	  isampler,
873 	  { GL_R32I, src_data_rg32i + 0 },
874 	  { GL_R32I, src_data_rg32i + 1 },
875 	  zero_ch,
876 	  one_ch,
877 	  src_data_rg32i,
878 	  sint32_zero,
879 	  sint32_one },
880 	{ glu::ApiType::core(3, 0),
881 	  GL_RG32UI,
882 	  GL_RG_INTEGER,
883 	  GL_UNSIGNED_INT,
884 	  GL_DEPTH_COMPONENT,
885 	  usampler,
886 	  { GL_R32UI, src_data_rg32ui + 0 },
887 	  { GL_R32UI, src_data_rg32ui + 1 },
888 	  zero_ch,
889 	  one_ch,
890 	  src_data_rg32ui,
891 	  uint32_zero,
892 	  uint32_one },
893 	{ glu::ApiType::core(3, 0),
894 	  GL_RGB8I,
895 	  GL_RGB_INTEGER,
896 	  GL_BYTE,
897 	  GL_DEPTH_COMPONENT,
898 	  isampler,
899 	  { GL_R8I, src_data_rgb8i + 0 },
900 	  { GL_R8I, src_data_rgb8i + 1 },
901 	  { GL_R8I, src_data_rgb8i + 2 },
902 	  one_ch,
903 	  src_data_rgb8i,
904 	  sint8_zero,
905 	  sint8_one },
906 	{ glu::ApiType::core(3, 0),
907 	  GL_RGB8UI,
908 	  GL_RGB_INTEGER,
909 	  GL_UNSIGNED_BYTE,
910 	  GL_DEPTH_COMPONENT,
911 	  usampler,
912 	  { GL_R8UI, src_data_rgb8ui + 0 },
913 	  { GL_R8UI, src_data_rgb8ui + 1 },
914 	  { GL_R8UI, src_data_rgb8ui + 2 },
915 	  one_ch,
916 	  src_data_rgb8ui,
917 	  uint8_zero,
918 	  uint8_one },
919 	{ glu::ApiType::core(3, 0),
920 	  GL_RGB16I,
921 	  GL_RGB_INTEGER,
922 	  GL_SHORT,
923 	  GL_DEPTH_COMPONENT,
924 	  isampler,
925 	  { GL_R16I, src_data_rgb16i + 0 },
926 	  { GL_R16I, src_data_rgb16i + 1 },
927 	  { GL_R16I, src_data_rgb16i + 2 },
928 	  one_ch,
929 	  src_data_rgb16i,
930 	  sint16_zero,
931 	  sint16_one },
932 	{ glu::ApiType::core(3, 0),
933 	  GL_RGB16UI,
934 	  GL_RGB_INTEGER,
935 	  GL_UNSIGNED_SHORT,
936 	  GL_DEPTH_COMPONENT,
937 	  usampler,
938 	  { GL_R16UI, src_data_rgb16ui + 0 },
939 	  { GL_R16UI, src_data_rgb16ui + 1 },
940 	  { GL_R16UI, src_data_rgb16ui + 2 },
941 	  one_ch,
942 	  src_data_rgb16ui,
943 	  uint16_zero,
944 	  uint16_one },
945 	{ glu::ApiType::core(3, 0),
946 	  GL_RGB32I,
947 	  GL_RGB_INTEGER,
948 	  GL_INT,
949 	  GL_DEPTH_COMPONENT,
950 	  isampler,
951 	  { GL_R32I, src_data_rgb32i + 0 },
952 	  { GL_R32I, src_data_rgb32i + 1 },
953 	  { GL_R32I, src_data_rgb32i + 2 },
954 	  one_ch,
955 	  src_data_rgb32i,
956 	  sint32_zero,
957 	  sint32_one },
958 	/* 56 */ { glu::ApiType::core(3, 0),
959 			   GL_RGB32UI,
960 			   GL_RGB_INTEGER,
961 			   GL_UNSIGNED_INT,
962 			   GL_DEPTH_COMPONENT,
963 			   usampler,
964 			   { GL_R32UI, src_data_rgb32ui + 0 },
965 			   { GL_R32UI, src_data_rgb32ui + 1 },
966 			   { GL_R32UI, src_data_rgb32ui + 2 },
967 			   one_ch,
968 			   src_data_rgb32ui,
969 			   uint32_zero,
970 			   uint32_one },
971 	{ glu::ApiType::core(3, 0),
972 	  GL_RGBA8I,
973 	  GL_RGBA_INTEGER,
974 	  GL_BYTE,
975 	  GL_DEPTH_COMPONENT,
976 	  isampler,
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 },
981 	  src_data_rgba8i,
982 	  sint8_zero,
983 	  sint8_one },
984 	{ glu::ApiType::core(3, 0),
985 	  GL_RGBA8UI,
986 	  GL_RGBA_INTEGER,
987 	  GL_UNSIGNED_BYTE,
988 	  GL_DEPTH_COMPONENT,
989 	  usampler,
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 },
994 	  src_data_rgba8ui,
995 	  uint8_zero,
996 	  uint8_one },
997 	{ glu::ApiType::core(3, 0),
998 	  GL_RGBA16I,
999 	  GL_RGBA_INTEGER,
1000 	  GL_SHORT,
1001 	  GL_DEPTH_COMPONENT,
1002 	  isampler,
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 },
1007 	  src_data_rgba16i,
1008 	  sint16_zero,
1009 	  sint16_one },
1010 	{ glu::ApiType::core(3, 0),
1011 	  GL_RGBA16UI,
1012 	  GL_RGBA_INTEGER,
1013 	  GL_UNSIGNED_SHORT,
1014 	  GL_DEPTH_COMPONENT,
1015 	  usampler,
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 },
1020 	  src_data_rgba16ui,
1021 	  uint16_zero,
1022 	  uint16_one },
1023 	{ glu::ApiType::core(3, 0),
1024 	  GL_RGBA32I,
1025 	  GL_RGBA_INTEGER,
1026 	  GL_INT,
1027 	  GL_DEPTH_COMPONENT,
1028 	  isampler,
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 },
1033 	  src_data_rgba32i,
1034 	  sint32_zero,
1035 	  sint32_one },
1036 	{ glu::ApiType::core(3, 0),
1037 	  GL_RGBA32UI,
1038 	  GL_RGBA_INTEGER,
1039 	  GL_UNSIGNED_INT,
1040 	  GL_DEPTH_COMPONENT,
1041 	  usampler,
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 },
1046 	  src_data_rgba32ui,
1047 	  uint32_zero,
1048 	  uint32_one },
1049 	{ glu::ApiType::core(3, 0),
1050 	  GL_DEPTH_COMPONENT16,
1051 	  GL_DEPTH_COMPONENT,
1052 	  GL_UNSIGNED_SHORT,
1053 	  GL_DEPTH_COMPONENT,
1054 	  sampler,
1055 	  { GL_R16, src_data_depth_component16 },
1056 	  zero_ch,
1057 	  zero_ch,
1058 	  one_ch,
1059 	  src_data_depth_component16,
1060 	  unorm16_zero,
1061 	  unorm16_one },
1062 	/* 64 */ { glu::ApiType::core(3, 0),
1063 			   GL_DEPTH_COMPONENT24,
1064 			   GL_DEPTH_COMPONENT,
1065 			   GL_UNSIGNED_INT,
1066 			   GL_DEPTH_COMPONENT,
1067 			   sampler,
1068 			   { GL_R32F, exp_data_depth_component32 },
1069 			   zero_ch,
1070 			   zero_ch,
1071 			   one_ch,
1072 			   src_data_depth_component32,
1073 			   float32_zero,
1074 			   float32_one },
1075 	{ glu::ApiType::core(3, 0),
1076 	  GL_DEPTH_COMPONENT32,
1077 	  GL_DEPTH_COMPONENT,
1078 	  GL_UNSIGNED_INT,
1079 	  GL_DEPTH_COMPONENT,
1080 	  sampler,
1081 	  { GL_R32F, exp_data_depth_component32 },
1082 	  zero_ch,
1083 	  zero_ch,
1084 	  one_ch,
1085 	  src_data_depth_component32,
1086 	  float32_zero,
1087 	  float32_one },
1088 	{ glu::ApiType::core(3, 0),
1089 	  GL_DEPTH_COMPONENT32F,
1090 	  GL_DEPTH_COMPONENT,
1091 	  GL_FLOAT,
1092 	  GL_DEPTH_COMPONENT,
1093 	  sampler,
1094 	  { GL_R32F, src_data_depth_component32f },
1095 	  zero_ch,
1096 	  zero_ch,
1097 	  one_ch,
1098 	  src_data_depth_component32f,
1099 	  float32_zero,
1100 	  float32_one },
1101 	{ glu::ApiType::core(3, 0),
1102 	  GL_DEPTH24_STENCIL8,
1103 	  GL_DEPTH_STENCIL,
1104 	  GL_UNSIGNED_INT_24_8,
1105 	  GL_DEPTH_COMPONENT,
1106 	  sampler,
1107 	  { GL_R32F, exp_data_depth_component32 },
1108 	  zero_ch,
1109 	  zero_ch,
1110 	  one_ch,
1111 	  src_data_depth24_stencil8,
1112 	  float32_zero,
1113 	  float32_one },
1114 	{ glu::ApiType::core(3, 0),
1115 	  GL_DEPTH32F_STENCIL8,
1116 	  GL_DEPTH_STENCIL,
1117 	  GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
1118 	  GL_DEPTH_COMPONENT,
1119 	  sampler,
1120 	  { GL_R32F, exp_data_depth_component32 },
1121 	  zero_ch,
1122 	  zero_ch,
1123 	  one_ch,
1124 	  src_data_depth32f_stencil8,
1125 	  float32_zero,
1126 	  float32_one },
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 }
1131 };
1132 static const size_t n_texture_formats = sizeof(texture_formats) / sizeof(texture_formats[0]);
1133 
1134 /* Texture access routine descriptors */
1135 struct _texture_access
1136 {
1137 	const glw::GLchar* m_name;
1138 	size_t			   m_n_coordinates;
1139 	bool			   m_use_derivaties;
1140 	bool			   m_use_integral_coordinates;
1141 	bool			   m_use_lod;
1142 	bool			   m_use_offsets;
1143 	bool			   m_support_multisampling;
1144 };
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]);
1160 
1161 /* Texture target descriptor */
1162 struct _texture_target
1163 {
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;
1169 	bool			   m_support_lod;
1170 	bool			   m_support_offset;
1171 	bool			   m_supports_proj;
1172 	bool			   m_require_multisampling;
1173 	glw::GLenum		   m_target;
1174 };
1175 
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 },
1186 };
1187 static const size_t n_texture_targets = sizeof(texture_targets) / sizeof(texture_targets[0]);
1188 
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]);
1192 
1193 /* Prototypes */
1194 const _out_ch_desc& get_descriptor_for_channel(const _texture_format& format, const size_t channel);
1195 
1196 #if ENABLE_DEBUG
1197 
1198 /** Debuging procedure. Logs parameters.
1199  *
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.
1204  * @param ignored
1205  * @param message  As specified in GL spec.
1206  * @param info     Pointer to instance of deqp::Context used by test.
1207  */
debug_proc(glw::GLenum source,glw::GLenum type,glw::GLuint id,glw::GLenum severity,glw::GLsizei,const glw::GLchar * message,void * info)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)
1210 {
1211 	Context* ctx = (Context*)info;
1212 
1213 	const glw::GLchar* source_str   = "Unknown";
1214 	const glw::GLchar* type_str		= "Unknown";
1215 	const glw::GLchar* severity_str = "Unknown";
1216 
1217 	switch (source)
1218 	{
1219 	case GL_DEBUG_SOURCE_API:
1220 		source_str = "API";
1221 		break;
1222 	case GL_DEBUG_SOURCE_APPLICATION:
1223 		source_str = "APP";
1224 		break;
1225 	case GL_DEBUG_SOURCE_OTHER:
1226 		source_str = "OTR";
1227 		break;
1228 	case GL_DEBUG_SOURCE_SHADER_COMPILER:
1229 		source_str = "COM";
1230 		break;
1231 	case GL_DEBUG_SOURCE_THIRD_PARTY:
1232 		source_str = "3RD";
1233 		break;
1234 	case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1235 		source_str = "WS";
1236 		break;
1237 	default:
1238 		break;
1239 	}
1240 
1241 	switch (type)
1242 	{
1243 	case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1244 		type_str = "DEPRECATED_BEHAVIOR";
1245 		break;
1246 	case GL_DEBUG_TYPE_ERROR:
1247 		type_str = "ERROR";
1248 		break;
1249 	case GL_DEBUG_TYPE_MARKER:
1250 		type_str = "MARKER";
1251 		break;
1252 	case GL_DEBUG_TYPE_OTHER:
1253 		type_str = "OTHER";
1254 		break;
1255 	case GL_DEBUG_TYPE_PERFORMANCE:
1256 		type_str = "PERFORMANCE";
1257 		break;
1258 	case GL_DEBUG_TYPE_POP_GROUP:
1259 		type_str = "POP_GROUP";
1260 		break;
1261 	case GL_DEBUG_TYPE_PORTABILITY:
1262 		type_str = "PORTABILITY";
1263 		break;
1264 	case GL_DEBUG_TYPE_PUSH_GROUP:
1265 		type_str = "PUSH_GROUP";
1266 		break;
1267 	case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1268 		type_str = "UNDEFINED_BEHAVIOR";
1269 		break;
1270 	default:
1271 		break;
1272 	}
1273 
1274 	switch (severity)
1275 	{
1276 	case GL_DEBUG_SEVERITY_HIGH:
1277 		severity_str = "H";
1278 		break;
1279 	case GL_DEBUG_SEVERITY_LOW:
1280 		severity_str = "L";
1281 		break;
1282 	case GL_DEBUG_SEVERITY_MEDIUM:
1283 		severity_str = "M";
1284 		break;
1285 	case GL_DEBUG_SEVERITY_NOTIFICATION:
1286 		severity_str = "N";
1287 		break;
1288 	default:
1289 		break;
1290 	}
1291 
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;
1295 }
1296 
1297 #endif /* ENABLE_DEBUG */
1298 
1299 /** Extracts value of each channel from source data of given format
1300  *
1301  * @param format_idx  Index of format
1302  * @param out_ch_rgba Storage for values
1303  **/
calculate_values_from_source(size_t format_idx,double out_ch_rgba[4])1304 void calculate_values_from_source(size_t format_idx, double out_ch_rgba[4])
1305 {
1306 	const _texture_format& format = texture_formats[format_idx];
1307 
1308 	/*  */
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;
1316 
1317 	/* Select n_channels and is_norm */
1318 	switch (format.m_format)
1319 	{
1320 	case GL_RED_INTEGER:
1321 		is_norm = false;
1322 	/* fall through */
1323 
1324 	case GL_RED:
1325 		n_channels = 1;
1326 
1327 		break;
1328 
1329 	case GL_RG_INTEGER:
1330 		is_norm = false;
1331 	/* fall through */
1332 
1333 	case GL_RG:
1334 		n_channels = 2;
1335 
1336 		break;
1337 
1338 	case GL_RGB_INTEGER:
1339 		is_norm = false;
1340 	/* fall through */
1341 
1342 	case GL_RGB:
1343 		n_channels = 3;
1344 
1345 		break;
1346 
1347 	case GL_RGBA_INTEGER:
1348 		is_norm = false;
1349 	/* fall through */
1350 
1351 	case GL_RGBA:
1352 		n_channels = 4;
1353 
1354 		break;
1355 
1356 	default:
1357 		TCU_FAIL("Unsupported format");
1358 	}
1359 
1360 	/* Calculate rgba values */
1361 	if ((GL_SRGB8 == format.m_internal_format) || (GL_SRGB8_ALPHA8 == format.m_internal_format))
1362 	{
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];
1368 
1369 		ch_r = r;
1370 		ch_g = g;
1371 		ch_b = b;
1372 		ch_a = a;
1373 
1374 		ch_r /= 255.0;
1375 		ch_g /= 255.0;
1376 		ch_b /= 255.0;
1377 		ch_a /= 255.0;
1378 	}
1379 	else if (GL_UNSIGNED_BYTE_3_3_2 == format.m_type)
1380 	{
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;
1385 
1386 		ch_r = r;
1387 		ch_g = g;
1388 		ch_b = b;
1389 
1390 		ch_r /= 7.0;
1391 		ch_g /= 7.0;
1392 		ch_b /= 3.0;
1393 	}
1394 	else if (GL_UNSIGNED_SHORT_5_6_5 == format.m_type)
1395 	{
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;
1400 
1401 		ch_r = r;
1402 		ch_g = g;
1403 		ch_b = b;
1404 
1405 		ch_r /= 31.0;
1406 		ch_g /= 63.0;
1407 		ch_b /= 31.0;
1408 	}
1409 	else if (GL_UNSIGNED_SHORT_4_4_4_4 == format.m_type)
1410 	{
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);
1416 
1417 		ch_r = r;
1418 		ch_g = g;
1419 		ch_b = b;
1420 		ch_a = a;
1421 
1422 		ch_r /= 15.0;
1423 		ch_g /= 15.0;
1424 		ch_b /= 15.0;
1425 		ch_a /= 15.0;
1426 	}
1427 	else if (GL_UNSIGNED_SHORT_5_5_5_1 == format.m_type)
1428 	{
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;
1434 
1435 		ch_r = r;
1436 		ch_g = g;
1437 		ch_b = b;
1438 		ch_a = a;
1439 
1440 		ch_r /= 31.0;
1441 		ch_g /= 31.0;
1442 		ch_b /= 31.0;
1443 		ch_a /= 1.0;
1444 	}
1445 	else if (GL_UNSIGNED_INT_10_10_10_2 == format.m_type)
1446 	{
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;
1452 
1453 		ch_r = r;
1454 		ch_g = g;
1455 		ch_b = b;
1456 		ch_a = a;
1457 
1458 		if (true == is_norm)
1459 		{
1460 			ch_r /= 1023.0;
1461 			ch_g /= 1023.0;
1462 			ch_b /= 1023.0;
1463 			ch_a /= 3.0;
1464 		}
1465 	}
1466 	else if (GL_UNSIGNED_INT_10F_11F_11F_REV == format.m_type)
1467 	{
1468 		ch_r = r11f.asDouble();
1469 		ch_g = g11f.asDouble();
1470 		ch_b = b10f.asDouble();
1471 	}
1472 	else if (GL_UNSIGNED_INT_5_9_9_9_REV == format.m_type)
1473 	{
1474 		TCU_FAIL("Not supported: GL_UNSIGNED_INT_5_9_9_9_REV");
1475 	}
1476 	else if (GL_UNSIGNED_INT_24_8 == format.m_type)
1477 	{
1478 		TCU_FAIL("Not supported: GL_UNSIGNED_INT_24_8");
1479 	}
1480 	else if (GL_FLOAT_32_UNSIGNED_INT_24_8_REV == format.m_type)
1481 	{
1482 		TCU_FAIL("Not supported: GL_FLOAT_32_UNSIGNED_INT_24_8_REV");
1483 	}
1484 	else if (GL_BYTE == format.m_type)
1485 	{
1486 		const glw::GLbyte* ptr = (const glw::GLbyte*)format.m_source_data;
1487 
1488 		for (size_t i = 0; i < n_channels; ++i)
1489 		{
1490 			const glw::GLbyte val = ptr[i];
1491 			double&			  ch  = ch_rgba[i];
1492 
1493 			ch = val;
1494 			if (true == is_norm)
1495 				ch /= 127.0;
1496 		}
1497 	}
1498 	else if (GL_UNSIGNED_BYTE == format.m_type)
1499 	{
1500 		const glw::GLubyte* ptr = (const glw::GLubyte*)format.m_source_data;
1501 
1502 		for (size_t i = 0; i < n_channels; ++i)
1503 		{
1504 			const glw::GLubyte val = ptr[i];
1505 			double&			   ch  = ch_rgba[i];
1506 
1507 			ch = val;
1508 			if (true == is_norm)
1509 				ch /= 255.0;
1510 		}
1511 	}
1512 	else if (GL_SHORT == format.m_type)
1513 	{
1514 		const glw::GLshort* ptr = (const glw::GLshort*)format.m_source_data;
1515 
1516 		for (size_t i = 0; i < n_channels; ++i)
1517 		{
1518 			const glw::GLshort val = ptr[i];
1519 			double&			   ch  = ch_rgba[i];
1520 
1521 			ch = val;
1522 			if (true == is_norm)
1523 				ch /= 32767.0;
1524 		}
1525 	}
1526 	else if (GL_UNSIGNED_SHORT == format.m_type)
1527 	{
1528 		const glw::GLushort* ptr = (const glw::GLushort*)format.m_source_data;
1529 
1530 		for (size_t i = 0; i < n_channels; ++i)
1531 		{
1532 			const glw::GLushort val = ptr[i];
1533 			double&				ch  = ch_rgba[i];
1534 
1535 			ch = val;
1536 			if (true == is_norm)
1537 				ch /= 65535.0;
1538 		}
1539 	}
1540 	else if (GL_INT == format.m_type)
1541 	{
1542 		const glw::GLint* ptr = (const glw::GLint*)format.m_source_data;
1543 
1544 		for (size_t i = 0; i < n_channels; ++i)
1545 		{
1546 			const glw::GLint val = ptr[i];
1547 			double&			 ch  = ch_rgba[i];
1548 
1549 			ch = val;
1550 			if (true == is_norm)
1551 				ch /= 2147483647.0;
1552 		}
1553 	}
1554 	else if (GL_UNSIGNED_INT == format.m_type)
1555 	{
1556 		const glw::GLuint* ptr = (const glw::GLuint*)format.m_source_data;
1557 
1558 		for (size_t i = 0; i < n_channels; ++i)
1559 		{
1560 			const glw::GLuint val = ptr[i];
1561 			double&			  ch  = ch_rgba[i];
1562 
1563 			ch = val;
1564 			if (true == is_norm)
1565 				ch /= 4294967295.0;
1566 		}
1567 	}
1568 	else if (GL_FLOAT == format.m_type)
1569 	{
1570 		const glw::GLfloat* ptr = (const glw::GLfloat*)format.m_source_data;
1571 
1572 		for (size_t i = 0; i < n_channels; ++i)
1573 		{
1574 			const glw::GLfloat val = ptr[i];
1575 			double&			   ch  = ch_rgba[i];
1576 
1577 			ch = val;
1578 		}
1579 	}
1580 	else if (GL_HALF_FLOAT == format.m_type)
1581 	{
1582 		const glw::GLhalf* ptr = (const glw::GLhalf*)format.m_source_data;
1583 
1584 		for (size_t i = 0; i < n_channels; ++i)
1585 		{
1586 			const glw::GLhalf val = ptr[i];
1587 			double&			  ch  = ch_rgba[i];
1588 
1589 			tcu::Float16 f16(val);
1590 			ch = f16.asDouble();
1591 		}
1592 	}
1593 	else
1594 	{
1595 		TCU_FAIL("Invalid enum");
1596 	}
1597 
1598 	/* Store results */
1599 	memcpy(out_ch_rgba, ch_rgba, 4 * sizeof(double));
1600 }
1601 
1602 /** Calculate maximum uint value for given size of storage
1603  *
1604  * @param size Size of storage in bits
1605  *
1606  * @return Calculated max
1607  **/
calculate_max_for_size(size_t size)1608 double calculate_max_for_size(size_t size)
1609 {
1610 	double power = pow(2.0, double(size));
1611 
1612 	return power - 1.0;
1613 }
1614 
1615 /** Converts from double to given T
1616  *
1617  * @tparam Requested type of value
1618  *
1619  * @param out_expected_data Storage for converted value
1620  * @param value             Value to be converted
1621  **/
1622 template <typename T>
convert(void * out_expected_data,double value)1623 void convert(void* out_expected_data, double value)
1624 {
1625 	T* ptr = (T*)out_expected_data;
1626 
1627 	*ptr = T(value);
1628 }
1629 
1630 /** Calcualte range of expected values
1631  *
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
1640  **/
calculate_expected_value(size_t source_format_idx,size_t output_format_idx,size_t index_of_swizzled_channel,glw::GLint source_size,glw::GLint output_size,void * out_expected_data_low,void * out_expected_data_top,size_t & out_expected_data_size)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)
1644 {
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;
1653 
1654 	/* Select range, texel size and is_signed */
1655 	switch (output_format.m_type)
1656 	{
1657 	case GL_BYTE:
1658 		is_signed = true;
1659 
1660 		range_low = -127.0;
1661 		range_top = 127.0;
1662 
1663 		texel_size = 1;
1664 
1665 		break;
1666 
1667 	case GL_UNSIGNED_BYTE:
1668 		range_low = 0.0;
1669 		range_top = 255.0;
1670 
1671 		texel_size = 1;
1672 
1673 		break;
1674 
1675 	case GL_SHORT:
1676 		is_signed = true;
1677 
1678 		range_low = -32767.0;
1679 		range_top = 32767.0;
1680 
1681 		texel_size = 2;
1682 
1683 		break;
1684 
1685 	case GL_UNSIGNED_SHORT:
1686 		range_low = 0.0;
1687 		range_top = 65535.0;
1688 
1689 		texel_size = 2;
1690 
1691 		break;
1692 
1693 	case GL_HALF_FLOAT:
1694 		texel_size = 2;
1695 
1696 		/* Halfs are not calculated, range will not be used */
1697 
1698 		break;
1699 
1700 	case GL_INT:
1701 		is_signed = true;
1702 
1703 		range_low = -2147483647.0;
1704 		range_top = 2147483647.0;
1705 
1706 		texel_size = 4;
1707 
1708 		break;
1709 
1710 	case GL_UNSIGNED_INT:
1711 		range_low = 0.0;
1712 		range_top = 4294967295.0;
1713 
1714 		texel_size = 4;
1715 
1716 		break;
1717 
1718 	case GL_FLOAT:
1719 		texel_size = 4;
1720 
1721 		/* Float are not calculated, range will not be used */
1722 
1723 		break;
1724 
1725 	default:
1726 		TCU_FAIL("Invalid enum");
1727 		break;
1728 	}
1729 
1730 	/* Signed formats use one bit less */
1731 	if (true == is_signed)
1732 	{
1733 		source_size -= 1;
1734 		output_size -= 1;
1735 	}
1736 
1737 	/* If expected data is hardcoded just copy data to low and top */
1738 	if (DE_NULL != expected_data)
1739 	{
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;
1743 	}
1744 	else
1745 	{
1746 		/* Get source values */
1747 		double ch_rgba[4];
1748 		calculate_values_from_source(source_format_idx, ch_rgba);
1749 
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);
1764 
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);
1768 
1769 		/* Store resuts */
1770 		switch (output_format.m_type)
1771 		{
1772 		case GL_BYTE:
1773 			convert<glw::GLbyte>(out_expected_data_low, stor_output_low);
1774 			convert<glw::GLbyte>(out_expected_data_top, stor_output_top);
1775 			break;
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);
1779 			break;
1780 		case GL_SHORT:
1781 			convert<glw::GLshort>(out_expected_data_low, stor_output_low);
1782 			convert<glw::GLshort>(out_expected_data_top, stor_output_top);
1783 			break;
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);
1787 			break;
1788 		case GL_INT:
1789 			convert<glw::GLint>(out_expected_data_low, stor_output_low);
1790 			convert<glw::GLint>(out_expected_data_top, stor_output_top);
1791 			break;
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);
1795 			break;
1796 		default:
1797 			TCU_FAIL("Invalid enum");
1798 			break;
1799 		}
1800 		out_expected_data_size = texel_size;
1801 	}
1802 }
1803 
1804 /** Gets index of internal format in texture_fomrats
1805  *
1806  * @param internal_format Internal format to be found
1807  *
1808  * @return Found index. -1 when format is not available. 0 when GL_ZERO is requested.
1809  **/
get_index_of_format(glw::GLenum internal_format)1810 size_t get_index_of_format(glw::GLenum internal_format)
1811 {
1812 	if (GL_ZERO == internal_format)
1813 	{
1814 		return 0;
1815 	}
1816 
1817 	for (size_t i = 0; i < n_texture_formats; ++i)
1818 	{
1819 		if (texture_formats[i].m_internal_format == internal_format)
1820 		{
1821 			return i;
1822 		}
1823 	}
1824 
1825 	TCU_FAIL("Unknown internal format");
1826 	return -1;
1827 }
1828 
1829 /** Gets index of target in texture_targets
1830  *
1831  * @param target target to be found
1832  *
1833  * @return Found index. -1 when format is not available. 0 when GL_ZERO is requested.
1834  **/
get_index_of_target(glw::GLenum target)1835 size_t get_index_of_target(glw::GLenum target)
1836 {
1837 	if (GL_ZERO == target)
1838 	{
1839 		return 0;
1840 	}
1841 
1842 	for (size_t i = 0; i < n_texture_targets; ++i)
1843 	{
1844 		if (texture_targets[i].m_target == target)
1845 		{
1846 			return i;
1847 		}
1848 	}
1849 
1850 	TCU_FAIL("Unknown texture target");
1851 	return -1;
1852 }
1853 
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;
1857 
1858 /** Get index of channel that will be accessed after "swizzle" is applied
1859  *
1860  * @param channel_idx Index of channel before "swizzle" is applied
1861  * @param swizzle_set Set of swizzle states
1862  *
1863  * @return Index of "swizzled" channel
1864  */
get_swizzled_channel_idx(const size_t channel_idx,const glw::GLint swizzle_set[4])1865 size_t get_swizzled_channel_idx(const size_t channel_idx, const glw::GLint swizzle_set[4])
1866 {
1867 	const glw::GLint swizzle = swizzle_set[channel_idx];
1868 
1869 	size_t channel = 0;
1870 
1871 	switch (swizzle)
1872 	{
1873 	case GL_RED:
1874 		channel = 0;
1875 		break;
1876 	case GL_GREEN:
1877 		channel = 1;
1878 		break;
1879 	case GL_BLUE:
1880 		channel = 2;
1881 		break;
1882 	case GL_ALPHA:
1883 		channel = 3;
1884 		break;
1885 	case GL_ONE:
1886 		channel = CHANNEL_INDEX_ONE;
1887 		break;
1888 	case GL_ZERO:
1889 		channel = CHANNEL_INDEX_ZERO;
1890 		break;
1891 	default:
1892 		TCU_FAIL("Invalid value");
1893 		break;
1894 	}
1895 
1896 	return channel;
1897 }
1898 
1899 /** Gets descriptor of output channel from texture format descriptor
1900  *
1901  * @param format  Format descriptor
1902  * @param channel Index of "swizzled" channel
1903  *
1904  * @return Descriptor of output channel
1905  **/
get_descriptor_for_channel(const _texture_format & format,const size_t channel)1906 const _out_ch_desc& get_descriptor_for_channel(const _texture_format& format, const size_t channel)
1907 {
1908 	const _out_ch_desc* desc = 0;
1909 
1910 	switch (channel)
1911 	{
1912 	case CHANNEL_INDEX_ONE:
1913 		desc = &format.m_one_ch;
1914 		break;
1915 	case CHANNEL_INDEX_ZERO:
1916 		desc = &format.m_zero_ch;
1917 		break;
1918 	case 0:
1919 		desc = &format.m_red_ch;
1920 		break;
1921 	case 1:
1922 		desc = &format.m_green_ch;
1923 		break;
1924 	case 2:
1925 		desc = &format.m_blue_ch;
1926 		break;
1927 	case 3:
1928 		desc = &format.m_alpha_ch;
1929 		break;
1930 	default:
1931 		TCU_FAIL("Invalid value");
1932 		break;
1933 	};
1934 
1935 	switch (desc->m_internal_format)
1936 	{
1937 	case GL_ONE:
1938 		desc = &format.m_one_ch;
1939 		break;
1940 	case GL_ZERO:
1941 		desc = &format.m_zero_ch;
1942 		break;
1943 	default:
1944 		break;
1945 	}
1946 
1947 	return *desc;
1948 }
1949 
1950 /** Gets internal_format of output channel for given texture format
1951  *
1952  * @param format  Format descriptor
1953  * @param channel Index of "swizzled" channel
1954  *
1955  * @return Internal format
1956  **/
get_internal_format_for_channel(const _texture_format & format,const size_t channel)1957 glw::GLenum get_internal_format_for_channel(const _texture_format& format, const size_t channel)
1958 {
1959 	return get_descriptor_for_channel(format, channel).m_internal_format;
1960 }
1961 
1962 /** Constructor
1963  *
1964  * @param context Test context
1965  **/
programInfo(deqp::Context & 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)
1968 {
1969 	/* Nothing to be done here */
1970 }
1971 
1972 /** Destructor
1973  *
1974  **/
~programInfo()1975 Utils::programInfo::~programInfo()
1976 {
1977 	/* GL entry points */
1978 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1979 
1980 	/* Make sure program object is no longer used by GL */
1981 	gl.useProgram(0);
1982 
1983 	/* Clean program object */
1984 	if (0 != m_program_object_id)
1985 	{
1986 		gl.deleteProgram(m_program_object_id);
1987 		m_program_object_id = 0;
1988 	}
1989 
1990 	/* Clean shaders */
1991 	if (0 != m_fragment_shader_id)
1992 	{
1993 		gl.deleteShader(m_fragment_shader_id);
1994 		m_fragment_shader_id = 0;
1995 	}
1996 
1997 	if (0 != m_vertex_shader_id)
1998 	{
1999 		gl.deleteShader(m_vertex_shader_id);
2000 		m_vertex_shader_id = 0;
2001 	}
2002 }
2003 
2004 /** Build program
2005  *
2006  * @param fragment_shader_code Fragment shader source code
2007  * @param vertex_shader_code   Vertex shader source code
2008  **/
build(const glw::GLchar * fragment_shader_code,const glw::GLchar * vertex_shader_code)2009 void Utils::programInfo::build(const glw::GLchar* fragment_shader_code, const glw::GLchar* vertex_shader_code)
2010 {
2011 	/* GL entry points */
2012 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2013 
2014 	/* Create shader objects and compile */
2015 	if (0 != fragment_shader_code)
2016 	{
2017 		m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER);
2018 		GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
2019 
2020 		compile(m_fragment_shader_id, fragment_shader_code);
2021 	}
2022 
2023 	if (0 != vertex_shader_code)
2024 	{
2025 		m_vertex_shader_id = gl.createShader(GL_VERTEX_SHADER);
2026 		GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
2027 
2028 		compile(m_vertex_shader_id, vertex_shader_code);
2029 	}
2030 
2031 	/* Create program object */
2032 	m_program_object_id = gl.createProgram();
2033 	GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram");
2034 
2035 	/* Link program */
2036 	link();
2037 }
2038 
2039 /** Compile shader
2040  *
2041  * @param shader_id   Shader object id
2042  * @param shader_code Shader source code
2043  **/
compile(glw::GLuint shader_id,const glw::GLchar * shader_code) const2044 void Utils::programInfo::compile(glw::GLuint shader_id, const glw::GLchar* shader_code) const
2045 {
2046 	/* GL entry points */
2047 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2048 
2049 	/* Compilation status */
2050 	glw::GLint status = GL_FALSE;
2051 
2052 	/* Set source code */
2053 	gl.shaderSource(shader_id, 1 /* count */, &shader_code, 0);
2054 	GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource");
2055 
2056 	/* Compile */
2057 	gl.compileShader(shader_id);
2058 	GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader");
2059 
2060 	/* Get compilation status */
2061 	gl.getShaderiv(shader_id, GL_COMPILE_STATUS, &status);
2062 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
2063 
2064 	/* Log compilation error */
2065 	if (GL_TRUE != status)
2066 	{
2067 		glw::GLint				 length = 0;
2068 		std::vector<glw::GLchar> message;
2069 
2070 		/* Error log length */
2071 		gl.getShaderiv(shader_id, GL_INFO_LOG_LENGTH, &length);
2072 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
2073 
2074 		/* Prepare storage */
2075 		message.resize(length);
2076 
2077 		/* Get error log */
2078 		gl.getShaderInfoLog(shader_id, length, 0, &message[0]);
2079 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog");
2080 
2081 		/* Log */
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;
2085 
2086 		TCU_FAIL("Failed to compile shader");
2087 	}
2088 }
2089 
2090 /** Attach shaders and link program
2091  *
2092  **/
link() const2093 void Utils::programInfo::link() const
2094 {
2095 	/* GL entry points */
2096 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2097 
2098 	/* Link status */
2099 	glw::GLint status = GL_FALSE;
2100 
2101 	/* Attach shaders */
2102 	if (0 != m_fragment_shader_id)
2103 	{
2104 		gl.attachShader(m_program_object_id, m_fragment_shader_id);
2105 		GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
2106 	}
2107 
2108 	if (0 != m_vertex_shader_id)
2109 	{
2110 		gl.attachShader(m_program_object_id, m_vertex_shader_id);
2111 		GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
2112 	}
2113 
2114 	/* Link */
2115 	gl.linkProgram(m_program_object_id);
2116 	GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram");
2117 
2118 	/* Get link status */
2119 	gl.getProgramiv(m_program_object_id, GL_LINK_STATUS, &status);
2120 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
2121 
2122 	/* Log link error */
2123 	if (GL_TRUE != status)
2124 	{
2125 		glw::GLint				 length = 0;
2126 		std::vector<glw::GLchar> message;
2127 
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");
2131 
2132 		message.resize(length);
2133 
2134 		/* Get error log */
2135 		gl.getProgramInfoLog(m_program_object_id, length, 0, &message[0]);
2136 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog");
2137 
2138 		/* Log */
2139 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to link program:\n"
2140 											<< &message[0] << tcu::TestLog::EndMessage;
2141 
2142 		TCU_FAIL("Failed to link program");
2143 	}
2144 }
2145 
2146 /** Replace first occurance of <token> with <text> in <string> starting at <search_posistion>
2147  *
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
2152  **/
replaceToken(const glw::GLchar * token,size_t & search_position,const glw::GLchar * text,std::string & string)2153 void Utils::replaceToken(const glw::GLchar* token, size_t& search_position, const glw::GLchar* text,
2154 						 std::string& string)
2155 {
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);
2159 
2160 	string.replace(token_position, token_length, text, text_length);
2161 
2162 	search_position = token_position + text_length;
2163 }
2164 
2165 /** Constructor.
2166  *
2167  * @param context Rendering context.
2168  **/
APIErrorsTest(deqp::Context & context)2169 APIErrorsTest::APIErrorsTest(deqp::Context& context)
2170 	: TestCase(context, "api_errors", "Verifies that errors are generated as specified"), m_id(0)
2171 {
2172 	/* Left blank intentionally */
2173 }
2174 
2175 /** Deinitialization **/
deinit()2176 void APIErrorsTest::deinit()
2177 {
2178 	if (0 != m_id)
2179 	{
2180 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2181 
2182 		gl.deleteTextures(1, &m_id);
2183 		m_id = 0;
2184 	}
2185 }
2186 
2187 /** Executes test iteration.
2188  *
2189  *  @return Returns STOP.
2190  */
iterate()2191 tcu::TestNode::IterateResult APIErrorsTest::iterate()
2192 {
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]);
2195 
2196 	/*  */
2197 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2198 
2199 	gl.genTextures(1, &m_id);
2200 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
2201 
2202 	gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_id);
2203 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2204 
2205 	/*
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,
2209 	 * ONE];
2210 	 */
2211 	for (size_t i = 0; i < n_states; ++i)
2212 	{
2213 		for (size_t j = 0; j < n_valid_values; ++j)
2214 		{
2215 			const glw::GLenum state = states[i];
2216 			const glw::GLint  value = valid_values[j];
2217 
2218 			gl.texParameteri(GL_TEXTURE_CUBE_MAP, state, value);
2219 			verifyError(GL_NO_ERROR);
2220 		}
2221 
2222 		for (size_t j = 0; j < n_invalid_values; ++j)
2223 		{
2224 			const glw::GLenum state = states[i];
2225 			const glw::GLint  value = invalid_values[j];
2226 
2227 			gl.texParameteri(GL_TEXTURE_CUBE_MAP, state, value);
2228 			verifyError(GL_INVALID_ENUM);
2229 		}
2230 	}
2231 
2232 	/*
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].
2236 	 */
2237 	for (size_t i = 0; i < 4 /* number of channels */; ++i)
2238 	{
2239 		for (size_t j = 0; j < n_valid_values; ++j)
2240 		{
2241 			const glw::GLint value = valid_values[j];
2242 
2243 			glw::GLint param[4] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA };
2244 
2245 			param[i] = value;
2246 
2247 			gl.texParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_RGBA, param);
2248 			verifyError(GL_NO_ERROR);
2249 		}
2250 
2251 		for (size_t j = 0; j < n_invalid_values; ++j)
2252 		{
2253 			const glw::GLint value = invalid_values[j];
2254 
2255 			glw::GLint param[4] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA };
2256 
2257 			param[i] = value;
2258 
2259 			gl.texParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_RGBA, param);
2260 			verifyError(GL_INVALID_ENUM);
2261 		}
2262 	}
2263 
2264 	/* Set result - exceptions are thrown in case of any error */
2265 	m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
2266 
2267 	/* Done */
2268 	return STOP;
2269 }
2270 
2271 /** Verifies that proper error was generated
2272  *
2273  * @param expected_error
2274  **/
verifyError(const glw::GLenum expected_error)2275 void APIErrorsTest::verifyError(const glw::GLenum expected_error)
2276 {
2277 	/*  */
2278 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2279 
2280 	const glw::GLenum error = gl.getError();
2281 
2282 	if (expected_error != error)
2283 	{
2284 		TCU_FAIL("Got invalid error");
2285 	}
2286 }
2287 
2288 /** Constructor.
2289  *
2290  * @param context Rendering context.
2291  **/
IntialStateTest(deqp::Context & context)2292 IntialStateTest::IntialStateTest(deqp::Context& context)
2293 	: TestCase(context, "intial_state", "Verifies that initial states are as specified"), m_id(0)
2294 {
2295 	/* Left blank intentionally */
2296 }
2297 
2298 /** Deinitialization **/
deinit()2299 void IntialStateTest::deinit()
2300 {
2301 	if (0 != m_id)
2302 	{
2303 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2304 
2305 		gl.deleteTextures(1, &m_id);
2306 		m_id = 0;
2307 	}
2308 }
2309 
2310 /** Executes test iteration.
2311  *
2312  *  @return Returns STOP.
2313  */
iterate()2314 tcu::TestNode::IterateResult IntialStateTest::iterate()
2315 {
2316 	/*  */
2317 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2318 
2319 	gl.genTextures(1, &m_id);
2320 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
2321 
2322 	for (size_t tex_tgt_idx = 0; tex_tgt_idx < n_texture_targets; ++tex_tgt_idx)
2323 	{
2324 		const glw::GLenum target = texture_targets[tex_tgt_idx].m_target;
2325 
2326 		gl.bindTexture(target, m_id);
2327 		GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2328 
2329 		verifyValues(target);
2330 
2331 		deinit();
2332 	}
2333 
2334 	/* Set result - exceptions are thrown in case of any error */
2335 	m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
2336 
2337 	/* Done */
2338 	return STOP;
2339 }
2340 
2341 /** Verifies that proper error was generated
2342  *
2343  * @param expected_error
2344  **/
verifyValues(const glw::GLenum texture_target)2345 void IntialStateTest::verifyValues(const glw::GLenum texture_target)
2346 {
2347 	/*  */
2348 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2349 
2350 	glw::GLint red		= 0;
2351 	glw::GLint green	= 0;
2352 	glw::GLint blue		= 0;
2353 	glw::GLint alpha	= 0;
2354 	glw::GLint param[4] = { 0 };
2355 
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");
2366 
2367 	if (GL_RED != red)
2368 	{
2369 		TCU_FAIL("Got invalid initial state for TEXTURE_SWIZZLE_R");
2370 	}
2371 	if (GL_GREEN != green)
2372 	{
2373 		TCU_FAIL("Got invalid initial state for TEXTURE_SWIZZLE_G");
2374 	}
2375 	if (GL_BLUE != blue)
2376 	{
2377 		TCU_FAIL("Got invalid initial state for TEXTURE_SWIZZLE_B");
2378 	}
2379 	if (GL_ALPHA != alpha)
2380 	{
2381 		TCU_FAIL("Got invalid initial state for TEXTURE_SWIZZLE_A");
2382 	}
2383 
2384 	if (GL_RED != param[0])
2385 	{
2386 		TCU_FAIL("Got invalid initial red state for TEXTURE_SWIZZLE_RGBA");
2387 	}
2388 	if (GL_GREEN != param[1])
2389 	{
2390 		TCU_FAIL("Got invalid initial green state for TEXTURE_SWIZZLE_RGBA");
2391 	}
2392 	if (GL_BLUE != param[2])
2393 	{
2394 		TCU_FAIL("Got invalid initial blue state for TEXTURE_SWIZZLE_RGBA");
2395 	}
2396 	if (GL_ALPHA != param[3])
2397 	{
2398 		TCU_FAIL("Got invalid initial alpha state for TEXTURE_SWIZZLE_RGBA");
2399 	}
2400 }
2401 
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;
2408 
2409 /** Constructor.
2410  *
2411  * @param context Rendering context.
2412  **/
SmokeTest(deqp::Context & 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)
2417 	, m_out_tex_id(0)
2418 	, m_source_tex_id(0)
2419 	, m_test_fbo_id(0)
2420 	, m_vao_id(0)
2421 {
2422 	/* Left blank intentionally */
2423 }
2424 
2425 /** Constructor.
2426  *
2427  * @param context Rendering context.
2428  **/
SmokeTest(deqp::Context & context,const glw::GLchar * name,const glw::GLchar * description)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)
2433 	, m_out_tex_id(0)
2434 	, m_source_tex_id(0)
2435 	, m_test_fbo_id(0)
2436 	, m_vao_id(0)
2437 {
2438 	/* Left blank intentionally */
2439 }
2440 
2441 /** Deinitialization **/
deinit()2442 void SmokeTest::deinit()
2443 {
2444 	deinitTextures();
2445 
2446 	if (m_prepare_fbo_id != 0)
2447 	{
2448 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2449 		gl.deleteFramebuffers(1, &m_prepare_fbo_id);
2450 
2451 		m_prepare_fbo_id = 0;
2452 	}
2453 
2454 	if (m_test_fbo_id != 0)
2455 	{
2456 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2457 		gl.deleteFramebuffers(1, &m_test_fbo_id);
2458 
2459 		m_test_fbo_id = 0;
2460 	}
2461 
2462 	if (m_vao_id != 0)
2463 	{
2464 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2465 		gl.deleteVertexArrays(1, &m_vao_id);
2466 
2467 		m_vao_id = 0;
2468 	}
2469 }
2470 
2471 /** Executes test iteration.
2472  *
2473  *  @return Returns STOP.
2474  */
iterate()2475 tcu::TestNode::IterateResult SmokeTest::iterate()
2476 {
2477 	static const glw::GLenum tested_format = GL_RGBA32UI;
2478 	static const glw::GLenum tested_target = GL_TEXTURE_2D_ARRAY;
2479 
2480 	const size_t format_idx = get_index_of_format(tested_format);
2481 	const size_t tgt_idx	= get_index_of_target(tested_target);
2482 
2483 	glw::GLint source_channel_sizes[4] = { 0 };
2484 
2485 	/*  */
2486 	testInit();
2487 
2488 	if (false == isTargetSupported(tgt_idx))
2489 	{
2490 		throw tcu::NotSupportedError("Texture target is not support by implementation", "", __FILE__, __LINE__);
2491 	}
2492 
2493 	/* Prepare and fill source texture */
2494 	prepareSourceTexture(format_idx, tgt_idx, source_channel_sizes);
2495 	if (false == fillSourceTexture(format_idx, tgt_idx))
2496 	{
2497 		TCU_FAIL("Failed to prepare source texture");
2498 	}
2499 
2500 	/* Iterate over all cases */
2501 	for (size_t access_idx = 0; access_idx < n_texture_access; ++access_idx)
2502 	{
2503 		/* Skip invalid cases */
2504 		if (false == isTargetSuppByAccess(access_idx, tgt_idx))
2505 		{
2506 			continue;
2507 		}
2508 
2509 		for (size_t r = 0; r < n_valid_values; ++r)
2510 		{
2511 			for (size_t g = 0; g < n_valid_values; ++g)
2512 			{
2513 				for (size_t b = 0; b < n_valid_values; ++b)
2514 				{
2515 					for (size_t a = 0; a < n_valid_values; ++a)
2516 					{
2517 						for (size_t channel_idx = 0; channel_idx < 4; ++channel_idx)
2518 						{
2519 							const testCase test_case = { channel_idx,
2520 														 format_idx,
2521 														 tgt_idx,
2522 														 access_idx,
2523 														 valid_values[r],
2524 														 valid_values[g],
2525 														 valid_values[b],
2526 														 valid_values[a],
2527 														 { source_channel_sizes[0], source_channel_sizes[1],
2528 														   source_channel_sizes[2], source_channel_sizes[3] } };
2529 
2530 							executeTestCase(test_case);
2531 
2532 							deinitOutputTexture();
2533 						} /* iteration over channels */
2534 					}	 /* iteration over swizzle combinations */
2535 				}
2536 			}
2537 		}
2538 	} /* iteration over access routines */
2539 
2540 	/* Set result - exceptions are thrown in case of any error */
2541 	m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
2542 
2543 	/* Done */
2544 	return STOP;
2545 }
2546 
2547 /** Deinitialization of output texture **/
deinitOutputTexture()2548 void SmokeTest::deinitOutputTexture()
2549 {
2550 	if (m_out_tex_id != 0)
2551 	{
2552 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2553 		gl.deleteTextures(1, &m_out_tex_id);
2554 
2555 		m_out_tex_id = 0;
2556 	}
2557 }
2558 
2559 /** Deinitialization of textures **/
deinitTextures()2560 void SmokeTest::deinitTextures()
2561 {
2562 	deinitOutputTexture();
2563 
2564 	if (m_source_tex_id != 0)
2565 	{
2566 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2567 		gl.deleteTextures(1, &m_source_tex_id);
2568 
2569 		m_source_tex_id = 0;
2570 	}
2571 }
2572 
2573 /** Captures and verifies contents of output texture
2574  *
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
2579  */
captureAndVerify(const testCase & test_case,size_t output_format_index,glw::GLint output_channel_size,size_t 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)
2582 {
2583 	const _texture_format& output_format = texture_formats[output_format_index];
2584 
2585 	/*  */
2586 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2587 
2588 	/* Storage for image data */
2589 	glw::GLubyte result_image[m_output_width * m_output_height * 4 /* channles */ * sizeof(glw::GLuint)];
2590 
2591 	/* Get image data */
2592 	gl.bindTexture(GL_TEXTURE_2D, m_out_tex_id);
2593 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2594 
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");
2597 
2598 	/* Unbind output texture */
2599 	gl.bindTexture(GL_TEXTURE_2D, 0);
2600 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2601 
2602 	/* Verification */
2603 	verifyOutputImage(test_case, output_format_index, output_channel_size, index_of_swizzled_channel, result_image);
2604 }
2605 
2606 /** Draws four points
2607  *
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
2611  **/
draw(glw::GLenum target,const glw::GLint * texture_swizzle,bool use_rgba_enum)2612 void SmokeTest::draw(glw::GLenum target, const glw::GLint* texture_swizzle, bool use_rgba_enum)
2613 {
2614 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2615 
2616 	/* Prepare source texture */
2617 	gl.activeTexture(GL_TEXTURE0);
2618 	GLU_EXPECT_NO_ERROR(gl.getError(), "ActiveTexture");
2619 
2620 	gl.bindTexture(target, m_source_tex_id);
2621 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2622 
2623 	/* Set texture swizzle */
2624 	if (true == use_rgba_enum)
2625 	{
2626 		gl.texParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, texture_swizzle);
2627 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteriv");
2628 	}
2629 	else
2630 	{
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");
2636 	}
2637 
2638 	/* Clear */
2639 	gl.clear(GL_COLOR_BUFFER_BIT);
2640 	GLU_EXPECT_NO_ERROR(gl.getError(), "Clear");
2641 
2642 	/* Draw */
2643 	gl.drawArrays(GL_TRIANGLE_STRIP, 0 /* first */, 4 /* count */);
2644 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
2645 
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");
2652 
2653 	/* Unbind source texture */
2654 	gl.bindTexture(target, 0);
2655 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2656 }
2657 
2658 /** Executes test case
2659  *
2660  * @param test_case Test case instance
2661  **/
executeTestCase(const testCase & test_case)2662 void SmokeTest::executeTestCase(const testCase& test_case)
2663 {
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);
2674 
2675 	/*  */
2676 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2677 
2678 	/* Prepare output */
2679 	prepareOutputTexture(out_format_idx);
2680 
2681 	gl.bindTexture(GL_TEXTURE_2D, m_out_tex_id);
2682 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2683 
2684 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_test_fbo_id);
2685 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
2686 
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");
2689 
2690 	/* Set Viewport */
2691 	gl.viewport(0 /* x */, 0 /* y */, m_output_width, m_output_height);
2692 	GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
2693 
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");
2697 
2698 	/* Unbind output texture */
2699 	gl.bindTexture(GL_TEXTURE_2D, 0);
2700 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2701 
2702 	prepareAndTestProgram(test_case, out_format_idx, out_channel_size, channel, true);
2703 	prepareAndTestProgram(test_case, out_format_idx, out_channel_size, channel, false);
2704 
2705 	/* Unbind FBO */
2706 	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
2707 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
2708 }
2709 
2710 /** Fills source texture
2711  *
2712  * @param format_idx Index of format
2713  * @param target_idx Index of target
2714  *
2715  * @return True if operation was successful, false other wise
2716  **/
fillSourceTexture(size_t format_idx,size_t target_idx)2717 bool SmokeTest::fillSourceTexture(size_t format_idx, size_t target_idx)
2718 {
2719 	static const glw::GLuint rgba32ui[4] = { 0x3fffffff, 0x7fffffff, 0xbfffffff, 0xffffffff };
2720 
2721 	const glw::GLenum	  target		  = texture_targets[target_idx].m_target;
2722 	const _texture_format& texture_format = texture_formats[format_idx];
2723 
2724 	/*  */
2725 	const glw::Functions& gl   = m_context.getRenderContext().getFunctions();
2726 	const glw::GLvoid*	data = 0;
2727 
2728 	/* Bind texture and FBO */
2729 	gl.bindTexture(target, m_source_tex_id);
2730 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2731 
2732 	/* Set color */
2733 	switch (texture_format.m_internal_format)
2734 	{
2735 	case GL_RGBA32UI:
2736 		data = (const glw::GLubyte*)rgba32ui;
2737 		break;
2738 
2739 	default:
2740 		TCU_FAIL("Invalid enum");
2741 		break;
2742 	}
2743 
2744 	/* Attach texture */
2745 	switch (target)
2746 	{
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);
2750 		break;
2751 
2752 	default:
2753 		TCU_FAIL("Invalid enum");
2754 		break;
2755 	}
2756 
2757 	/* Unbind */
2758 	gl.bindTexture(target, 0);
2759 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2760 
2761 	/* Done */
2762 	return true;
2763 }
2764 
2765 /** Gets source of fragment shader
2766  *
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
2770  *
2771  * @return Source of shader
2772  **/
getFragmentShader(const testCase & test_case,size_t output_format_index,bool is_tested_stage)2773 std::string SmokeTest::getFragmentShader(const testCase& test_case, size_t output_format_index, bool is_tested_stage)
2774 {
2775 	static const glw::GLchar* fs_blank_template = "#version 330 core\n"
2776 												  "\n"
2777 												  "flat in BASIC_TYPE result;\n"
2778 												  "\n"
2779 												  "out BASIC_TYPE out_color;\n"
2780 												  "\n"
2781 												  "void main()\n"
2782 												  "{\n"
2783 												  "    out_color = result;\n"
2784 												  "}\n"
2785 												  "\n";
2786 
2787 	static const glw::GLchar* fs_test_template = "#version 330 core\n"
2788 												 "\n"
2789 												 "uniform PREFIXsamplerSAMPLER_TYPE sampler;\n"
2790 												 "\n"
2791 												 "out BASIC_TYPE out_color;\n"
2792 												 "\n"
2793 												 "void main()\n"
2794 												 "{\n"
2795 												 "    BASIC_TYPE result = TEXTURE_ACCESS(sampler, ARGUMENTS).CHANNEL;\n"
2796 												 "\n"
2797 												 "    out_color = result;\n"
2798 												 "}\n"
2799 												 "\n";
2800 
2801 	/* */
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];
2808 
2809 	std::string fs;
2810 	size_t		position = 0;
2811 
2812 	if (is_tested_stage)
2813 	{
2814 		fs = fs_test_template;
2815 
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);
2823 	}
2824 	else
2825 	{
2826 		fs = fs_blank_template;
2827 
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);
2830 	}
2831 
2832 	return fs;
2833 }
2834 
2835 /** Gets source of vertex shader
2836  *
2837  * @param test_case           Test case instance
2838  * @param is_tested_stage     Selects if vertex or fragment shader makes texture access
2839  *
2840  * @return Source of shader
2841  **/
getVertexShader(const testCase & test_case,bool is_tested_stage)2842 std::string SmokeTest::getVertexShader(const testCase& test_case, bool is_tested_stage)
2843 {
2844 	static const glw::GLchar* vs_blank_template = "#version 330 core\n"
2845 												  "\n"
2846 												  "void main()\n"
2847 												  "{\n"
2848 												  "    switch (gl_VertexID)\n"
2849 												  "    {\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"
2854 												  "    }\n"
2855 												  "}\n"
2856 												  "\n";
2857 
2858 	static const glw::GLchar* vs_test_template = "#version 330 core\n"
2859 												 "\n"
2860 												 "uniform PREFIXsamplerSAMPLER_TYPE sampler;\n"
2861 												 "\n"
2862 												 "flat out BASIC_TYPE result;\n"
2863 												 "\n"
2864 												 "void main()\n"
2865 												 "{\n"
2866 												 "    result = TEXTURE_ACCESS(sampler, ARGUMENTS).CHANNEL;\n"
2867 												 "\n"
2868 												 "    switch (gl_VertexID)\n"
2869 												 "    {\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"
2874 												 "    }\n"
2875 												 "}\n"
2876 												 "\n";
2877 
2878 	std::string vs;
2879 
2880 	if (is_tested_stage)
2881 	{
2882 		/* */
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];
2888 
2889 		size_t position = 0;
2890 
2891 		vs = vs_test_template;
2892 
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);
2899 	}
2900 	else
2901 	{
2902 		vs = vs_blank_template;
2903 	}
2904 
2905 	return vs;
2906 }
2907 
2908 /** Check if target is supported
2909  *
2910  * @param target_idx Index of target
2911  *
2912  * @return true if target is supported, false otherwise
2913  **/
isTargetSupported(size_t target_idx)2914 bool SmokeTest::isTargetSupported(size_t target_idx)
2915 {
2916 	const _texture_target& target = texture_targets[target_idx];
2917 
2918 	bool is_supported = true;
2919 
2920 	switch (target.m_target)
2921 	{
2922 	case GL_TEXTURE_2D_MULTISAMPLE:
2923 	case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
2924 		is_supported = m_is_ms_supported;
2925 		break;
2926 
2927 	default:
2928 		break;
2929 	}
2930 
2931 	return is_supported;
2932 }
2933 
2934 /** Check if target is supported by access routine
2935  *
2936  * @param access_idx Index of access routine
2937  * @param target_idx Index of target
2938  *
2939  * @return true if target is supported, false otherwise
2940  **/
isTargetSuppByAccess(size_t access_idx,size_t target_idx)2941 bool SmokeTest::isTargetSuppByAccess(size_t access_idx, size_t target_idx)
2942 {
2943 	const _texture_access& access		 = texture_access[access_idx];
2944 	const _texture_target& source_target = texture_targets[target_idx];
2945 
2946 	if ((false == source_target.m_support_integral_coordinates) && (true == access.m_use_integral_coordinates))
2947 	{
2948 		/* Cases are not valid, texelFetch* is not supported by the target */
2949 		return false;
2950 	}
2951 
2952 	if ((false == source_target.m_support_offset) && (true == access.m_use_offsets))
2953 	{
2954 		/* Cases are not valid, texture*Offset is not supported by the target */
2955 		return false;
2956 	}
2957 
2958 	if ((false == source_target.m_support_lod) && (true == access.m_use_lod))
2959 	{
2960 		/* Access is one of texture*Lod* or texelFetch* */
2961 		/* Target is one of MS or rect */
2962 
2963 		if ((true == source_target.m_require_multisampling) && (true == access.m_support_multisampling))
2964 		{
2965 			/* texelFetch */
2966 			/* One of MS targets */
2967 			return true;
2968 		}
2969 
2970 		/* Cases are not valid, either lod or sample is required but target does not supported that */
2971 		return false;
2972 	}
2973 
2974 	if ((false == source_target.m_supports_proj) && (1 == access.m_n_coordinates))
2975 	{
2976 		/* Cases are not valid, textureProj* is not supported by the target */
2977 		return false;
2978 	}
2979 
2980 	if ((true == source_target.m_require_multisampling) && (false == access.m_support_multisampling))
2981 	{
2982 		/* Cases are not valid, texelFetch* is not supported by the target */
2983 		return false;
2984 	}
2985 
2986 	return true;
2987 }
2988 
2989 /** Check if target is supported by format
2990  *
2991  * @param format_idx Index of format
2992  * @param target_idx Index of target
2993  *
2994  * @return true if target is supported, false otherwise
2995  **/
isTargetSuppByFormat(size_t format_idx,size_t target_idx)2996 bool SmokeTest::isTargetSuppByFormat(size_t format_idx, size_t target_idx)
2997 {
2998 	const _texture_format& format		 = texture_formats[format_idx];
2999 	const _texture_target& source_target = texture_targets[target_idx];
3000 
3001 	bool is_supported = true;
3002 
3003 	switch (format.m_internal_format)
3004 	{
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)
3012 		{
3013 		case GL_TEXTURE_3D:
3014 		case GL_TEXTURE_2D_MULTISAMPLE:
3015 		case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
3016 			is_supported = false;
3017 			break;
3018 		default:
3019 			break;
3020 		}
3021 		break;
3022 
3023 	case GL_RGB9_E5:
3024 		switch (source_target.m_target)
3025 		{
3026 		case GL_TEXTURE_2D_MULTISAMPLE:
3027 		case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
3028 			is_supported = false;
3029 			break;
3030 		default:
3031 			break;
3032 		}
3033 		break;
3034 
3035 	default:
3036 		break;
3037 	}
3038 
3039 	return is_supported;
3040 }
3041 
3042 /** Logs details of test case
3043  *
3044  * @parma test_case Test case instance
3045  **/
logTestCaseDetials(const testCase & test_case)3046 void SmokeTest::logTestCaseDetials(const testCase& test_case)
3047 {
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];
3059 
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;
3075 }
3076 
3077 /** Prepares program then draws and verifies resutls for both ways of setting texture swizzle
3078  *
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
3084  **/
prepareAndTestProgram(const testCase & test_case,size_t output_format_index,glw::GLint output_channel_size,size_t index_of_swizzled_channel,bool test_vertex_stage)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)
3088 {
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 };
3095 
3096 	/*  */
3097 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3098 
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);
3102 
3103 	Utils::programInfo program(m_context);
3104 	program.build(fs.c_str(), vs.c_str());
3105 
3106 	gl.useProgram(program.m_program_object_id);
3107 	GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
3108 
3109 	/* Prepare sampler */
3110 	glw::GLint location = gl.getUniformLocation(program.m_program_object_id, "sampler");
3111 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformLocation");
3112 
3113 	if (-1 == location)
3114 	{
3115 		TCU_FAIL("Uniform is not available");
3116 	}
3117 
3118 	gl.uniform1i(location, 0 /* texture unit */);
3119 	GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i");
3120 
3121 	draw(source_target.m_target, param, false);
3122 	captureAndVerify(test_case, output_format_index, output_channel_size, index_of_swizzled_channel);
3123 
3124 	draw(source_target.m_target, param, true);
3125 	captureAndVerify(test_case, output_format_index, output_channel_size, index_of_swizzled_channel);
3126 }
3127 
3128 /** Prepares arguments for texture access routine call
3129  *
3130  * @param test_case Test case instance
3131  *
3132  * @return Source code
3133  **/
prepareArguments(const testCase & test_case)3134 std::string SmokeTest::prepareArguments(const testCase& test_case)
3135 {
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];
3138 
3139 	std::string		   arguments   = "COORDINATESLODDERIVATIVESOFFSETSSAMPLE";
3140 	const std::string& coordinates = prepareCoordinates(test_case);
3141 
3142 	size_t position = 0;
3143 
3144 	Utils::replaceToken("COORDINATES", position, coordinates.c_str(), arguments);
3145 
3146 	if ((true == access.m_use_lod) && (true == target.m_support_lod))
3147 	{
3148 		Utils::replaceToken("LODDERIVATIVES", position, ", int(0)", arguments);
3149 	}
3150 	else if (true == access.m_use_derivaties)
3151 	{
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;
3155 
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);
3160 	}
3161 	else
3162 	{
3163 		Utils::replaceToken("LODDERIVATIVES", position, "", arguments);
3164 	}
3165 
3166 	if (true == access.m_use_offsets)
3167 	{
3168 		const std::string& offsets   = prepareOffsets(test_case);
3169 		const size_t	   start_pos = position;
3170 
3171 		Utils::replaceToken("OFFSETS", position, ", XXXXX", arguments);
3172 		position = start_pos + 2;
3173 		Utils::replaceToken("XXXXX", position, offsets.c_str(), arguments);
3174 	}
3175 	else
3176 	{
3177 		Utils::replaceToken("OFFSETS", position, "", arguments);
3178 	}
3179 
3180 	if ((true == target.m_require_multisampling) && (true == access.m_support_multisampling))
3181 	{
3182 		const std::string& sample	= prepareSample();
3183 		const size_t	   start_pos = position;
3184 
3185 		Utils::replaceToken("SAMPLE", position, ", XX", arguments);
3186 		position = start_pos + 2;
3187 		Utils::replaceToken("XX", position, sample.c_str(), arguments);
3188 	}
3189 	else
3190 	{
3191 		Utils::replaceToken("SAMPLE", position, "", arguments);
3192 	}
3193 
3194 	return arguments;
3195 }
3196 
3197 /** Prepares coordinate for texture access routine call
3198  *
3199  * @param test_case Test case instance
3200  *
3201  * @return Source code
3202  **/
prepareCoordinates(const testCase & test_case)3203 std::string SmokeTest::prepareCoordinates(const testCase& test_case)
3204 {
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];
3207 
3208 	const glw::GLchar* type = 0;
3209 
3210 	std::string coordinates = "TYPE(VAL_LIST)";
3211 
3212 	if (false == access.m_use_integral_coordinates)
3213 	{
3214 		switch (access.m_n_coordinates + target.m_n_array_coordinates + target.m_n_coordinates)
3215 		{
3216 		case 1:
3217 			type = "float";
3218 			break;
3219 		case 2:
3220 			type = "vec2";
3221 			break;
3222 		case 3:
3223 			type = "vec3";
3224 			break;
3225 		case 4:
3226 			type = "vec4";
3227 			break;
3228 		default:
3229 			TCU_FAIL("Invalid value");
3230 			break;
3231 		}
3232 	}
3233 	else
3234 	{
3235 		switch (access.m_n_coordinates + target.m_n_array_coordinates + target.m_n_coordinates)
3236 		{
3237 		case 1:
3238 			type = "int";
3239 			break;
3240 		case 2:
3241 			type = "ivec2";
3242 			break;
3243 		case 3:
3244 			type = "ivec3";
3245 			break;
3246 		case 4:
3247 			type = "ivec4";
3248 			break;
3249 		default:
3250 			TCU_FAIL("Invalid value");
3251 			break;
3252 		}
3253 	}
3254 
3255 	size_t position = 0;
3256 
3257 	Utils::replaceToken("TYPE", position, type, coordinates);
3258 
3259 	for (size_t i = 0; i < target.m_n_coordinates; ++i)
3260 	{
3261 		size_t start_position = position;
3262 
3263 		Utils::replaceToken("VAL_LIST", position, "0, VAL_LIST", coordinates);
3264 
3265 		position = start_position + 1;
3266 	}
3267 
3268 	for (size_t i = 0; i < target.m_n_array_coordinates; ++i)
3269 	{
3270 		size_t start_position = position;
3271 
3272 		Utils::replaceToken("VAL_LIST", position, "0, VAL_LIST", coordinates);
3273 
3274 		position = start_position + 1;
3275 	}
3276 
3277 	for (size_t i = 0; i < access.m_n_coordinates; ++i)
3278 	{
3279 		size_t start_position = position;
3280 
3281 		Utils::replaceToken("VAL_LIST", position, "1, VAL_LIST", coordinates);
3282 
3283 		position = start_position + 1;
3284 	}
3285 
3286 	Utils::replaceToken(", VAL_LIST", position, "", coordinates);
3287 
3288 	return coordinates;
3289 }
3290 
3291 /** Prepares derivatives for texture access routine call
3292  *
3293  * @param test_case Test case instance
3294  *
3295  * @return Source code
3296  **/
prepareDerivatives(const testCase & test_case,size_t index)3297 std::string SmokeTest::prepareDerivatives(const testCase& test_case, size_t index)
3298 {
3299 	const _texture_target& target = texture_targets[test_case.m_source_texture_target_index];
3300 
3301 	const glw::GLchar* type = 0;
3302 
3303 	std::string derivatives = "TYPE(VAL_LIST)";
3304 
3305 	switch (target.m_n_derivatives)
3306 	{
3307 	case 1:
3308 		type = "float";
3309 		break;
3310 	case 2:
3311 		type = "vec2";
3312 		break;
3313 	case 3:
3314 		type = "vec3";
3315 		break;
3316 	case 4:
3317 		type = "vec4";
3318 		break;
3319 	default:
3320 		TCU_FAIL("Invalid value");
3321 		break;
3322 	}
3323 
3324 	size_t position = 0;
3325 
3326 	Utils::replaceToken("TYPE", position, type, derivatives);
3327 
3328 	for (size_t i = 0; i < target.m_n_derivatives; ++i)
3329 	{
3330 		size_t start_position = position;
3331 
3332 		if (index == i)
3333 		{
3334 			Utils::replaceToken("VAL_LIST", position, "1.0, VAL_LIST", derivatives);
3335 		}
3336 		else
3337 		{
3338 			Utils::replaceToken("VAL_LIST", position, "0.0, VAL_LIST", derivatives);
3339 		}
3340 
3341 		position = start_position + 1;
3342 	}
3343 
3344 	Utils::replaceToken(", VAL_LIST", position, "", derivatives);
3345 
3346 	return derivatives;
3347 }
3348 
3349 /** Prepares offsets for texture access routine call
3350  *
3351  * @param test_case Test case instance
3352  *
3353  * @return Source code
3354  **/
prepareOffsets(const testCase & test_case)3355 std::string SmokeTest::prepareOffsets(const testCase& test_case)
3356 {
3357 	const _texture_target& target = texture_targets[test_case.m_source_texture_target_index];
3358 
3359 	const glw::GLchar* type = DE_NULL;
3360 
3361 	std::string offsets = "TYPE(VAL_LIST)";
3362 
3363 	switch (target.m_n_derivatives)
3364 	{
3365 	case 1:
3366 		type = "int";
3367 		break;
3368 	case 2:
3369 		type = "ivec2";
3370 		break;
3371 	case 3:
3372 		type = "ivec3";
3373 		break;
3374 	case 4:
3375 		type = "ivec4";
3376 		break;
3377 	default:
3378 		TCU_FAIL("Invalid value");
3379 		break;
3380 	}
3381 
3382 	size_t position = 0;
3383 
3384 	Utils::replaceToken("TYPE", position, type, offsets);
3385 
3386 	for (size_t i = 0; i < target.m_n_coordinates; ++i)
3387 	{
3388 		size_t start_position = position;
3389 
3390 		Utils::replaceToken("VAL_LIST", position, "0, VAL_LIST", offsets);
3391 
3392 		position = start_position + 1;
3393 	}
3394 
3395 	Utils::replaceToken(", VAL_LIST", position, "", offsets);
3396 
3397 	return offsets;
3398 }
3399 
3400 /** Prepares output texture
3401  *
3402  * @param format_idx Index of texture format
3403  **/
prepareOutputTexture(size_t format_idx)3404 void SmokeTest::prepareOutputTexture(size_t format_idx)
3405 {
3406 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3407 
3408 	const _texture_format& format = texture_formats[format_idx];
3409 
3410 	gl.genTextures(1, &m_out_tex_id);
3411 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
3412 
3413 	gl.bindTexture(GL_TEXTURE_2D, m_out_tex_id);
3414 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
3415 
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");
3419 
3420 	gl.bindTexture(GL_TEXTURE_2D, 0);
3421 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
3422 }
3423 
3424 /** Prepares sample for texture access routine call
3425  *
3426  * @return Source code
3427  **/
prepareSample()3428 std::string SmokeTest::prepareSample()
3429 {
3430 	glw::GLsizei	  samples = 1;
3431 	std::stringstream stream;
3432 
3433 	/* Get max number of samples */
3434 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3435 
3436 	gl.getIntegerv(GL_MAX_SAMPLES, &samples);
3437 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
3438 
3439 	stream << samples - 1;
3440 
3441 	return stream.str();
3442 }
3443 
3444 /** Prepares source texture
3445  *
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
3449  **/
prepareSourceTexture(size_t format_idx,size_t target_idx,glw::GLint out_sizes[4])3450 void SmokeTest::prepareSourceTexture(size_t format_idx, size_t target_idx, glw::GLint out_sizes[4])
3451 {
3452 	static const glw::GLint border = 0;
3453 	static const glw::GLint level  = 0;
3454 
3455 	/* */
3456 	const glw::GLenum	  target		  = texture_targets[target_idx].m_target;
3457 	const _texture_format& texture_format = texture_formats[format_idx];
3458 
3459 	/* */
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;
3467 
3468 	/*  */
3469 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3470 
3471 	/* Get max number of samples */
3472 	gl.getIntegerv(GL_MAX_SAMPLES, &samples);
3473 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
3474 
3475 	/* Generate and bind */
3476 	gl.genTextures(1, &m_source_tex_id);
3477 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
3478 
3479 	gl.bindTexture(target, m_source_tex_id);
3480 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
3481 
3482 	/* Allocate storage */
3483 	switch (target)
3484 	{
3485 	case GL_TEXTURE_1D:
3486 
3487 		gl.texImage1D(target, level, internal_format, m_width, border, format, type, 0 /* pixels */);
3488 		error		  = gl.getError();
3489 		function_name = "TexImage1D";
3490 
3491 		break;
3492 
3493 	case GL_TEXTURE_1D_ARRAY:
3494 	case GL_TEXTURE_2D:
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";
3499 
3500 		break;
3501 
3502 	case GL_TEXTURE_2D_ARRAY:
3503 	case GL_TEXTURE_3D:
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";
3507 
3508 		break;
3509 
3510 	case GL_TEXTURE_CUBE_MAP:
3511 		for (size_t i = 0; i < n_cube_map_faces; ++i)
3512 		{
3513 			gl.texImage2D(cube_map_faces[i], level, internal_format, m_width, m_height, border, format, type,
3514 						  0 /* pixels */);
3515 		}
3516 		error		  = gl.getError();
3517 		function_name = "TexImage2D";
3518 
3519 		target_get_prm = cube_map_faces[0];
3520 
3521 		break;
3522 
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";
3528 
3529 		break;
3530 
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";
3536 
3537 		break;
3538 
3539 	default:
3540 		TCU_FAIL("Invalid enum");
3541 		break;
3542 	}
3543 
3544 	/* Log error */
3545 	GLU_EXPECT_NO_ERROR(error, function_name);
3546 
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))
3550 	{
3551 		gl.texParameteri(target, GL_TEXTURE_BASE_LEVEL, 0);
3552 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
3553 
3554 		gl.texParameteri(target, GL_TEXTURE_MAX_LEVEL, 0);
3555 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
3556 
3557 		gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3558 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
3559 
3560 		gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3561 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
3562 	}
3563 
3564 	if (texture_format.m_ds_mode == GL_STENCIL_INDEX)
3565 	{
3566 		gl.texParameteri(target, GL_DEPTH_STENCIL_TEXTURE_MODE, texture_format.m_ds_mode);
3567 		GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
3568 	}
3569 
3570 	/* Get internal storage sizes */
3571 	switch (internal_format)
3572 	{
3573 	case GL_DEPTH24_STENCIL8:
3574 	case GL_DEPTH32F_STENCIL8:
3575 
3576 		gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_STENCIL_SIZE, out_sizes + 1);
3577 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3578 
3579 	/* Fall through */
3580 
3581 	case GL_DEPTH_COMPONENT16:
3582 	case GL_DEPTH_COMPONENT24:
3583 	case GL_DEPTH_COMPONENT32:
3584 	case GL_DEPTH_COMPONENT32F:
3585 
3586 		gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_DEPTH_SIZE, out_sizes + 0);
3587 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3588 
3589 		break;
3590 
3591 	default:
3592 
3593 		gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_RED_SIZE, out_sizes + 0);
3594 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3595 
3596 		gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_GREEN_SIZE, out_sizes + 1);
3597 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3598 
3599 		gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_BLUE_SIZE, out_sizes + 2);
3600 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3601 
3602 		gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_ALPHA_SIZE, out_sizes + 3);
3603 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3604 
3605 		break;
3606 	}
3607 
3608 	/* Unbind texture */
3609 	gl.bindTexture(target, 0);
3610 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
3611 }
3612 
3613 /** Initializes frame buffer and vertex array
3614  *
3615  **/
testInit()3616 void SmokeTest::testInit()
3617 {
3618 	/*  */
3619 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3620 
3621 	glw::GLint major = 0;
3622 	glw::GLint minor = 0;
3623 
3624 	gl.getIntegerv(GL_MAJOR_VERSION, &major);
3625 	gl.getIntegerv(GL_MINOR_VERSION, &minor);
3626 
3627 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
3628 
3629 	if (4 < major)
3630 	{
3631 		m_is_ms_supported = true;
3632 	}
3633 	else if (4 == major)
3634 	{
3635 		if (3 <= minor)
3636 		{
3637 			m_is_ms_supported = true;
3638 		}
3639 	}
3640 
3641 	/* Context is below 4.3 */
3642 	if (false == m_is_ms_supported)
3643 	{
3644 		m_is_ms_supported = m_context.getContextInfo().isExtensionSupported("GL_ARB_texture_storage_multisample");
3645 	}
3646 
3647 #if ENABLE_DEBUG
3648 
3649 	gl.debugMessageCallback(debug_proc, &m_context);
3650 	GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback");
3651 
3652 #endif /* ENABLE_DEBUG */
3653 
3654 	/* Prepare FBOs */
3655 	gl.genFramebuffers(1, &m_prepare_fbo_id);
3656 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
3657 
3658 	gl.genFramebuffers(1, &m_test_fbo_id);
3659 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
3660 
3661 	/* Prepare blank VAO */
3662 	gl.genVertexArrays(1, &m_vao_id);
3663 	GLU_EXPECT_NO_ERROR(gl.getError(), "genVertexArrays");
3664 
3665 	gl.bindVertexArray(m_vao_id);
3666 	GLU_EXPECT_NO_ERROR(gl.getError(), "bindVertexArray");
3667 }
3668 
3669 /** Verifies contents of output image
3670  *
3671  * @param test_case                 Test case instance
3672  * @param ignored
3673  * @param ignored
3674  * @param index_of_swizzled_channel Index of swizzled channel
3675  * @param data                      Image contents
3676  **/
verifyOutputImage(const testCase & test_case,size_t,glw::GLint,size_t index_of_swizzled_channel,const glw::GLubyte * data)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)
3680 {
3681 	static const glw::GLuint rgba32ui[6] = { 0x3fffffff, 0x7fffffff, 0xbfffffff, 0xffffffff, 1, 0 };
3682 
3683 	const _texture_format& source_format = texture_formats[test_case.m_source_texture_format_index];
3684 
3685 	/* Set color */
3686 	switch (source_format.m_internal_format)
3687 	{
3688 	case GL_RGBA32UI:
3689 	{
3690 		glw::GLuint		   expected_value = rgba32ui[index_of_swizzled_channel];
3691 		const glw::GLuint* image		  = (glw::GLuint*)data;
3692 
3693 		for (size_t i = 0; i < m_output_width * m_output_height; ++i)
3694 		{
3695 			if (image[i] != expected_value)
3696 			{
3697 				TCU_FAIL("Found pixel with wrong value");
3698 			}
3699 		}
3700 	}
3701 	break;
3702 
3703 	default:
3704 		TCU_FAIL("Invalid enum");
3705 		break;
3706 	}
3707 }
3708 
3709 /** Constructor.
3710  *
3711  * @param context Rendering context.
3712  **/
FunctionalTest(deqp::Context & context)3713 FunctionalTest::FunctionalTest(deqp::Context& context)
3714 	: SmokeTest(context, "functional",
3715 				"Verifies that swizzle is respected for textures of different formats and targets")
3716 {
3717 	/* Left blank intentionally */
3718 }
3719 
3720 /** Executes test iteration.
3721  *
3722  *  @return Returns STOP.
3723  */
iterate()3724 tcu::TestNode::IterateResult FunctionalTest::iterate()
3725 {
3726 
3727 #if FUNCTIONAL_TEST_ALL_FORMATS == 0
3728 
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]);
3732 
3733 #endif /* FUNCTIONAL_TEST_ALL_FORMATS == 0 */
3734 
3735 #if FUNCTIONAL_TEST_ALL_TARGETS == 0
3736 
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]);
3739 
3740 #endif /* FUNCTIONAL_TEST_ALL_TARGETS == 0 */
3741 
3742 #if FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES == 0
3743 
3744 	static const size_t access_idx = 4; /* 4 - index of "texelFetch" entry in texture_access_routines */
3745 
3746 #endif /* FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES == 0 */
3747 
3748 #if FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS == 0
3749 
3750 	static const size_t tested_swizzle_combinations[][4] = { { 3, 2, 1,
3751 															   0 }, /* values are indices of entries in valid_values */
3752 															 { 5, 4, 0, 3 },
3753 															 { 5, 5, 5, 5 },
3754 															 { 4, 4, 4, 4 },
3755 															 { 2, 2, 2, 2 } };
3756 	static const size_t n_tested_swizzle_combinations =
3757 		sizeof(tested_swizzle_combinations) / sizeof(tested_swizzle_combinations[0]);
3758 
3759 #endif /* FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS == 0 */
3760 
3761 	/*  */
3762 	bool	   test_result			   = true;
3763 	glw::GLint source_channel_sizes[4] = { 0 };
3764 
3765 	/*  */
3766 	testInit();
3767 
3768 /* Iterate over all cases */
3769 
3770 #if FUNCTIONAL_TEST_ALL_FORMATS
3771 
3772 	for (size_t format_idx = 0; format_idx < n_texture_formats; ++format_idx)
3773 	{
3774 
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))
3778 		{
3779 			continue;
3780 		}
3781 
3782 #else /* FUNCTIONAL_TEST_ALL_FORMATS */
3783 
3784 	for (size_t tested_format_idx = 0; tested_format_idx < n_tested_formats; ++tested_format_idx)
3785 	{
3786 		const size_t format_idx = get_index_of_format(tested_formats[tested_format_idx]);
3787 
3788 #endif /* FUNCTIONAL_TEST_ALL_FORMATS */
3789 
3790 #if FUNCTIONAL_TEST_ALL_TARGETS
3791 
3792 		for (size_t tgt_idx = 0; tgt_idx < n_texture_targets; ++tgt_idx)
3793 		{
3794 
3795 #else /* FUNCTIONAL_TEST_ALL_TARGETS */
3796 
3797 		for (size_t tested_tgt_idx = 0; tested_tgt_idx < n_tested_targets; ++tested_tgt_idx)
3798 		{
3799 			const size_t tgt_idx = get_index_of_target(tested_targets[tested_tgt_idx]);
3800 
3801 #endif /* FUNCTIONAL_TEST_ALL_TARGETS */
3802 
3803 			/* Skip not supported targets */
3804 			if (false == isTargetSupported(tgt_idx))
3805 			{
3806 				continue;
3807 			}
3808 
3809 			/* Skip invalid cases */
3810 			if (false == isTargetSuppByFormat(format_idx, tgt_idx))
3811 			{
3812 				continue;
3813 			}
3814 
3815 			try
3816 			{
3817 				prepareSourceTexture(format_idx, tgt_idx, source_channel_sizes);
3818 
3819 				/* Skip formats not supported by FBO */
3820 				if (false == fillSourceTexture(format_idx, tgt_idx))
3821 				{
3822 					deinitTextures();
3823 					continue;
3824 				}
3825 
3826 #if FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES
3827 
3828 				for (size_t access_idx = 0; access_idx < n_texture_access; ++access_idx)
3829 				{
3830 					/* Skip invalid cases */
3831 					if (false == isTargetSuppByAccess(access_idx, tgt_idx))
3832 					{
3833 						continue;
3834 					}
3835 #else /* FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES */
3836 					/* Skip invalid cases */
3837 					if (false == isTargetSuppByAccess(access_idx, tgt_idx))
3838 					{
3839 						deinitTextures();
3840 						continue;
3841 					}
3842 #endif /* FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES */
3843 
3844 #if FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS
3845 
3846 					for (size_t r = 0; r < n_valid_values; ++r)
3847 					{
3848 						for (size_t g = 0; g < n_valid_values; ++g)
3849 						{
3850 							for (size_t b = 0; b < n_valid_values; ++b)
3851 							{
3852 								for (size_t a = 0; a < n_valid_values; ++a)
3853 								{
3854 
3855 #else /* FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS */
3856 
3857 				for (size_t tested_swizzle_idx = 0; tested_swizzle_idx < n_tested_swizzle_combinations;
3858 					 ++tested_swizzle_idx)
3859 				{
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];
3864 
3865 #endif /* FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS */
3866 
3867 									for (size_t channel_idx = 0; channel_idx < 4; ++channel_idx)
3868 									{
3869 										const testCase test_case = { channel_idx,
3870 																	 format_idx,
3871 																	 tgt_idx,
3872 																	 access_idx,
3873 																	 valid_values[r],
3874 																	 valid_values[g],
3875 																	 valid_values[b],
3876 																	 valid_values[a],
3877 																	 { source_channel_sizes[0], source_channel_sizes[1],
3878 																	   source_channel_sizes[2],
3879 																	   source_channel_sizes[3] } };
3880 
3881 										executeTestCase(test_case);
3882 
3883 										deinitOutputTexture();
3884 									} /* iteration over channels */
3885 
3886 #if FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS
3887 
3888 									/* iteration over swizzle combinations */
3889 								}
3890 							}
3891 						}
3892 					}
3893 
3894 #else /* FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS */
3895 
3896 				} /* iteration over swizzle combinations */
3897 
3898 #endif /* FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS */
3899 
3900 #if FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES
3901 
3902 				} /* iteration over access routines - only when enabled */
3903 
3904 #endif /* FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES */
3905 				deinitTextures();
3906 			} /* try */
3907 			catch (wrongResults& exc)
3908 			{
3909 				logTestCaseDetials(exc.m_test_case);
3910 				m_context.getTestContext().getLog() << tcu::TestLog::Message << exc.what() << tcu::TestLog::EndMessage;
3911 
3912 				test_result = false;
3913 				deinitTextures();
3914 			}
3915 			catch (...)
3916 			{
3917 				deinitTextures();
3918 				throw;
3919 			}
3920 		} /* iteration over texture targets */
3921 
3922 	} /* iteration over texture formats */
3923 
3924 	/* Set result */
3925 	if (true == test_result)
3926 	{
3927 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
3928 	}
3929 	else
3930 	{
3931 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
3932 	}
3933 
3934 	/* Done */
3935 	return STOP;
3936 }
3937 
3938 /** Fills multisampled source texture
3939  *
3940  * @param format_idx Index of format
3941  * @param target_idx Index of target
3942  *
3943  * @return True if operation was successful, false other wise
3944  **/
3945 bool FunctionalTest::fillMSTexture(size_t format_idx, size_t target_idx)
3946 {
3947 	const glw::GLenum target = texture_targets[target_idx].m_target;
3948 
3949 	/*  */
3950 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3951 
3952 	/* Bind FBO */
3953 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_prepare_fbo_id);
3954 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
3955 
3956 	/* Attach texture */
3957 	switch (target)
3958 	{
3959 	case GL_TEXTURE_2D_MULTISAMPLE:
3960 
3961 		gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, m_source_tex_id, 0 /* level */);
3962 		GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture2D");
3963 
3964 		break;
3965 
3966 	case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
3967 
3968 		gl.framebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_source_tex_id, 0 /* level */, 0 /* layer */);
3969 		GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture2D");
3970 
3971 		break;
3972 
3973 	default:
3974 		TCU_FAIL("Invalid enum");
3975 		break;
3976 	}
3977 
3978 	/* Verify status */
3979 	const glw::GLenum status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
3980 	GLU_EXPECT_NO_ERROR(gl.getError(), "CheckFramebufferStatus");
3981 
3982 	if (GL_FRAMEBUFFER_UNSUPPORTED == status)
3983 	{
3984 		/* Unbind */
3985 		gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
3986 		GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
3987 
3988 		return false;
3989 	}
3990 	else if (GL_FRAMEBUFFER_COMPLETE != status)
3991 	{
3992 		TCU_FAIL("Framebuffer is incomplete. Format is supported");
3993 	}
3994 
3995 	/* Set Viewport */
3996 	gl.viewport(0 /* x */, 0 /* y */, m_output_width, m_output_height);
3997 	GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
3998 
3999 	Utils::programInfo program(m_context);
4000 	prepareProgram(format_idx, program);
4001 
4002 	gl.useProgram(program.m_program_object_id);
4003 	GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
4004 
4005 	/* Clear */
4006 	gl.clear(GL_COLOR_BUFFER_BIT);
4007 	GLU_EXPECT_NO_ERROR(gl.getError(), "Clear");
4008 
4009 	/* Draw */
4010 	gl.drawArrays(GL_TRIANGLE_STRIP, 0 /* first */, 4 /* count */);
4011 	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
4012 
4013 	/* Unbind FBO */
4014 	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
4015 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
4016 
4017 	/* Done */
4018 	return true;
4019 }
4020 
4021 /** Fills source texture
4022  *
4023  * @param format_idx Index of format
4024  * @param target_idx Index of target
4025  *
4026  * @return True if operation was successful, false other wise
4027  **/
4028 bool FunctionalTest::fillSourceTexture(size_t format_idx, size_t target_idx)
4029 {
4030 	const glw::GLenum	  target = texture_targets[target_idx].m_target;
4031 	const _texture_format& format = texture_formats[format_idx];
4032 
4033 	/*  */
4034 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4035 
4036 	/* Result */
4037 	bool result = true;
4038 
4039 	/* Bind texture */
4040 	gl.bindTexture(target, m_source_tex_id);
4041 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
4042 
4043 	/* Attach texture */
4044 	switch (target)
4045 	{
4046 	case GL_TEXTURE_1D:
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");
4050 
4051 		break;
4052 
4053 	case GL_TEXTURE_1D_ARRAY:
4054 	case GL_TEXTURE_2D:
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");
4059 
4060 		break;
4061 
4062 	case GL_TEXTURE_2D_ARRAY:
4063 	case GL_TEXTURE_3D:
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");
4067 
4068 		break;
4069 
4070 	case GL_TEXTURE_CUBE_MAP:
4071 		for (size_t i = 0; i < n_cube_map_faces; ++i)
4072 		{
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");
4076 		}
4077 
4078 		break;
4079 
4080 	case GL_TEXTURE_2D_MULTISAMPLE:
4081 	case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
4082 		result = fillMSTexture(format_idx, target_idx);
4083 
4084 		break;
4085 
4086 	default:
4087 		TCU_FAIL("Invalid enum");
4088 		break;
4089 	}
4090 
4091 	/* Unbind */
4092 	gl.bindTexture(target, 0);
4093 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
4094 
4095 	/* Done */
4096 	return result;
4097 }
4098 
4099 /** Prepares program used to fill multisampled texture
4100  *
4101  * @param format_idx Index of texture format
4102  * @param program    Instance of program that will be prepared
4103  **/
4104 void FunctionalTest::prepareProgram(size_t format_idx, Utils::programInfo& program)
4105 {
4106 	static const glw::GLchar* fs_template = "#version 330 core\n"
4107 											"\n"
4108 											"out PREFIXvec4 out_color;\n"
4109 											"\n"
4110 											"void main()\n"
4111 											"{\n"
4112 											"    out_color = PREFIXvec4(VALUES);\n"
4113 											"}\n"
4114 											"\n";
4115 
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 */
4119 
4120 	std::string fs		 = fs_template;
4121 	size_t		position = 0;
4122 
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);
4126 
4127 	program.build(fs.c_str(), vs.c_str());
4128 }
4129 
4130 /** Prepares hardcoded values used by program to fill multisampled textures
4131  *
4132  * @param format_idx Index of texture format
4133  *
4134  * @return Shader source
4135  **/
4136 std::string FunctionalTest::prepareValues(size_t format_idx)
4137 {
4138 	double ch_rgba[4] = { 0.0, 0.0, 0.0, 0.0 };
4139 
4140 	calculate_values_from_source(format_idx, ch_rgba);
4141 
4142 	/* Prepare string */
4143 	std::stringstream stream;
4144 	stream << ch_rgba[0] << ", " << ch_rgba[1] << ", " << ch_rgba[2] << ", " << ch_rgba[3];
4145 
4146 	return stream.str();
4147 }
4148 
4149 /** Verifies if value is in <low:top> range
4150  *
4151  * @tparam T Type oo values
4152  *
4153  * @param value Value to check
4154  * @param low   Lowest acceptable value
4155  * @param top   Highest acceptable value
4156  *
4157  * @return true if value is in range, false otherwise
4158  **/
4159 template <typename T>
4160 bool isInRange(const void* value, const void* low, const void* top)
4161 {
4162 	const T* v_ptr = (const T*)value;
4163 	const T* l_ptr = (const T*)low;
4164 	const T* t_ptr = (const T*)top;
4165 
4166 	if ((*v_ptr > *t_ptr) || (*v_ptr < *l_ptr))
4167 	{
4168 		return false;
4169 	}
4170 
4171 	return true;
4172 }
4173 
4174 /** Verifies contents of output image
4175  *
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
4181  **/
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)
4185 {
4186 	const _texture_format& output_format = texture_formats[output_format_index];
4187 
4188 	glw::GLubyte expected_data_low[8] = { 0 };
4189 	glw::GLubyte expected_data_top[8] = { 0 };
4190 	size_t		 texel_size			  = 0;
4191 
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);
4195 
4196 	for (size_t i = 0; i < m_output_height * m_output_width; ++i)
4197 	{
4198 		const size_t	   offset  = i * texel_size;
4199 		const glw::GLvoid* pointer = data + offset;
4200 
4201 		bool res = false;
4202 
4203 		switch (output_format.m_type)
4204 		{
4205 		case GL_BYTE:
4206 			res = isInRange<glw::GLbyte>(pointer, expected_data_low, expected_data_top);
4207 			break;
4208 		case GL_UNSIGNED_BYTE:
4209 			res = isInRange<glw::GLubyte>(pointer, expected_data_low, expected_data_top);
4210 			break;
4211 		case GL_SHORT:
4212 			res = isInRange<glw::GLshort>(pointer, expected_data_low, expected_data_top);
4213 			break;
4214 		case GL_UNSIGNED_SHORT:
4215 			res = isInRange<glw::GLushort>(pointer, expected_data_low, expected_data_top);
4216 			break;
4217 		case GL_HALF_FLOAT:
4218 			res = isInRange<glw::GLbyte>(pointer, expected_data_low, expected_data_top);
4219 			break;
4220 		case GL_INT:
4221 			res = isInRange<glw::GLint>(pointer, expected_data_low, expected_data_top);
4222 			break;
4223 		case GL_UNSIGNED_INT:
4224 			res = isInRange<glw::GLhalf>(pointer, expected_data_low, expected_data_top);
4225 			break;
4226 		case GL_FLOAT:
4227 			res = isInRange<glw::GLfloat>(pointer, expected_data_low, expected_data_top);
4228 			break;
4229 		default:
4230 			TCU_FAIL("Invalid enum");
4231 			break;
4232 		}
4233 
4234 		if (false == res)
4235 		{
4236 			throw wrongResults(test_case);
4237 		}
4238 	}
4239 }
4240 }
4241 
4242 /** Constructor.
4243  *
4244  *  @param context Rendering context.
4245  **/
4246 TextureSwizzleTests::TextureSwizzleTests(deqp::Context& context)
4247 	: TestCaseGroup(context, "texture_swizzle", "Verifies \"texture_swizzle\" functionality")
4248 {
4249 	/* Left blank on purpose */
4250 }
4251 
4252 /** Initializes a texture_storage_multisample test group.
4253  *
4254  **/
4255 void TextureSwizzleTests::init(void)
4256 {
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));
4261 }
4262 } /* glcts namespace */
4263