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
45namespace gl3cts
46{
47namespace TextureSwizzle
48{
49/* Static constants use by tests */
50/* One and zero */
51static const glw::GLhalf   data_float16_one[]  = { tcu::Float16(1.0).bits() };
52static const glw::GLhalf   data_float16_zero[] = { tcu::Float16(0.0).bits() };
53static const glw::GLfloat  data_float32_one[]  = { 1.0f };
54static const glw::GLfloat  data_float32_zero[] = { 0.0f };
55static const glw::GLbyte   data_snorm8_zero[]  = { 0 };
56static const glw::GLbyte   data_snorm8_one[]   = { 127 };
57static const glw::GLshort  data_snorm16_one[]  = { 32767 };
58static const glw::GLshort  data_snorm16_zero[] = { 0 };
59static const glw::GLubyte  data_unorm8_one[]   = { 255 };
60static const glw::GLubyte  data_unorm8_zero[]  = { 0 };
61static const glw::GLushort data_unorm16_one[]  = { 65535 };
62static const glw::GLushort data_unorm16_zero[] = { 0 };
63static const glw::GLbyte   data_sint8_zero[]   = { 0 };
64static const glw::GLbyte   data_sint8_one[]	= { 1 };
65static const glw::GLshort  data_sint16_one[]   = { 1 };
66static const glw::GLshort  data_sint16_zero[]  = { 0 };
67static const glw::GLint	data_sint32_one[]   = { 1 };
68static const glw::GLint	data_sint32_zero[]  = { 0 };
69static const glw::GLubyte  data_uint8_one[]	= { 1 };
70static const glw::GLubyte  data_uint8_zero[]   = { 0 };
71static const glw::GLushort data_uint16_one[]   = { 1 };
72static const glw::GLushort data_uint16_zero[]  = { 0 };
73static const glw::GLuint   data_uint32_one[]   = { 1 };
74static const glw::GLuint   data_uint32_zero[]  = { 0 };
75
76/* Source and expected data */
77static const glw::GLubyte  src_data_r8[]		   = { 123 };
78static const glw::GLbyte   src_data_r8_snorm[]	 = { -123 };
79static const glw::GLushort src_data_r16[]		   = { 12345 };
80static const glw::GLshort  src_data_r16_snorm[]	= { -12345 };
81static const glw::GLubyte  src_data_rg8[]		   = { 123, 231 };
82static const glw::GLbyte   src_data_rg8_snorm[]	= { -123, -23 };
83static const glw::GLushort src_data_rg16[]		   = { 12345, 54321 };
84static const glw::GLshort  src_data_rg16_snorm[]   = { -12345, -23451 };
85static const glw::GLubyte  src_data_r3_g3_b2[]	 = { 236 };   /* 255, 109, 0 */
86static const glw::GLushort src_data_rgb4[]		   = { 64832 }; /* 5_6_5: 255, 170, 0 */
87static const glw::GLushort src_data_rgb5[]		   = { 64832 };
88static const glw::GLubyte  src_data_rgb8[]		   = { 3, 2, 1 };
89static const glw::GLbyte   src_data_rgb8_snorm[]   = { -1, -2, -3 };
90static const glw::GLushort src_data_rgb16[]		   = { 65535, 32767, 16383 };
91static const glw::GLshort  src_data_rgb16_snorm[]  = { -32767, -16383, -8191 };
92static const glw::GLushort src_data_rgba4[]		   = { 64005 }; /* 255, 170, 0, 85 */
93static const glw::GLushort src_data_rgb5_a1[]	  = { 64852 };
94static const glw::GLubyte  src_data_rgba8[]		   = { 0, 64, 128, 255 };
95static const glw::GLbyte   src_data_rgba8_snorm[]  = { -127, -63, -32, -16 };
96static const glw::GLuint   src_data_rgb10_a2[]	 = { 4291823615u };
97static const glw::GLushort exp_data_rgb10_a2ui[]   = { 1023, 256, 511, 3 };
98static const glw::GLushort src_data_rgba16[]	   = { 65535, 32767, 16383, 8191 };
99static const glw::GLshort  src_data_rgba16_snorm[] = { -32767, -16383, -8191, -4091 };
100static const glw::GLubyte  exp_data_srgb8_alpha8[] = { 13, 1, 255, 32 }; /* See 4.5 core 8.24 */
101static const glw::GLubyte  src_data_srgb8_alpha8[] = { 64, 8, 255, 32 };
102static const glw::GLhalf   src_data_r16f[]		   = { tcu::Float16(1.0).bits() };
103static const glw::GLhalf   src_data_rg16f[]		   = { tcu::Float16(1.0).bits(), tcu::Float16(-1.0).bits() };
104static const glw::GLhalf   src_data_rgb16f[]	   = { tcu::Float16(1.0).bits(), tcu::Float16(-1.0).bits(),
105											   tcu::Float16(2.0).bits() };
106static 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() };
108static const glw::GLfloat src_data_r32f[]	= { 1.0f };
109static const glw::GLfloat src_data_rg32f[]   = { 1.0f, -1.0f };
110static const glw::GLfloat src_data_rgb32f[]  = { 1.0f, -1.0f, 2.0f };
111static const glw::GLfloat src_data_rgba32f[] = { 1.0f, -1.0f, 2.0f, -2.0f };
112
113static const tcu::Float<deUint32, 5, 6, 15, tcu::FLOAT_SUPPORT_DENORM> r11f(0.5);
114static const tcu::Float<deUint32, 5, 6, 15, tcu::FLOAT_SUPPORT_DENORM> g11f(0.75);
115static const tcu::Float<deUint32, 5, 5, 15, tcu::FLOAT_SUPPORT_DENORM> b10f(0.25);
116
117static const glw::GLhalf exp_data_r11f_g11f_b10f[] = { tcu::Float16(0.5).bits(), tcu::Float16(0.75).bits(),
118													   tcu::Float16(0.25).bits() };
119static const glw::GLuint   src_data_r11f_g11f_b10f[]	= { (r11f.bits()) | (g11f.bits() << 11) | (b10f.bits() << 22) };
120static const glw::GLfloat  exp_data_rgb9_e5[]			= { 31.0f, 23.0f, 32.0f };
121static const glw::GLuint   src_data_rgb9_e5[]			= { 2885775608u };
122static const glw::GLbyte   src_data_r8i[]				= { -127 };
123static const glw::GLubyte  src_data_r8ui[]				= { 128 };
124static const glw::GLshort  src_data_r16i[]				= { -32767 };
125static const glw::GLushort src_data_r16ui[]				= { 32768 };
126static const glw::GLint	src_data_r32i[]				= { -1 };
127static const glw::GLuint   src_data_r32ui[]				= { 1 };
128static const glw::GLbyte   src_data_rg8i[]				= { -127, -126 };
129static const glw::GLubyte  src_data_rg8ui[]				= { 128, 129 };
130static const glw::GLshort  src_data_rg16i[]				= { -32767, -32766 };
131static const glw::GLushort src_data_rg16ui[]			= { 32768, 32769 };
132static const glw::GLint	src_data_rg32i[]				= { -1, -2 };
133static const glw::GLuint   src_data_rg32ui[]			= { 1, 2 };
134static const glw::GLbyte   src_data_rgb8i[]				= { -127, -126, -125 };
135static const glw::GLubyte  src_data_rgb8ui[]			= { 128, 129, 130 };
136static const glw::GLshort  src_data_rgb16i[]			= { -32767, -32766, -32765 };
137static const glw::GLushort src_data_rgb16ui[]			= { 32768, 32769, 32770 };
138static const glw::GLint	src_data_rgb32i[]			= { -1, -2, -3 };
139static const glw::GLuint   src_data_rgb32ui[]			= { 1, 2, 3 };
140static const glw::GLbyte   src_data_rgba8i[]			= { -127, -126, -125, -124 };
141static const glw::GLubyte  src_data_rgba8ui[]			= { 128, 129, 130, 131 };
142static const glw::GLshort  src_data_rgba16i[]			= { -32767, -32766, -32765, -32764 };
143static const glw::GLushort src_data_rgba16ui[]			= { 32768, 32769, 32770, 32771 };
144static const glw::GLint	src_data_rgba32i[]			= { -1, -2, -3, -4 };
145static const glw::GLuint   src_data_rgba32ui[]			= { 1, 2, 3, 4 };
146static const glw::GLushort src_data_depth_component16[] = { 32768 };
147static const glw::GLfloat  exp_data_depth_component32[] = { 1.0f };
148static const glw::GLuint   src_data_depth_component32[] = { 4294967295u };
149static const glw::GLfloat  src_data_depth_component32f[] = { 0.75f };
150static const glw::GLuint   src_data_depth24_stencil8[]   = { 4294967041u /* 1.0, 1 */ };
151static const glw::GLuint   src_data_depth32f_stencil8[]  = { 1065353216, 1 /* 1.0f, 1 */ };
152
153/* Texture channels */
154static const glw::GLchar* channels[] = { "r", "g", "b", "a" };
155
156/* Enumerations of cube map faces */
157static 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 };
160static const size_t n_cube_map_faces = sizeof(cube_map_faces) / sizeof(cube_map_faces[0]);
161
162/* Swizzle states */
163static const glw::GLenum states[] = { GL_TEXTURE_SWIZZLE_R, GL_TEXTURE_SWIZZLE_G, GL_TEXTURE_SWIZZLE_B,
164									  GL_TEXTURE_SWIZZLE_A };
165static const size_t n_states = sizeof(states) / sizeof(states[0]);
166
167/* Sampler descriptor */
168struct _sampler
169{
170	const glw::GLchar* m_basic_type;
171	const glw::GLchar* m_sampler_prefix;
172};
173static const _sampler isampler = { "int", "i" };
174static const _sampler usampler = { "uint", "u" };
175static const _sampler sampler  = { "float", "" };
176
177/* Output channel descriptor */
178struct _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 */
185static const _out_ch_desc zero_ch	  = { GL_ZERO, 0 };
186static const _out_ch_desc one_ch	   = { GL_ONE, 0 };
187static const _out_ch_desc float16_zero = { GL_R16F, data_float16_zero };
188static const _out_ch_desc float16_one  = { GL_R16F, data_float16_one };
189static const _out_ch_desc float32_zero = { GL_R32F, data_float32_zero };
190static const _out_ch_desc float32_one  = { GL_R32F, data_float32_one };
191static const _out_ch_desc sint8_zero   = { GL_R8I, data_sint8_zero };
192static const _out_ch_desc sint8_one	= { GL_R8I, data_sint8_one };
193static const _out_ch_desc sint16_zero  = { GL_R16I, data_sint16_zero };
194static const _out_ch_desc sint16_one   = { GL_R16I, data_sint16_one };
195static const _out_ch_desc sint32_zero  = { GL_R32I, data_sint32_zero };
196static const _out_ch_desc sint32_one   = { GL_R32I, data_sint32_one };
197static const _out_ch_desc snorm8_zero  = { GL_R8_SNORM, data_snorm8_zero };
198static const _out_ch_desc snorm8_one   = { GL_R8_SNORM, data_snorm8_one };
199static const _out_ch_desc snorm16_zero = { GL_R16_SNORM, data_snorm16_zero };
200static const _out_ch_desc snorm16_one  = { GL_R16_SNORM, data_snorm16_one };
201static const _out_ch_desc uint8_zero   = { GL_R8UI, data_uint8_zero };
202static const _out_ch_desc uint8_one	= { GL_R8UI, data_uint8_one };
203static const _out_ch_desc uint16_zero  = { GL_R16UI, data_uint16_zero };
204static const _out_ch_desc uint16_one   = { GL_R16UI, data_uint16_one };
205static const _out_ch_desc uint32_zero  = { GL_R32UI, data_uint32_zero };
206static const _out_ch_desc uint32_one   = { GL_R32UI, data_uint32_one };
207static const _out_ch_desc unorm8_zero  = { GL_R8, data_unorm8_zero };
208static const _out_ch_desc unorm8_one   = { GL_R8, data_unorm8_one };
209static const _out_ch_desc unorm16_zero = { GL_R16, data_unorm16_zero };
210static 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 */
213struct _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};
229static 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};
1132static const size_t n_texture_formats = sizeof(texture_formats) / sizeof(texture_formats[0]);
1133
1134/* Texture access routine descriptors */
1135struct _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};
1145static 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 } };
1159static const size_t n_texture_access = sizeof(texture_access) / sizeof(texture_access[0]);
1160
1161/* Texture target descriptor */
1162struct _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
1176static 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};
1187static const size_t n_texture_targets = sizeof(texture_targets) / sizeof(texture_targets[0]);
1188
1189/* Swizzle valid values */
1190static const glw::GLint valid_values[] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, GL_ONE, GL_ZERO };
1191static const size_t		n_valid_values = sizeof(valid_values) / sizeof(valid_values[0]);
1192
1193/* Prototypes */
1194const _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 */
1208void 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 **/
1304void 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 **/
1608double 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 **/
1622template <typename T>
1623void 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 **/
1641void 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 **/
1810size_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 **/
1835size_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 */
1855static const size_t CHANNEL_INDEX_ONE  = 4;
1856static 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 */
1865size_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 **/
1906const _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 **/
1957glw::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 **/
1966Utils::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 **/
1975Utils::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 **/
2009void 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 **/
2044void 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 **/
2093void 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 **/
2153void 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 **/
2169APIErrorsTest::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 **/
2176void 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 */
2191tcu::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 **/
2275void 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 **/
2292IntialStateTest::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 **/
2299void 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 */
2314tcu::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 **/
2345void 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 */
2403const glw::GLsizei SmokeTest::m_depth		  = 1;
2404const glw::GLsizei SmokeTest::m_height		  = 1;
2405const glw::GLsizei SmokeTest::m_width		  = 1;
2406const glw::GLsizei SmokeTest::m_output_height = 8;
2407const glw::GLsizei SmokeTest::m_output_width  = 8;
2408
2409/** Constructor.
2410 *
2411 * @param context Rendering context.
2412 **/
2413SmokeTest::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 **/
2429SmokeTest::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 **/
2442void 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 */
2475tcu::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 **/
2548void 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 **/
2560void 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 */
2580void 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 **/
2612void 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 **/
2662void 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 **/
2717bool 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 **/
2773std::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 **/
2842std::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 **/
2914bool 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 **/
2941bool 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 **/
2996bool 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 **/
3046void 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 **/
3085void 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 **/
3134std::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 **/
3203std::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 **/
3297std::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 **/
3355std::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 **/
3404void 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 **/
3428std::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 **/
3450void 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 **/
3616void 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 **/
3677void 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 **/
3713FunctionalTest::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 */
3724tcu::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 **/
3945bool 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 **/
4028bool 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 **/
4104void 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 **/
4136std::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 **/
4159template <typename T>
4160bool 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 **/
4182void 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 **/
4246TextureSwizzleTests::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 **/
4255void 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