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 */ /*!
26 * \file  gl4cDirectStateAccessTexturesTests.cpp
27 * \brief Conformance tests for the Direct State Access feature functionality (Texture access part).
28 */ /*-----------------------------------------------------------------------------------------------------------*/
29
30/* Uncomment this if SubImageErrorsTest crashes during negative test of TextureSubImage (negative value width/height/depth passed to the function). */
31/* #define TURN_OFF_SUB_IMAGE_ERRORS_TEST_OF_NEGATIVE_WIDTH_HEIGHT_OR_DEPTH */
32
33/* Includes. */
34#include "gl4cDirectStateAccessTests.hpp"
35
36#include "deSharedPtr.hpp"
37
38#include "gluContextInfo.hpp"
39#include "gluDefs.hpp"
40#include "gluPixelTransfer.hpp"
41#include "gluStrUtil.hpp"
42
43#include "tcuFuzzyImageCompare.hpp"
44#include "tcuImageCompare.hpp"
45#include "tcuRenderTarget.hpp"
46#include "tcuSurface.hpp"
47#include "tcuTestLog.hpp"
48
49#include "glw.h"
50#include "glwFunctions.hpp"
51
52#include <algorithm>
53#include <climits>
54#include <set>
55#include <sstream>
56#include <stack>
57#include <string>
58
59namespace gl4cts
60{
61namespace DirectStateAccess
62{
63namespace Textures
64{
65/******************************** Creation Test Implementation   ********************************/
66
67/** @brief Creation Test constructor.
68 *
69 *  @param [in] context     OpenGL context.
70 */
71CreationTest::CreationTest(deqp::Context& context)
72	: deqp::TestCase(context, "textures_creation", "Texture Objects Creation Test")
73{
74	/* Intentionally left blank. */
75}
76
77/** @brief Iterate Creation Test cases.
78 *
79 *  @return Iteration result.
80 */
81tcu::TestNode::IterateResult CreationTest::iterate()
82{
83	/* Shortcut for GL functionality. */
84	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
85
86	/* Get context setup. */
87	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
88	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
89
90	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
91	{
92		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
93
94		return STOP;
95	}
96
97	/* Running tests. */
98	bool is_ok	= true;
99	bool is_error = false;
100
101	/* Textures' objects */
102	static const glw::GLenum texture_targets[] = { GL_TEXTURE_1D,
103												   GL_TEXTURE_2D,
104												   GL_TEXTURE_3D,
105												   GL_TEXTURE_1D_ARRAY,
106												   GL_TEXTURE_2D_ARRAY,
107												   GL_TEXTURE_RECTANGLE,
108												   GL_TEXTURE_CUBE_MAP,
109												   GL_TEXTURE_CUBE_MAP_ARRAY,
110												   GL_TEXTURE_BUFFER,
111												   GL_TEXTURE_2D_MULTISAMPLE,
112												   GL_TEXTURE_2D_MULTISAMPLE_ARRAY };
113	static const glw::GLuint texture_targets_count = sizeof(texture_targets) / sizeof(texture_targets[0]);
114	static const glw::GLuint textures_count		   = 2;
115
116	glw::GLuint textures_legacy[textures_count]						= {};
117	glw::GLuint textures_dsa[texture_targets_count][textures_count] = {};
118
119	try
120	{
121		/* Check legacy state creation. */
122		gl.genTextures(textures_count, textures_legacy);
123		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
124
125		for (glw::GLuint i = 0; i < textures_count; ++i)
126		{
127			if (gl.isTexture(textures_legacy[i]))
128			{
129				is_ok = false;
130
131				/* Log. */
132				m_context.getTestContext().getLog()
133					<< tcu::TestLog::Message
134					<< "GenTextures has created default objects, but it should create only a names."
135					<< tcu::TestLog::EndMessage;
136			}
137		}
138
139		/* Check direct state creation. */
140		for (glw::GLuint j = 0; j < texture_targets_count; ++j)
141		{
142			gl.createTextures(texture_targets[j], textures_count, textures_dsa[j]);
143			GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
144
145			for (glw::GLuint i = 0; i < textures_count; ++i)
146			{
147				if (!gl.isTexture(textures_dsa[j][i]))
148				{
149					is_ok = false;
150
151					/* Log. */
152					m_context.getTestContext().getLog()
153						<< tcu::TestLog::Message << "CreateTextures has not created default objects for target "
154						<< glu::getTextureTargetStr(texture_targets[j]) << "." << tcu::TestLog::EndMessage;
155				}
156			}
157		}
158	}
159	catch (...)
160	{
161		is_ok	= false;
162		is_error = true;
163	}
164
165	/* Cleanup. */
166	for (glw::GLuint i = 0; i < textures_count; ++i)
167	{
168		if (textures_legacy[i])
169		{
170			gl.deleteTextures(1, &textures_legacy[i]);
171
172			textures_legacy[i] = 0;
173		}
174
175		for (glw::GLuint j = 0; j < texture_targets_count; ++j)
176		{
177			if (textures_dsa[j][i])
178			{
179				gl.deleteTextures(1, &textures_dsa[j][i]);
180
181				textures_dsa[j][i] = 0;
182			}
183		}
184	}
185
186	/* Errors clean up. */
187	while (gl.getError())
188		;
189
190	/* Result's setup. */
191	if (is_ok)
192	{
193		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
194	}
195	else
196	{
197		if (is_error)
198		{
199			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
200		}
201		else
202		{
203			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
204		}
205	}
206
207	return STOP;
208}
209
210/******************************** Reference Data Implementation   *****************************/
211
212/** @brief Internal Format selector.
213 *
214 *  @tparam T      Type.
215 *  @tparam S      Size (# of components).
216 *  @tparam N      Is normalized.
217 *
218 *  @return Internal format.
219 */
220template <>
221glw::GLenum Reference::InternalFormat<glw::GLbyte, 1, false>()
222{
223	return GL_R8I;
224}
225
226template <>
227glw::GLenum Reference::InternalFormat<glw::GLbyte, 2, false>()
228{
229	return GL_RG8I;
230}
231
232template <>
233glw::GLenum Reference::InternalFormat<glw::GLbyte, 3, false>()
234{
235	return GL_RGB8I;
236}
237
238template <>
239glw::GLenum Reference::InternalFormat<glw::GLbyte, 4, false>()
240{
241	return GL_RGBA8I;
242}
243
244template <>
245glw::GLenum Reference::InternalFormat<glw::GLubyte, 1, false>()
246{
247	return GL_R8UI;
248}
249
250template <>
251glw::GLenum Reference::InternalFormat<glw::GLubyte, 2, false>()
252{
253	return GL_RG8UI;
254}
255
256template <>
257glw::GLenum Reference::InternalFormat<glw::GLubyte, 3, false>()
258{
259	return GL_RGB8UI;
260}
261
262template <>
263glw::GLenum Reference::InternalFormat<glw::GLubyte, 4, false>()
264{
265	return GL_RGBA8UI;
266}
267
268template <>
269glw::GLenum Reference::InternalFormat<glw::GLshort, 1, false>()
270{
271	return GL_R16I;
272}
273
274template <>
275glw::GLenum Reference::InternalFormat<glw::GLshort, 2, false>()
276{
277	return GL_RG16I;
278}
279
280template <>
281glw::GLenum Reference::InternalFormat<glw::GLshort, 3, false>()
282{
283	return GL_RGB16I;
284}
285
286template <>
287glw::GLenum Reference::InternalFormat<glw::GLshort, 4, false>()
288{
289	return GL_RGBA16I;
290}
291
292template <>
293glw::GLenum Reference::InternalFormat<glw::GLushort, 1, false>()
294{
295	return GL_R16UI;
296}
297
298template <>
299glw::GLenum Reference::InternalFormat<glw::GLushort, 2, false>()
300{
301	return GL_RG16UI;
302}
303
304template <>
305glw::GLenum Reference::InternalFormat<glw::GLushort, 3, false>()
306{
307	return GL_RGB16UI;
308}
309
310template <>
311glw::GLenum Reference::InternalFormat<glw::GLushort, 4, false>()
312{
313	return GL_RGBA16UI;
314}
315
316template <>
317glw::GLenum Reference::InternalFormat<glw::GLint, 1, false>()
318{
319	return GL_R32I;
320}
321
322template <>
323glw::GLenum Reference::InternalFormat<glw::GLint, 2, false>()
324{
325	return GL_RG32I;
326}
327
328template <>
329glw::GLenum Reference::InternalFormat<glw::GLint, 3, false>()
330{
331	return GL_RGB32I;
332}
333
334template <>
335glw::GLenum Reference::InternalFormat<glw::GLint, 4, false>()
336{
337	return GL_RGBA32I;
338}
339
340template <>
341glw::GLenum Reference::InternalFormat<glw::GLuint, 1, false>()
342{
343	return GL_R32UI;
344}
345
346template <>
347glw::GLenum Reference::InternalFormat<glw::GLuint, 2, false>()
348{
349	return GL_RG32UI;
350}
351
352template <>
353glw::GLenum Reference::InternalFormat<glw::GLuint, 3, false>()
354{
355	return GL_RGB32UI;
356}
357
358template <>
359glw::GLenum Reference::InternalFormat<glw::GLuint, 4, false>()
360{
361	return GL_RGBA32UI;
362}
363
364template <>
365glw::GLenum Reference::InternalFormat<glw::GLubyte, 1, true>()
366{
367	return GL_R8;
368}
369
370template <>
371glw::GLenum Reference::InternalFormat<glw::GLubyte, 2, true>()
372{
373	return GL_RG8;
374}
375
376template <>
377glw::GLenum Reference::InternalFormat<glw::GLubyte, 3, true>()
378{
379	return GL_RGB8;
380}
381
382template <>
383glw::GLenum Reference::InternalFormat<glw::GLubyte, 4, true>()
384{
385	return GL_RGBA8;
386}
387
388template <>
389glw::GLenum Reference::InternalFormat<glw::GLushort, 1, true>()
390{
391	return GL_R16;
392}
393
394template <>
395glw::GLenum Reference::InternalFormat<glw::GLushort, 2, true>()
396{
397	return GL_RG16;
398}
399
400template <>
401glw::GLenum Reference::InternalFormat<glw::GLushort, 3, true>()
402{
403	return GL_RGB16;
404}
405
406template <>
407glw::GLenum Reference::InternalFormat<glw::GLushort, 4, true>()
408{
409	return GL_RGBA16;
410}
411
412template <>
413glw::GLenum Reference::InternalFormat<glw::GLfloat, 1, true>()
414{
415	return GL_R32F;
416}
417
418template <>
419glw::GLenum Reference::InternalFormat<glw::GLfloat, 2, true>()
420{
421	return GL_RG32F;
422}
423
424template <>
425glw::GLenum Reference::InternalFormat<glw::GLfloat, 3, true>()
426{
427	return GL_RGB32F;
428}
429
430template <>
431glw::GLenum Reference::InternalFormat<glw::GLfloat, 4, true>()
432{
433	return GL_RGBA32F;
434}
435
436/** @brief Format selector.
437 *
438 *  @tparam S      Size (# of components).
439 *  @tparam N      Is normalized.
440 *
441 *  @return format.
442 */
443template <>
444glw::GLenum Reference::Format<1, false>()
445{
446	return GL_RED_INTEGER;
447}
448
449template <>
450glw::GLenum Reference::Format<2, false>()
451{
452	return GL_RG_INTEGER;
453}
454
455template <>
456glw::GLenum Reference::Format<3, false>()
457{
458	return GL_RGB_INTEGER;
459}
460
461template <>
462glw::GLenum Reference::Format<4, false>()
463{
464	return GL_RGBA_INTEGER;
465}
466
467template <>
468glw::GLenum Reference::Format<1, true>()
469{
470	return GL_RED;
471}
472
473template <>
474glw::GLenum Reference::Format<2, true>()
475{
476	return GL_RG;
477}
478
479template <>
480glw::GLenum Reference::Format<3, true>()
481{
482	return GL_RGB;
483}
484
485template <>
486glw::GLenum Reference::Format<4, true>()
487{
488	return GL_RGBA;
489}
490
491/** @brief Type selector.
492 *
493 *  @tparam T      Type.
494 *
495 *  @return Type.
496 */
497template <>
498glw::GLenum Reference::Type<glw::GLbyte>()
499{
500	return GL_BYTE;
501}
502
503template <>
504glw::GLenum Reference::Type<glw::GLubyte>()
505{
506	return GL_UNSIGNED_BYTE;
507}
508
509template <>
510glw::GLenum Reference::Type<glw::GLshort>()
511{
512	return GL_SHORT;
513}
514
515template <>
516glw::GLenum Reference::Type<glw::GLushort>()
517{
518	return GL_UNSIGNED_SHORT;
519}
520
521template <>
522glw::GLenum Reference::Type<glw::GLint>()
523{
524	return GL_INT;
525}
526
527template <>
528glw::GLenum Reference::Type<glw::GLuint>()
529{
530	return GL_UNSIGNED_INT;
531}
532
533template <>
534glw::GLenum Reference::Type<glw::GLfloat>()
535{
536	return GL_FLOAT;
537}
538
539/** @brief Reference data selector.
540 *
541 *  @tparam T      Type.
542 *  @tparam N      Is normalized.
543 *
544 *  @return Reference data.
545 */
546
547/* RGBA8I */
548template <>
549const glw::GLbyte* Reference::ReferenceData<glw::GLbyte, false>()
550{
551	static const glw::GLbyte reference[s_reference_count] = {
552		0,  -1,  2,  -3,  4,  -5,  6,  -7,  8,  -9,  10, -11, 12, -13, 14, -15, 16, -17, 18, -19, 20, -21, 22, -23,
553		24, -25, 26, -27, 28, -29, 30, -31, 32, -33, 34, -35, 36, -37, 38, -39, 40, -41, 42, -43, 44, -45, 46, -47,
554		48, -49, 50, -51, 52, -53, 54, -55, 56, -57, 58, -59, 60, -61, 62, -63, 64, -65, 66, -67, 68, -69, 70, -71,
555		72, -73, 74, -75, 76, -77, 78, -79, 80, -81, 82, -83, 84, -85, 86, -87, 88, -89, 90, -91, 92, -93, 94, -95
556	};
557	return reference;
558}
559
560/* RGBA8UI */
561template <>
562const glw::GLubyte* Reference::ReferenceData<glw::GLubyte, false>()
563{
564	static const glw::GLubyte reference[s_reference_count] = {
565		0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
566		24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
567		48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
568		72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95
569	};
570	return reference;
571}
572
573/* RGBA16I */
574template <>
575const glw::GLshort* Reference::ReferenceData<glw::GLshort, false>()
576{
577	static const glw::GLshort reference[s_reference_count] = {
578		0,  -1,  2,  -3,  4,  -5,  6,  -7,  8,  -9,  10, -11, 12, -13, 14, -15, 16, -17, 18, -19, 20, -21, 22, -23,
579		24, -25, 26, -27, 28, -29, 30, -31, 32, -33, 34, -35, 36, -37, 38, -39, 40, -41, 42, -43, 44, -45, 46, -47,
580		48, -49, 50, -51, 52, -53, 54, -55, 56, -57, 58, -59, 60, -61, 62, -63, 64, -65, 66, -67, 68, -69, 70, -71,
581		72, -73, 74, -75, 76, -77, 78, -79, 80, -81, 82, -83, 84, -85, 86, -87, 88, -89, 90, -91, 92, -93, 94, -95
582	};
583	return reference;
584}
585
586/* RGBA16UI */
587template <>
588const glw::GLushort* Reference::ReferenceData<glw::GLushort, false>()
589{
590	static const glw::GLushort reference[s_reference_count] = {
591		0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
592		24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
593		48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
594		72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95
595	};
596	return reference;
597}
598
599/* RGBA32I */
600template <>
601const glw::GLint* Reference::ReferenceData<glw::GLint, false>()
602{
603	static const glw::GLint reference[s_reference_count] = {
604		0,  -1,  2,  -3,  4,  -5,  6,  -7,  8,  -9,  10, -11, 12, -13, 14, -15, 16, -17, 18, -19, 20, -21, 22, -23,
605		24, -25, 26, -27, 28, -29, 30, -31, 32, -33, 34, -35, 36, -37, 38, -39, 40, -41, 42, -43, 44, -45, 46, -47,
606		48, -49, 50, -51, 52, -53, 54, -55, 56, -57, 58, -59, 60, -61, 62, -63, 64, -65, 66, -67, 68, -69, 70, -71,
607		72, -73, 74, -75, 76, -77, 78, -79, 80, -81, 82, -83, 84, -85, 86, -87, 88, -89, 90, -91, 92, -93, 94, -95
608	};
609	return reference;
610}
611
612/* RGBA32UI */
613template <>
614const glw::GLuint* Reference::ReferenceData<glw::GLuint, false>()
615{
616	static const glw::GLuint reference[s_reference_count] = {
617		0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
618		24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
619		48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
620		72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95
621	};
622	return reference;
623}
624
625/* RGBA8 */
626template <>
627const glw::GLubyte* Reference::ReferenceData<glw::GLubyte, true>()
628{
629	static const glw::GLubyte reference[s_reference_count] = {
630		0,   2,   5,   8,   10,  13,  16,  18,  21,  24,  26,  29,  32,  34,  37,  40,  42,  45,  48,  51,
631		53,  56,  59,  61,  64,  67,  69,  72,  75,  77,  80,  83,  85,  88,  91,  93,  96,  99,  102, 104,
632		107, 110, 112, 115, 118, 120, 123, 126, 128, 131, 134, 136, 139, 142, 144, 147, 150, 153, 155, 158,
633		161, 163, 166, 169, 171, 174, 177, 179, 182, 185, 187, 190, 193, 195, 198, 201, 204, 206, 209, 212,
634		214, 217, 220, 222, 225, 228, 230, 233, 236, 238, 241, 244, 246, 249, 252, 255
635	};
636	return reference;
637}
638
639/* RGBA16 */
640template <>
641const glw::GLushort* Reference::ReferenceData<glw::GLushort, true>()
642{
643	static const glw::GLushort reference[s_reference_count] = {
644		0,	 689,   1379,  2069,  2759,  3449,  4139,  4828,  5518,  6208,  6898,  7588,  8278,  8967,  9657,  10347,
645		11037, 11727, 12417, 13107, 13796, 14486, 15176, 15866, 16556, 17246, 17935, 18625, 19315, 20005, 20695, 21385,
646		22074, 22764, 23454, 24144, 24834, 25524, 26214, 26903, 27593, 28283, 28973, 29663, 30353, 31042, 31732, 32422,
647		33112, 33802, 34492, 35181, 35871, 36561, 37251, 37941, 38631, 39321, 40010, 40700, 41390, 42080, 42770, 43460,
648		44149, 44839, 45529, 46219, 46909, 47599, 48288, 48978, 49668, 50358, 51048, 51738, 52428, 53117, 53807, 54497,
649		55187, 55877, 56567, 57256, 57946, 58636, 59326, 60016, 60706, 61395, 62085, 62775, 63465, 64155, 64845, 65535
650	};
651	return reference;
652}
653
654/* RGBA32F */
655template <>
656const glw::GLfloat* Reference::ReferenceData<glw::GLfloat, true>()
657{
658	static const glw::GLfloat reference[s_reference_count] = {
659		0.f,		   0.0105263158f, 0.0210526316f, 0.0315789474f, 0.0421052632f, 0.0526315789f,
660		0.0631578947f, 0.0736842105f, 0.0842105263f, 0.0947368421f, 0.1052631579f, 0.1157894737f,
661		0.1263157895f, 0.1368421053f, 0.1473684211f, 0.1578947368f, 0.1684210526f, 0.1789473684f,
662		0.1894736842f, 0.2f,		  0.2105263158f, 0.2210526316f, 0.2315789474f, 0.2421052632f,
663		0.2526315789f, 0.2631578947f, 0.2736842105f, 0.2842105263f, 0.2947368421f, 0.3052631579f,
664		0.3157894737f, 0.3263157895f, 0.3368421053f, 0.3473684211f, 0.3578947368f, 0.3684210526f,
665		0.3789473684f, 0.3894736842f, 0.4f,			 0.4105263158f, 0.4210526316f, 0.4315789474f,
666		0.4421052632f, 0.4526315789f, 0.4631578947f, 0.4736842105f, 0.4842105263f, 0.4947368421f,
667		0.5052631579f, 0.5157894737f, 0.5263157895f, 0.5368421053f, 0.5473684211f, 0.5578947368f,
668		0.5684210526f, 0.5789473684f, 0.5894736842f, 0.6f,			0.6105263158f, 0.6210526316f,
669		0.6315789474f, 0.6421052632f, 0.6526315789f, 0.6631578947f, 0.6736842105f, 0.6842105263f,
670		0.6947368421f, 0.7052631579f, 0.7157894737f, 0.7263157895f, 0.7368421053f, 0.7473684211f,
671		0.7578947368f, 0.7684210526f, 0.7789473684f, 0.7894736842f, 0.8f,		   0.8105263158f,
672		0.8210526316f, 0.8315789474f, 0.8421052632f, 0.8526315789f, 0.8631578947f, 0.8736842105f,
673		0.8842105263f, 0.8947368421f, 0.9052631579f, 0.9157894737f, 0.9263157895f, 0.9368421053f,
674		0.9473684211f, 0.9578947368f, 0.9684210526f, 0.9789473684f, 0.9894736842f, 1.f
675	};
676	return reference;
677}
678
679/* Total number of reference components. */
680glw::GLuint Reference::ReferenceDataCount()
681{
682	return s_reference_count;
683}
684
685/* Total number of reference size in basic machine units. */
686template <typename T>
687glw::GLuint Reference::ReferenceDataSize()
688{
689	return Reference::ReferenceDataCount() * sizeof(T);
690}
691
692/** @brief Comparison function (for floats).
693 *
694 *  @param [in] a      First element.
695 *  @param [in] b      Second element.
696 *
697 *  @return Comparison result.
698 */
699template <>
700bool Reference::Compare<glw::GLfloat>(const glw::GLfloat a, const glw::GLfloat b)
701{
702	if (de::abs(a - b) < 1.f / 256.f)
703	{
704		return true;
705	}
706	return false;
707}
708
709/** @brief Comparison function (integer).
710 *
711 *  @param [in] a      First element.
712 *  @param [in] b      Second element.
713 *
714 *  @return Comparison result.
715 */
716template <typename T>
717bool Reference::Compare(const T a, const T b)
718{
719	return a == b;
720}
721
722/******************************** Buffer Test Implementation   ********************************/
723
724/** @brief Buffer Test constructor.
725 *
726 *  @tparam T      Type.
727 *  @tparam S      Size.
728 *  @tparam N      Is normalized.
729 *
730 *  @param [in] context     OpenGL context.
731 *  @param [in] name     Name of the test.
732 */
733template <typename T, glw::GLint S, bool N>
734BufferTest<T, S, N>::BufferTest(deqp::Context& context, const char* name)
735	: deqp::TestCase(context, name, "Texture Buffer Objects Test")
736	, m_fbo(0)
737	, m_rbo(0)
738	, m_po(0)
739	, m_to(0)
740	, m_bo(0)
741	, m_vao(0)
742{
743	/* Intentionally left blank. */
744}
745
746/** @brief Count of reference data to be teted.
747 *
748 *  @return Count.
749 */
750template <typename T, glw::GLint S, bool N>
751glw::GLuint BufferTest<T, S, N>::TestReferenceDataCount()
752{
753	return s_fbo_size_x * S;
754}
755
756/** @brief Size of reference data to be teted..
757 *
758 *  @return Size.
759 */
760template <typename T, glw::GLint S, bool N>
761glw::GLuint BufferTest<T, S, N>::TestReferenceDataSize()
762{
763	return static_cast<glw::GLint>(TestReferenceDataCount() * sizeof(T));
764}
765
766/** @brief Create buffer textuew.
767 *
768 *  @param [in] use_range_version       Uses TextureBufferRange instead TextureBuffer.
769 *
770 *  @return True if succeded, false otherwise.
771 */
772template <typename T, glw::GLint S, bool N>
773bool BufferTest<T, S, N>::CreateBufferTexture(bool use_range_version)
774{
775	/* Shortcut for GL functionality. */
776	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
777
778	/* Objects creation. */
779	gl.genTextures(1, &m_to);
780	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
781
782	gl.bindTexture(GL_TEXTURE_BUFFER, m_to);
783	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
784
785	gl.genBuffers(1, &m_bo);
786	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers has failed");
787
788	gl.bindBuffer(GL_TEXTURE_BUFFER, m_bo);
789	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
790
791	/* Data setup. */
792	if (use_range_version)
793	{
794		glw::GLint alignment = 1;
795
796		gl.getIntegerv(GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT, &alignment);
797		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");
798
799		const glw::GLuint b_offset = alignment;
800		const glw::GLuint b_size   = TestReferenceDataSize() + b_offset;
801
802		gl.bufferData(GL_TEXTURE_BUFFER, b_size, NULL, GL_STATIC_DRAW);
803		GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData has failed");
804
805		gl.bufferSubData(GL_TEXTURE_BUFFER, b_offset, TestReferenceDataSize(), ReferenceData<T, N>());
806		GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferSubdata has failed");
807
808		gl.textureBufferRange(m_to, InternalFormat<T, S, N>(), m_bo, b_offset, TestReferenceDataSize());
809	}
810	else
811	{
812		gl.bufferData(GL_TEXTURE_BUFFER, TestReferenceDataSize(), ReferenceData<T, N>(), GL_STATIC_DRAW);
813		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData has failed");
814
815		gl.textureBuffer(m_to, InternalFormat<T, S, N>(), m_bo);
816	}
817
818	/* Error checking. */
819	glw::GLenum error;
820
821	if (GL_NO_ERROR != (error = gl.getError()))
822	{
823		/* Log. */
824		m_context.getTestContext().getLog()
825			<< tcu::TestLog::Message << (use_range_version ? ("glTextureBufferRange") : ("glTextureBuffer"))
826			<< " unexpectedly generated error " << glu::getErrorStr(error) << " during test of internal format "
827			<< glu::getTextureFormatStr(InternalFormat<T, S, N>()) << "." << tcu::TestLog::EndMessage;
828
829		CleanBufferTexture();
830
831		return false;
832	}
833
834	return true;
835}
836
837/** @brief Function prepares framebuffer with internal format color attachment.
838 *         Viewport is set up. Content of the framebuffer is cleared.
839 *
840 *  @note The function may throw if unexpected error has occured.
841 *
842 *  @return if the framebuffer returned is supported
843 */
844template <typename T, glw::GLint S, bool N>
845bool BufferTest<T, S, N>::PrepareFramebuffer(const glw::GLenum internal_format)
846{
847	/* Shortcut for GL functionality. */
848	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
849
850	/* Prepare framebuffer. */
851	gl.genFramebuffers(1, &m_fbo);
852	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
853
854	gl.genRenderbuffers(1, &m_rbo);
855	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
856
857	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
858	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
859
860	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo);
861	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
862
863	gl.renderbufferStorage(GL_RENDERBUFFER, internal_format, s_fbo_size_x, s_fbo_size_y);
864	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed.");
865
866	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo);
867	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed.");
868
869	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
870	{
871		if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_UNSUPPORTED)
872			throw tcu::NotSupportedError("unsupported framebuffer configuration");
873		else
874			throw 0;
875	}
876
877	gl.viewport(0, 0, s_fbo_size_x, s_fbo_size_y);
878	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
879
880	/* Clear framebuffer's content. */
881	gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f);
882	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");
883
884	gl.clear(GL_COLOR_BUFFER_BIT);
885	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed.");
886
887	return true;
888}
889
890/** @brief Create program.
891 *
892 *  @param [in] variable_declaration    Choose variable declaration of the fragment shader.
893 */
894template <typename T, glw::GLint S, bool N>
895void BufferTest<T, S, N>::PrepareProgram(const glw::GLchar* variable_declaration)
896{
897	/* Shortcut for GL functionality */
898	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
899
900	struct Shader
901	{
902		glw::GLchar const* source[3];
903		glw::GLsizei const count;
904		glw::GLenum const  type;
905		glw::GLuint		   id;
906	} shader[] = {
907		{ { s_vertex_shader, NULL, NULL }, 1, GL_VERTEX_SHADER, 0 },
908		{ { s_fragment_shader_head, variable_declaration, s_fragment_shader_tail }, 3, GL_FRAGMENT_SHADER, 0 }
909	};
910
911	glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);
912
913	try
914	{
915		/* Create program. */
916		m_po = gl.createProgram();
917		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");
918
919		/* Shader compilation. */
920
921		for (glw::GLuint i = 0; i < shader_count; ++i)
922		{
923			{
924				shader[i].id = gl.createShader(shader[i].type);
925
926				GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");
927
928				gl.attachShader(m_po, shader[i].id);
929
930				GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");
931
932				gl.shaderSource(shader[i].id, shader[i].count, shader[i].source, NULL);
933
934				GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");
935
936				gl.compileShader(shader[i].id);
937
938				GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");
939
940				glw::GLint status = GL_FALSE;
941
942				gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
943				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
944
945				if (GL_FALSE == status)
946				{
947					glw::GLint log_size = 0;
948					gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
949					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
950
951					glw::GLchar* log_text = new glw::GLchar[log_size];
952
953					gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);
954
955					m_context.getTestContext().getLog()
956						<< tcu::TestLog::Message << "Shader compilation has failed.\n"
957						<< "Shader type: " << glu::getShaderTypeStr(shader[i].type) << "\n"
958						<< "Shader compilation error log:\n"
959						<< log_text << "\n"
960						<< "Shader source code:\n"
961						<< shader[i].source[0] << (shader[i].source[1] ? shader[i].source[1] : "")
962						<< (shader[i].source[2] ? shader[i].source[2] : "") << "\n"
963						<< tcu::TestLog::EndMessage;
964
965					delete[] log_text;
966
967					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");
968
969					throw 0;
970				}
971			}
972		}
973
974		/* Link. */
975		gl.linkProgram(m_po);
976
977		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
978
979		glw::GLint status = GL_FALSE;
980
981		gl.getProgramiv(m_po, GL_LINK_STATUS, &status);
982
983		if (GL_TRUE == status)
984		{
985			for (glw::GLuint i = 0; i < shader_count; ++i)
986			{
987				if (shader[i].id)
988				{
989					gl.detachShader(m_po, shader[i].id);
990
991					GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
992				}
993			}
994		}
995		else
996		{
997			glw::GLint log_size = 0;
998
999			gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);
1000
1001			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");
1002
1003			glw::GLchar* log_text = new glw::GLchar[log_size];
1004
1005			gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);
1006
1007			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
1008												<< log_text << "\n"
1009												<< tcu::TestLog::EndMessage;
1010
1011			delete[] log_text;
1012
1013			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");
1014
1015			throw 0;
1016		}
1017	}
1018	catch (...)
1019	{
1020		if (m_po)
1021		{
1022			gl.deleteProgram(m_po);
1023
1024			m_po = 0;
1025		}
1026	}
1027
1028	for (glw::GLuint i = 0; i < shader_count; ++i)
1029	{
1030		if (0 != shader[i].id)
1031		{
1032			gl.deleteShader(shader[i].id);
1033
1034			shader[i].id = 0;
1035		}
1036	}
1037
1038	if (0 == m_po)
1039	{
1040		throw 0;
1041	}
1042}
1043
1044/** @brief Create VAO.
1045 */
1046template <typename T, glw::GLint S, bool N>
1047void BufferTest<T, S, N>::PrepareVertexArray()
1048{
1049	/* Shortcut for GL functionality. */
1050	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1051
1052	gl.genVertexArrays(1, &m_vao);
1053	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays has failed");
1054
1055	gl.bindVertexArray(m_vao);
1056	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray has failed");
1057}
1058
1059/** @brief Test's draw function.
1060 */
1061template <typename T, glw::GLint S, bool N>
1062void BufferTest<T, S, N>::Draw()
1063{
1064	/* Shortcut for GL functionality. */
1065	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1066
1067	gl.useProgram(m_po);
1068	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram has failed");
1069
1070	gl.activeTexture(GL_TEXTURE0);
1071	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture has failed");
1072
1073	gl.bindTextureUnit(0, m_to);
1074	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture has failed");
1075
1076	gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
1077	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays has failed");
1078}
1079
1080/** @brief Compre results with the reference.
1081 *
1082 *  @return True if equal, false otherwise.
1083 */
1084template <typename T, glw::GLint S, bool N>
1085bool BufferTest<T, S, N>::Check()
1086{
1087	/* Shortcut for GL functionality. */
1088	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1089
1090	/* Fetching data. */
1091	std::vector<T> result(TestReferenceDataCount());
1092
1093	gl.pixelStorei(GL_UNPACK_ALIGNMENT, sizeof(T));
1094	GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed");
1095
1096	gl.pixelStorei(GL_PACK_ALIGNMENT, sizeof(T));
1097	GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed");
1098
1099	gl.readnPixels(0, 0, s_fbo_size_x, s_fbo_size_y, Format<S, N>(), Type<T>(), TestReferenceDataSize(),
1100				   (glw::GLvoid*)(&result[0]));
1101	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels has failed");
1102
1103	/* Comparison. */
1104	bool is_ok = true;
1105
1106	for (glw::GLuint i = 0; i < TestReferenceDataCount(); ++i)
1107	{
1108		if (!Compare<T>(result[i], ReferenceData<T, N>()[i]))
1109		{
1110			is_ok = false;
1111
1112			break;
1113		}
1114	}
1115
1116	return is_ok;
1117}
1118
1119/** @brief Test function.
1120 *
1121 *  @param [in] use_range_version   Uses TextureBufferRange instead TextureBuffer.
1122 *
1123 *  @return True if succeeded, false otherwise.
1124 */
1125template <typename T, glw::GLint S, bool N>
1126bool BufferTest<T, S, N>::Test(bool use_range_version)
1127{
1128	/* Setup. */
1129	if (!PrepareFramebuffer(InternalFormat<T, S, N>()))
1130	{
1131		/**
1132                 * If the framebuffer it not supported, means that the
1133                 * tested combination is unsupported for this driver,
1134                 * but allowed to be unsupported by OpenGL spec, so we
1135                 * just skip.
1136                 */
1137		CleanFramebuffer();
1138		CleanErrors();
1139
1140		return true;
1141	}
1142
1143	if (!CreateBufferTexture(use_range_version))
1144	{
1145		CleanFramebuffer();
1146		CleanErrors();
1147
1148		return false;
1149	}
1150
1151	/* Action. */
1152	Draw();
1153
1154	/* Compare results with reference. */
1155	bool result = Check();
1156
1157	/* Cleanup. */
1158	CleanFramebuffer();
1159	CleanBufferTexture();
1160	CleanErrors();
1161
1162	/* Pass result. */
1163	return result;
1164}
1165
1166/** @brief Clean GL objects
1167 */
1168template <typename T, glw::GLint S, bool N>
1169void BufferTest<T, S, N>::CleanBufferTexture()
1170{
1171	/* Shortcut for GL functionality. */
1172	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1173
1174	/* Texture. */
1175	if (m_to)
1176	{
1177		gl.deleteTextures(1, &m_to);
1178
1179		m_to = 0;
1180	}
1181
1182	/* Texture buffer. */
1183	if (m_bo)
1184	{
1185		gl.deleteBuffers(1, &m_bo);
1186
1187		m_bo = 0;
1188	}
1189}
1190
1191/** @brief Clean GL objects
1192 */
1193template <typename T, glw::GLint S, bool N>
1194void BufferTest<T, S, N>::CleanFramebuffer()
1195{
1196	/* Shortcut for GL functionality. */
1197	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1198
1199	/* Framebuffer. */
1200	if (m_fbo)
1201	{
1202		gl.deleteFramebuffers(1, &m_fbo);
1203
1204		m_fbo = 0;
1205	}
1206
1207	/* Renderbuffer. */
1208	if (m_rbo)
1209	{
1210		gl.deleteRenderbuffers(1, &m_rbo);
1211
1212		m_rbo = 0;
1213	}
1214}
1215
1216/** @brief Clean GL objects
1217 */
1218template <typename T, glw::GLint S, bool N>
1219void BufferTest<T, S, N>::CleanProgram()
1220{
1221	/* Shortcut for GL functionality. */
1222	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1223
1224	/* Program. */
1225	if (m_po)
1226	{
1227		gl.useProgram(0);
1228
1229		gl.deleteProgram(m_po);
1230
1231		m_po = 0;
1232	}
1233}
1234
1235/** @brief Clean errors.
1236 */
1237template <typename T, glw::GLint S, bool N>
1238void BufferTest<T, S, N>::CleanErrors()
1239{
1240	/* Shortcut for GL functionality. */
1241	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1242
1243	/* Query all errors until GL_NO_ERROR occure. */
1244	while (GL_NO_ERROR != gl.getError())
1245		;
1246}
1247
1248/** @brief Clean GL objects
1249 */
1250template <typename T, glw::GLint S, bool N>
1251void BufferTest<T, S, N>::CleanVertexArray()
1252{
1253	/* Shortcut for GL functionality. */
1254	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1255
1256	if (m_vao)
1257	{
1258		gl.bindVertexArray(0);
1259
1260		gl.deleteVertexArrays(1, &m_vao);
1261
1262		m_vao = 0;
1263	}
1264}
1265
1266/** @brief Iterate Buffer Test cases.
1267 *
1268 *  @return Iteration result.
1269 */
1270template <typename T, glw::GLint S, bool N>
1271tcu::TestNode::IterateResult BufferTest<T, S, N>::iterate()
1272{
1273	/* Shortcut for GL functionality. */
1274	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1275
1276	/* Get context setup. */
1277	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
1278	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
1279
1280	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
1281	{
1282		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
1283
1284		return STOP;
1285	}
1286
1287	/* Running tests. */
1288	bool is_ok	= true;
1289	bool is_error = false;
1290
1291	try
1292	{
1293		PrepareVertexArray();
1294
1295		PrepareProgram(FragmentShaderDeclaration());
1296
1297		for (glw::GLuint i = 0; i < 2; ++i)
1298		{
1299			bool use_range = (i == 1);
1300			is_ok &= Test(use_range);
1301			CleanErrors();
1302		}
1303
1304		CleanProgram();
1305	}
1306	catch (tcu::NotSupportedError e)
1307	{
1308		throw e;
1309	}
1310	catch (...)
1311	{
1312		is_ok	= false;
1313		is_error = true;
1314	}
1315
1316	/* Cleanup. */
1317	CleanBufferTexture();
1318	CleanFramebuffer();
1319	CleanProgram();
1320	CleanErrors();
1321	CleanVertexArray();
1322
1323	/* Errors clean up. */
1324	while (gl.getError())
1325		;
1326
1327	/* Result's setup. */
1328	if (is_ok)
1329	{
1330		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1331	}
1332	else
1333	{
1334		if (is_error)
1335		{
1336			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
1337		}
1338		else
1339		{
1340			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1341		}
1342	}
1343
1344	return STOP;
1345}
1346
1347/* Vertex shader source code. */
1348template <typename T, glw::GLint S, bool N>
1349const glw::GLchar* BufferTest<T, S, N>::s_vertex_shader = "#version 450\n"
1350														  "\n"
1351														  "void main()\n"
1352														  "{\n"
1353														  "    switch(gl_VertexID)\n"
1354														  "    {\n"
1355														  "        case 0:\n"
1356														  "            gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
1357														  "            break;\n"
1358														  "        case 1:\n"
1359														  "            gl_Position = vec4( 1.0, 1.0, 0.0, 1.0);\n"
1360														  "            break;\n"
1361														  "        case 2:\n"
1362														  "            gl_Position = vec4(-1.0,-1.0, 0.0, 1.0);\n"
1363														  "            break;\n"
1364														  "        case 3:\n"
1365														  "            gl_Position = vec4( 1.0,-1.0, 0.0, 1.0);\n"
1366														  "            break;\n"
1367														  "    }\n"
1368														  "}\n";
1369
1370/* Fragment shader source program. */
1371template <typename T, glw::GLint S, bool N>
1372const glw::GLchar* BufferTest<T, S, N>::s_fragment_shader_head = "#version 450\n"
1373																 "\n"
1374																 "layout(pixel_center_integer) in vec4 gl_FragCoord;\n"
1375																 "\n";
1376
1377template <typename T, glw::GLint S, bool N>
1378const glw::GLchar* BufferTest<T, S, N>::s_fragment_shader_fdecl_lowp = "uniform samplerBuffer texture_input;\n"
1379																	   "out     vec4          texture_output;\n";
1380
1381template <typename T, glw::GLint S, bool N>
1382const glw::GLchar* BufferTest<T, S, N>::s_fragment_shader_idecl_lowp = "uniform isamplerBuffer texture_input;\n"
1383																	   "out     ivec4          texture_output;\n";
1384
1385template <typename T, glw::GLint S, bool N>
1386const glw::GLchar* BufferTest<T, S, N>::s_fragment_shader_udecl_lowp = "uniform usamplerBuffer texture_input;\n"
1387																	   "out     uvec4          texture_output;\n";
1388
1389template <typename T, glw::GLint S, bool N>
1390const glw::GLchar* BufferTest<T, S, N>::s_fragment_shader_fdecl_mediump = "uniform samplerBuffer texture_input;\n"
1391																		  "out     vec4          texture_output;\n";
1392
1393template <typename T, glw::GLint S, bool N>
1394const glw::GLchar* BufferTest<T, S, N>::s_fragment_shader_idecl_mediump = "uniform isamplerBuffer texture_input;\n"
1395																		  "out     ivec4          texture_output;\n";
1396
1397template <typename T, glw::GLint S, bool N>
1398const glw::GLchar* BufferTest<T, S, N>::s_fragment_shader_udecl_mediump = "uniform usamplerBuffer texture_input;\n"
1399																		  "out     uvec4          texture_output;\n";
1400
1401template <typename T, glw::GLint S, bool N>
1402const glw::GLchar* BufferTest<T, S, N>::s_fragment_shader_fdecl_highp = "uniform samplerBuffer texture_input;\n"
1403																		"out     vec4          texture_output;\n";
1404
1405template <typename T, glw::GLint S, bool N>
1406const glw::GLchar* BufferTest<T, S, N>::s_fragment_shader_idecl_highp = "uniform isamplerBuffer texture_input;\n"
1407																		"out     ivec4          texture_output;\n";
1408
1409template <typename T, glw::GLint S, bool N>
1410const glw::GLchar* BufferTest<T, S, N>::s_fragment_shader_udecl_highp = "uniform usamplerBuffer texture_input;\n"
1411																		"out     uvec4          texture_output;\n";
1412
1413template <typename T, glw::GLint S, bool N>
1414const glw::GLchar* BufferTest<T, S, N>::s_fragment_shader_tail =
1415	"\n"
1416	"void main()\n"
1417	"{\n"
1418	"    texture_output = texelFetch(texture_input, int(gl_FragCoord.x));\n"
1419	"}\n";
1420
1421template class BufferTest<glw::GLbyte, 1, false>;
1422template class BufferTest<glw::GLbyte, 2, false>;
1423template class BufferTest<glw::GLbyte, 4, false>;
1424
1425template class BufferTest<glw::GLubyte, 1, false>;
1426template class BufferTest<glw::GLubyte, 2, false>;
1427template class BufferTest<glw::GLubyte, 4, false>;
1428template class BufferTest<glw::GLubyte, 1, true>;
1429template class BufferTest<glw::GLubyte, 2, true>;
1430template class BufferTest<glw::GLubyte, 4, true>;
1431
1432template class BufferTest<glw::GLshort, 1, false>;
1433template class BufferTest<glw::GLshort, 2, false>;
1434template class BufferTest<glw::GLshort, 4, false>;
1435
1436template class BufferTest<glw::GLushort, 1, false>;
1437template class BufferTest<glw::GLushort, 2, false>;
1438template class BufferTest<glw::GLushort, 4, false>;
1439template class BufferTest<glw::GLushort, 1, true>;
1440template class BufferTest<glw::GLushort, 2, true>;
1441template class BufferTest<glw::GLushort, 4, true>;
1442
1443template class BufferTest<glw::GLint, 1, false>;
1444template class BufferTest<glw::GLint, 2, false>;
1445template class BufferTest<glw::GLint, 3, false>;
1446template class BufferTest<glw::GLint, 4, false>;
1447
1448template class BufferTest<glw::GLuint, 1, false>;
1449template class BufferTest<glw::GLuint, 2, false>;
1450template class BufferTest<glw::GLuint, 3, false>;
1451template class BufferTest<glw::GLuint, 4, false>;
1452
1453template class BufferTest<glw::GLfloat, 1, true>;
1454template class BufferTest<glw::GLfloat, 2, true>;
1455template class BufferTest<glw::GLfloat, 3, true>;
1456template class BufferTest<glw::GLfloat, 4, true>;
1457
1458/******************************** Storage and SubImage Test Implementation   ********************************/
1459
1460/** @brief Storage Test constructor.
1461 *
1462 *  @tparam T      Type.
1463 *  @tparam S      Size.
1464 *  @tparam N      Is normalized.
1465 *  @tparam D      Texture dimension.
1466 *  @tparam I      Choose between SubImage and Storage tests.
1467 *
1468 *  @param [in] context     OpenGL context.
1469 *  @param [in] name        Name of the test.
1470 */
1471template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
1472StorageAndSubImageTest<T, S, N, D, I>::StorageAndSubImageTest(deqp::Context& context, const char* name)
1473	: deqp::TestCase(context, name, "Texture Storage and SubImage Test")
1474	, m_fbo(0)
1475	, m_rbo(0)
1476	, m_po(0)
1477	, m_to(0)
1478	, m_vao(0)
1479{
1480	/* Intentionally left blank. */
1481}
1482
1483/** @brief Count of reference data to be teted.
1484 *
1485 *  @return Count.
1486 */
1487template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
1488glw::GLuint StorageAndSubImageTest<T, S, N, D, I>::TestReferenceDataCount()
1489{
1490	return 2 /* 1D */ * ((D > 1) ? 3 : 1) /* 2D */ * ((D > 2) ? 4 : 1) /* 3D */ * S /* components */;
1491}
1492
1493/** @brief Size of reference data to be teted.
1494 *
1495 *  @tparam T      Type.
1496 *  @tparam S      Size (# of components).
1497 *  @tparam D      Texture dimenisons.
1498 *
1499 *  @return Size.
1500 */
1501template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
1502glw::GLuint StorageAndSubImageTest<T, S, N, D, I>::TestReferenceDataSize()
1503{
1504	return static_cast<glw::GLint>(TestReferenceDataCount() * sizeof(T));
1505}
1506
1507/** @brief Height, width or depth of reference data to be teted.
1508 *
1509 *  @return Height, width or depth.
1510 */
1511template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
1512glw::GLuint StorageAndSubImageTest<T, S, N, D, I>::TestReferenceDataHeight()
1513{
1514	switch (D)
1515	{
1516	case 2:
1517	case 3:
1518		return 3;
1519	default:
1520		return 1;
1521	}
1522}
1523
1524template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
1525glw::GLuint StorageAndSubImageTest<T, S, N, D, I>::TestReferenceDataDepth()
1526{
1527	switch (D)
1528	{
1529	case 3:
1530		return 4;
1531	default:
1532		return 1;
1533	}
1534}
1535
1536template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
1537glw::GLuint StorageAndSubImageTest<T, S, N, D, I>::TestReferenceDataWidth()
1538{
1539	return 2;
1540}
1541
1542/** @brief Fragment shader declaration selector.
1543 *
1544 *  @return Frgment shader source code part.
1545 */
1546template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
1547const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::FragmentShaderDeclaration()
1548{
1549	if (typeid(T) == typeid(glw::GLbyte))
1550	{
1551		switch (D)
1552		{
1553		case 1:
1554			return s_fragment_shader_1D_idecl_lowp;
1555		case 2:
1556			return s_fragment_shader_2D_idecl_lowp;
1557		case 3:
1558			return s_fragment_shader_3D_idecl_lowp;
1559		default:
1560			DE_ASSERT("invalid texture dimension");
1561			return DE_NULL;
1562		}
1563	}
1564
1565	if (typeid(T) == typeid(glw::GLubyte))
1566	{
1567		if (N)
1568		{
1569			switch (D)
1570			{
1571			case 1:
1572				return s_fragment_shader_1D_fdecl_lowp;
1573			case 2:
1574				return s_fragment_shader_2D_fdecl_lowp;
1575			case 3:
1576				return s_fragment_shader_3D_fdecl_lowp;
1577			default:
1578				DE_ASSERT("invalid texture dimension");
1579				return DE_NULL;
1580			}
1581		}
1582		else
1583		{
1584			switch (D)
1585			{
1586			case 1:
1587				return s_fragment_shader_1D_udecl_lowp;
1588			case 2:
1589				return s_fragment_shader_2D_udecl_lowp;
1590			case 3:
1591				return s_fragment_shader_3D_udecl_lowp;
1592			default:
1593				DE_ASSERT("invalid texture dimension");
1594				return DE_NULL;
1595			}
1596		}
1597	}
1598
1599	if (typeid(T) == typeid(glw::GLshort))
1600	{
1601		switch (D)
1602		{
1603		case 1:
1604			return s_fragment_shader_1D_idecl_mediump;
1605		case 2:
1606			return s_fragment_shader_2D_idecl_mediump;
1607		case 3:
1608			return s_fragment_shader_3D_idecl_mediump;
1609		default:
1610			DE_ASSERT("invalid texture dimension");
1611			return DE_NULL;
1612		}
1613	}
1614
1615	if (typeid(T) == typeid(glw::GLushort))
1616	{
1617		if (N)
1618		{
1619			switch (D)
1620			{
1621			case 1:
1622				return s_fragment_shader_1D_fdecl_mediump;
1623			case 2:
1624				return s_fragment_shader_2D_fdecl_mediump;
1625			case 3:
1626				return s_fragment_shader_3D_fdecl_mediump;
1627			default:
1628				DE_ASSERT("invalid texture dimension");
1629				return DE_NULL;
1630			}
1631		}
1632		else
1633		{
1634			switch (D)
1635			{
1636			case 1:
1637				return s_fragment_shader_1D_udecl_mediump;
1638			case 2:
1639				return s_fragment_shader_2D_udecl_mediump;
1640			case 3:
1641				return s_fragment_shader_3D_udecl_mediump;
1642			default:
1643				DE_ASSERT("invalid texture dimension");
1644				return DE_NULL;
1645			}
1646		}
1647	}
1648
1649	if (typeid(T) == typeid(glw::GLint))
1650	{
1651		switch (D)
1652		{
1653		case 1:
1654			return s_fragment_shader_1D_idecl_highp;
1655		case 2:
1656			return s_fragment_shader_2D_idecl_highp;
1657		case 3:
1658			return s_fragment_shader_3D_idecl_highp;
1659		default:
1660			DE_ASSERT("invalid texture dimension");
1661			return DE_NULL;
1662		}
1663	}
1664
1665	if (typeid(T) == typeid(glw::GLuint))
1666	{
1667		switch (D)
1668		{
1669		case 1:
1670			return s_fragment_shader_1D_udecl_highp;
1671		case 2:
1672			return s_fragment_shader_2D_udecl_highp;
1673		case 3:
1674			return s_fragment_shader_3D_udecl_highp;
1675		default:
1676			DE_ASSERT("invalid texture dimension");
1677			return DE_NULL;
1678		}
1679	}
1680
1681	switch (D)
1682	{
1683	case 1:
1684		return s_fragment_shader_1D_fdecl_highp;
1685	case 2:
1686		return s_fragment_shader_2D_fdecl_highp;
1687	case 3:
1688		return s_fragment_shader_3D_fdecl_highp;
1689	default:
1690		DE_ASSERT("invalid texture dimension");
1691		return DE_NULL;
1692	}
1693}
1694
1695/** @brief Fragment shader tail selector.
1696 *
1697 *  @tparam D      Texture dimenisons.
1698 *
1699 *  @return Frgment shader source code part.
1700 */
1701template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
1702const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::FragmentShaderTail()
1703{
1704	switch (D)
1705	{
1706	case 1:
1707		return s_fragment_shader_1D_tail;
1708	case 2:
1709		return s_fragment_shader_2D_tail;
1710	case 3:
1711		return s_fragment_shader_3D_tail;
1712	default:
1713		DE_ASSERT("invalid texture dimension");
1714		return DE_NULL;
1715	}
1716}
1717
1718/** @brief Texture target selector.
1719 *
1720 *  @tparam D      Texture dimenisons.
1721 *
1722 *  @return Texture target.
1723 */
1724template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
1725glw::GLenum StorageAndSubImageTest<T, S, N, D, I>::TextureTarget()
1726{
1727	switch (D)
1728	{
1729	case 1:
1730		return GL_TEXTURE_1D;
1731	case 2:
1732		return GL_TEXTURE_2D;
1733	case 3:
1734		return GL_TEXTURE_3D;
1735	default:
1736		DE_ASSERT("invalid texture dimension");
1737		return DE_NULL;
1738	}
1739}
1740
1741/** @brief TextureStorage* wrapper.
1742 *
1743 *  @return true if succeed (in legacy always or throw), false otherwise.
1744 */
1745template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
1746bool StorageAndSubImageTest<T, S, N, D, I>::TextureStorage(glw::GLenum target, glw::GLuint texture, glw::GLsizei levels,
1747														   glw::GLenum internalformat, glw::GLsizei width,
1748														   glw::GLsizei height, glw::GLsizei depth)
1749{
1750	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1751
1752	if (I)
1753	{
1754		switch (D)
1755		{
1756		case 1:
1757			gl.texStorage1D(target, levels, internalformat, width);
1758			break;
1759		case 2:
1760			gl.texStorage2D(target, levels, internalformat, width, height);
1761			break;
1762		case 3:
1763			gl.texStorage3D(target, levels, internalformat, width, height, depth);
1764			break;
1765		default:
1766			DE_ASSERT("invalid texture dimension");
1767		}
1768
1769		/* TextureSubImage* (not TextureStorage*) is tested */
1770		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage*() has failed");
1771		return true;
1772	}
1773	else
1774	{
1775		switch (D)
1776		{
1777		case 1:
1778			gl.textureStorage1D(texture, levels, internalformat, width);
1779			break;
1780		case 2:
1781			gl.textureStorage2D(texture, levels, internalformat, width, height);
1782			break;
1783		case 3:
1784			gl.textureStorage3D(texture, levels, internalformat, width, height, depth);
1785			break;
1786		default:
1787			DE_ASSERT("invalid texture dimension");
1788		}
1789
1790		glw::GLenum error;
1791		if (GL_NO_ERROR != (error = gl.getError()))
1792		{
1793			m_context.getTestContext().getLog()
1794				<< tcu::TestLog::Message << "glTextureStorage" << D << "D unexpectedly generated error " << glu::getErrorStr(error)
1795				<< " during test with levels " << levels << ", internal format " << internalformat
1796				<< " width=" << width << " height=" << height << " depth=" << depth
1797				<< "." << tcu::TestLog::EndMessage;
1798
1799			CleanTexture();
1800			CleanErrors();
1801
1802			return false;
1803		}
1804
1805		return true;
1806	}
1807}
1808
1809/** @brief TextureSubImage* wrapper.
1810 *
1811 *  @return true if suuceed (in legacy always or throw), false otherwise.
1812 */
1813template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
1814bool StorageAndSubImageTest<T, S, N, D, I>::TextureSubImage(glw::GLenum target, glw::GLuint texture, glw::GLint level,
1815															glw::GLsizei width, glw::GLsizei height, glw::GLsizei depth,
1816															glw::GLenum format, glw::GLenum type, const glw::GLvoid* data)
1817{
1818	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1819
1820	if (I)
1821	{
1822		switch (D)
1823		{
1824		case 1:
1825			gl.textureSubImage1D(texture, level, 0, width, format, type, data);
1826			break;
1827		case 2:
1828			gl.textureSubImage2D(texture, level, 0, 0, width, height, format, type, data);
1829			break;
1830		case 3:
1831			gl.textureSubImage3D(texture, level, 0, 0, 0, width, height, depth, format, type, data);
1832			break;
1833		default:
1834			DE_ASSERT("invalid texture dimension");
1835		}
1836
1837		glw::GLenum error;
1838		if (GL_NO_ERROR != (error = gl.getError()))
1839		{
1840			m_context.getTestContext().getLog()
1841				<< tcu::TestLog::Message << "glTextureSubImage" << D << "D unexpectedly generated error " << glu::getErrorStr(error)
1842				<< " during test with level " << level << ", width=" << width << ", height=" << height << ", depth=" << depth
1843				<< " format " << glu::getTextureFormatStr(format) << " and type " << glu::getTypeStr(type) << "."
1844				<< tcu::TestLog::EndMessage;
1845
1846			CleanTexture();
1847			CleanErrors();
1848
1849			return false;
1850		}
1851
1852		return true;
1853	}
1854	else
1855	{
1856		switch (D)
1857		{
1858		case 1:
1859			gl.texSubImage1D(target, level, 0, width, format, type, data);
1860			break;
1861		case 2:
1862			gl.texSubImage2D(target, level, 0, 0, width, height, format, type, data);
1863			break;
1864		case 3:
1865			gl.texSubImage3D(target, level, 0, 0, 0, width, height, depth, format, type, data);
1866			break;
1867		default:
1868			DE_ASSERT("invalid texture dimension");
1869		}
1870
1871		/* TextureStorage* (not TextureSubImage) is tested */
1872		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage*() has failed");
1873		return true;
1874	}
1875}
1876
1877/** @brief Create texture.
1878 *
1879 *  @tparam T      Type.
1880 *  @tparam S      Size (# of components).
1881 *  @tparam N      Is normalized.
1882 *  @tparam D      Dimmensions.
1883 *  @tparam I      Test SubImage or Storage.
1884 *
1885 *  @return True if succeded, false otherwise.
1886 */
1887template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
1888bool StorageAndSubImageTest<T, S, N, D, I>::CreateTexture()
1889{
1890	/* Shortcut for GL functionality. */
1891	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1892
1893	/* Objects creation. */
1894	gl.genTextures(1, &m_to);
1895	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
1896
1897	gl.bindTexture(TextureTarget(), m_to);
1898	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
1899
1900	/* Storage creation. */
1901	if (TextureStorage(TextureTarget(), m_to, 1, InternalFormat<T, S, N>(), TestReferenceDataWidth(),
1902					   TestReferenceDataHeight(), TestReferenceDataDepth()))
1903	{
1904		/* Data setup. */
1905		if (TextureSubImage(TextureTarget(), m_to, 0, TestReferenceDataWidth(), TestReferenceDataHeight(), TestReferenceDataDepth(),
1906							Format<S, N>(), Type<T>(), ReferenceData<T, N>()))
1907		{
1908			glTexParameteri(TextureTarget(), GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1909			glTexParameteri(TextureTarget(), GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1910			return true;
1911		}
1912	}
1913
1914	CleanTexture();
1915
1916	return false;
1917}
1918
1919/** @brief Compre results with the reference.
1920 *
1921 *  @return True if equal, false otherwise.
1922 */
1923template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
1924bool StorageAndSubImageTest<T, S, N, D, I>::Check()
1925{
1926	/* Shortcut for GL functionality. */
1927	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1928
1929	/* Fetching data. */
1930	std::vector<T> result(TestReferenceDataCount());
1931
1932	glw::GLuint fbo_size_x = 0;
1933
1934	switch (D)
1935	{
1936	case 1:
1937		fbo_size_x = 2;
1938		break;
1939	case 2:
1940		fbo_size_x = 2 * 3;
1941		break;
1942	case 3:
1943		fbo_size_x = 2 * 3 * 4;
1944		break;
1945	default:
1946		throw 0;
1947	}
1948
1949	gl.readnPixels(0, 0, fbo_size_x, 1, Format<S, N>(), Type<T>(), TestReferenceDataSize(),
1950				   (glw::GLvoid*)(&result[0]));
1951	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels has failed");
1952
1953	/* Comparison. */
1954	for (glw::GLuint i = 0; i < TestReferenceDataCount(); ++i)
1955	{
1956		if (!Compare<T>(result[i], ReferenceData<T, N>()[i]))
1957		{
1958			return false;
1959		}
1960	}
1961
1962	return true;
1963}
1964
1965/** @brief Test case function.
1966 *
1967 *  @return True if test succeeded, false otherwise.
1968 */
1969template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
1970bool StorageAndSubImageTest<T, S, N, D, I>::Test()
1971{
1972	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1973
1974	gl.pixelStorei(GL_UNPACK_ALIGNMENT, sizeof(T));
1975	GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed");
1976
1977	gl.pixelStorei(GL_PACK_ALIGNMENT, sizeof(T));
1978	GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed");
1979
1980	/* Setup. */
1981	PrepareFramebuffer(InternalFormat<T, S, N>());
1982
1983	if (!CreateTexture())
1984	{
1985		return false;
1986	}
1987
1988	/* Action. */
1989	Draw();
1990
1991	/* Compare results with reference. */
1992	bool result = Check();
1993
1994	/* Cleanup. */
1995	CleanTexture();
1996	CleanFramebuffer();
1997	CleanErrors();
1998
1999	/* Pass result. */
2000	return result;
2001}
2002
2003/** @brief Function prepares framebuffer with internal format color attachment.
2004 *         Viewport is set up. Content of the framebuffer is cleared.
2005 *
2006 *  @note The function may throw if unexpected error has occured.
2007 */
2008template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2009void StorageAndSubImageTest<T, S, N, D, I>::PrepareFramebuffer(const glw::GLenum internal_format)
2010{
2011	/* Shortcut for GL functionality. */
2012	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2013
2014	/* Prepare framebuffer. */
2015	gl.genFramebuffers(1, &m_fbo);
2016	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
2017
2018	gl.genRenderbuffers(1, &m_rbo);
2019	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
2020
2021	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
2022	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
2023
2024	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo);
2025	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
2026
2027	glw::GLuint fbo_size_x = 0;
2028
2029	switch (D)
2030	{
2031	case 1:
2032		fbo_size_x = 2;
2033		break;
2034	case 2:
2035		fbo_size_x = 2 * 3;
2036		break;
2037	case 3:
2038		fbo_size_x = 2 * 3 * 4;
2039		break;
2040	default:
2041		throw 0;
2042	}
2043
2044	gl.renderbufferStorage(GL_RENDERBUFFER, internal_format, fbo_size_x, 1);
2045	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed.");
2046
2047	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo);
2048	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed.");
2049
2050	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
2051	{
2052		if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_UNSUPPORTED)
2053			throw tcu::NotSupportedError("unsupported framebuffer configuration");
2054		else
2055			throw 0;
2056	}
2057
2058	gl.viewport(0, 0, fbo_size_x, 1);
2059	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
2060
2061	/* Clear framebuffer's content. */
2062	gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f);
2063	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");
2064
2065	gl.clear(GL_COLOR_BUFFER_BIT);
2066	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed.");
2067}
2068
2069/** @brief Prepare program
2070 *
2071 *  @param [in] variable_declaration      Variables declaration part of fragment shader source code.
2072 *  @param [in] tail                      Tail part of fragment shader source code.
2073 */
2074template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2075void StorageAndSubImageTest<T, S, N, D, I>::PrepareProgram(const glw::GLchar* variable_declaration, const glw::GLchar* tail)
2076{
2077	/* Shortcut for GL functionality */
2078	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2079
2080	struct Shader
2081	{
2082		glw::GLchar const* source[3];
2083		glw::GLsizei const count;
2084		glw::GLenum const  type;
2085		glw::GLuint		   id;
2086	} shader[] = { { { s_vertex_shader, NULL, NULL }, 1, GL_VERTEX_SHADER, 0 },
2087				   { { s_fragment_shader_head, variable_declaration, tail }, 3, GL_FRAGMENT_SHADER, 0 } };
2088
2089	glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);
2090
2091	try
2092	{
2093		/* Create program. */
2094		m_po = gl.createProgram();
2095		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");
2096
2097		/* Shader compilation. */
2098
2099		for (glw::GLuint i = 0; i < shader_count; ++i)
2100		{
2101			{
2102				shader[i].id = gl.createShader(shader[i].type);
2103
2104				GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");
2105
2106				gl.attachShader(m_po, shader[i].id);
2107
2108				GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");
2109
2110				gl.shaderSource(shader[i].id, shader[i].count, shader[i].source, NULL);
2111
2112				GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");
2113
2114				gl.compileShader(shader[i].id);
2115
2116				GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");
2117
2118				glw::GLint status = GL_FALSE;
2119
2120				gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
2121				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
2122
2123				if (GL_FALSE == status)
2124				{
2125					glw::GLint log_size = 0;
2126					gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
2127					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
2128
2129					glw::GLchar* log_text = new glw::GLchar[log_size];
2130
2131					gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);
2132
2133					m_context.getTestContext().getLog()
2134						<< tcu::TestLog::Message << "Shader compilation has failed.\n"
2135						<< "Shader type: " << glu::getShaderTypeStr(shader[i].type) << "\n"
2136						<< "Shader compilation error log:\n"
2137						<< log_text << "\n"
2138						<< "Shader source code:\n"
2139						<< shader[i].source[0] << (shader[i].source[1] ? shader[i].source[1] : "")
2140						<< (shader[i].source[2] ? shader[i].source[2] : "") << "\n"
2141						<< tcu::TestLog::EndMessage;
2142
2143					delete[] log_text;
2144
2145					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");
2146
2147					throw 0;
2148				}
2149			}
2150		}
2151
2152		/* Link. */
2153		gl.linkProgram(m_po);
2154
2155		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
2156
2157		glw::GLint status = GL_FALSE;
2158
2159		gl.getProgramiv(m_po, GL_LINK_STATUS, &status);
2160
2161		if (GL_TRUE == status)
2162		{
2163			for (glw::GLuint i = 0; i < shader_count; ++i)
2164			{
2165				if (shader[i].id)
2166				{
2167					gl.detachShader(m_po, shader[i].id);
2168
2169					GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
2170				}
2171			}
2172		}
2173		else
2174		{
2175			glw::GLint log_size = 0;
2176
2177			gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);
2178
2179			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");
2180
2181			glw::GLchar* log_text = new glw::GLchar[log_size];
2182
2183			gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);
2184
2185			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
2186												<< log_text << "\n"
2187												<< tcu::TestLog::EndMessage;
2188
2189			delete[] log_text;
2190
2191			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");
2192
2193			throw 0;
2194		}
2195	}
2196	catch (...)
2197	{
2198		if (m_po)
2199		{
2200			gl.deleteProgram(m_po);
2201
2202			m_po = 0;
2203		}
2204	}
2205
2206	for (glw::GLuint i = 0; i < shader_count; ++i)
2207	{
2208		if (0 != shader[i].id)
2209		{
2210			gl.deleteShader(shader[i].id);
2211
2212			shader[i].id = 0;
2213		}
2214	}
2215
2216	if (0 == m_po)
2217	{
2218		throw 0;
2219	}
2220}
2221
2222/** @brief Prepare VAO.
2223 */
2224template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2225void StorageAndSubImageTest<T, S, N, D, I>::PrepareVertexArray()
2226{
2227	/* Shortcut for GL functionality. */
2228	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2229
2230	gl.genVertexArrays(1, &m_vao);
2231	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays has failed");
2232
2233	gl.bindVertexArray(m_vao);
2234	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray has failed");
2235}
2236
2237/** @brief Test's draw call.
2238 */
2239template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2240void StorageAndSubImageTest<T, S, N, D, I>::Draw()
2241{
2242	/* Shortcut for GL functionality. */
2243	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2244
2245	gl.useProgram(m_po);
2246	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram has failed");
2247
2248	gl.activeTexture(GL_TEXTURE0);
2249	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture has failed");
2250
2251	gl.bindTextureUnit(0, m_to);
2252	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture has failed");
2253
2254	gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
2255	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays has failed");
2256}
2257
2258/** @brief Clean GL objects, test variables and GL errors.
2259 */
2260template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2261void StorageAndSubImageTest<T, S, N, D, I>::CleanTexture()
2262{
2263	/* Shortcut for GL functionality. */
2264	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2265
2266	/* Texture. */
2267	if (m_to)
2268	{
2269		gl.deleteTextures(1, &m_to);
2270
2271		m_to = 0;
2272	}
2273}
2274
2275/** @brief Clean GL objects, test variables and GL errors.
2276 */
2277template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2278void StorageAndSubImageTest<T, S, N, D, I>::CleanFramebuffer()
2279{
2280	/* Shortcut for GL functionality. */
2281	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2282
2283	/* Framebuffer. */
2284	if (m_fbo)
2285	{
2286		gl.deleteFramebuffers(1, &m_fbo);
2287
2288		m_fbo = 0;
2289	}
2290
2291	/* Renderbuffer. */
2292	if (m_rbo)
2293	{
2294		gl.deleteRenderbuffers(1, &m_rbo);
2295
2296		m_rbo = 0;
2297	}
2298}
2299
2300/** @brief Clean GL objects, test variables and GL errors.
2301 */
2302template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2303void StorageAndSubImageTest<T, S, N, D, I>::CleanProgram()
2304{
2305	/* Shortcut for GL functionality. */
2306	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2307
2308	/* Program. */
2309	if (m_po)
2310	{
2311		gl.useProgram(0);
2312
2313		gl.deleteProgram(m_po);
2314
2315		m_po = 0;
2316	}
2317}
2318
2319/** @brief Clean GL objects, test variables and GL errors.
2320 */
2321template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2322void StorageAndSubImageTest<T, S, N, D, I>::CleanErrors()
2323{
2324	/* Shortcut for GL functionality. */
2325	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2326
2327	/* Query all errors until GL_NO_ERROR occure. */
2328	while (GL_NO_ERROR != gl.getError())
2329		;
2330}
2331
2332/** @brief Clean GL objects, test variables and GL errors.
2333 */
2334template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2335void StorageAndSubImageTest<T, S, N, D, I>::CleanVertexArray()
2336{
2337	/* Shortcut for GL functionality. */
2338	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2339
2340	if (m_vao)
2341	{
2342		gl.bindVertexArray(0);
2343
2344		gl.deleteVertexArrays(1, &m_vao);
2345
2346		m_vao = 0;
2347	}
2348}
2349
2350/** @brief Iterate Storage Test cases.
2351 *
2352 *  @return Iteration result.
2353 */
2354template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2355tcu::TestNode::IterateResult StorageAndSubImageTest<T, S, N, D, I>::iterate()
2356{
2357	/* Shortcut for GL functionality. */
2358	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2359
2360	/* Get context setup. */
2361	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
2362	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
2363
2364	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
2365	{
2366		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
2367
2368		return STOP;
2369	}
2370
2371	/* Running tests. */
2372	bool is_ok	= true;
2373	bool is_error = false;
2374
2375	try
2376	{
2377		PrepareVertexArray();
2378		PrepareProgram(FragmentShaderDeclaration(), FragmentShaderTail());
2379		is_ok = Test();
2380	}
2381	catch (tcu::NotSupportedError e)
2382	{
2383		throw e;
2384	}
2385	catch (...)
2386	{
2387		is_ok	= false;
2388		is_error = true;
2389	}
2390
2391	/* Cleanup. */
2392	CleanTexture();
2393	CleanFramebuffer();
2394	CleanProgram();
2395	CleanErrors();
2396	CleanVertexArray();
2397
2398	/* Errors clean up. */
2399	while (gl.getError())
2400		;
2401
2402	/* Result's setup. */
2403	if (is_ok)
2404	{
2405		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2406	}
2407	else
2408	{
2409		if (is_error)
2410		{
2411			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
2412		}
2413		else
2414		{
2415			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2416		}
2417	}
2418
2419	return STOP;
2420}
2421
2422/* Vertex shader source code. */
2423template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2424const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_vertex_shader =
2425	"#version 450\n"
2426	"\n"
2427	"void main()\n"
2428	"{\n"
2429	"    switch(gl_VertexID)\n"
2430	"    {\n"
2431	"        case 0:\n"
2432	"            gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
2433	"            break;\n"
2434	"        case 1:\n"
2435	"            gl_Position = vec4( 1.0, 1.0, 0.0, 1.0);\n"
2436	"            break;\n"
2437	"        case 2:\n"
2438	"            gl_Position = vec4(-1.0,-1.0, 0.0, 1.0);\n"
2439	"            break;\n"
2440	"        case 3:\n"
2441	"            gl_Position = vec4( 1.0,-1.0, 0.0, 1.0);\n"
2442	"            break;\n"
2443	"    }\n"
2444	"}\n";
2445
2446/* Fragment shader source program. */
2447template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2448const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_head =
2449	"#version 450\n"
2450	"\n"
2451	"layout(pixel_center_integer) in vec4 gl_FragCoord;\n"
2452	"\n";
2453
2454template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2455const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_1D_fdecl_lowp =
2456	"uniform  sampler1D texture_input;\nout     vec4          texture_output;\n";
2457template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2458const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_1D_idecl_lowp =
2459	"uniform isampler1D texture_input;\nout     ivec4         texture_output;\n";
2460template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2461const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_1D_udecl_lowp =
2462	"uniform usampler1D texture_input;\nout     uvec4         texture_output;\n";
2463template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2464const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_1D_fdecl_mediump =
2465	"uniform  sampler1D texture_input;\nout     vec4          texture_output;\n";
2466template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2467const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_1D_idecl_mediump =
2468	"uniform isampler1D texture_input;\nout     ivec4         texture_output;\n";
2469template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2470const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_1D_udecl_mediump =
2471	"uniform usampler1D texture_input;\nout     uvec4         texture_output;\n";
2472template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2473const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_1D_fdecl_highp =
2474	"uniform  sampler1D texture_input;\nout     vec4          texture_output;\n";
2475template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2476const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_1D_idecl_highp =
2477	"uniform isampler1D texture_input;\nout     ivec4         texture_output;\n";
2478template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2479const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_1D_udecl_highp =
2480	"uniform usampler1D texture_input;\nout     uvec4         texture_output;\n";
2481
2482template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2483const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_2D_fdecl_lowp =
2484	"uniform  sampler2D texture_input;\nout     vec4          texture_output;\n";
2485template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2486const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_2D_idecl_lowp =
2487	"uniform isampler2D texture_input;\nout     ivec4         texture_output;\n";
2488template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2489const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_2D_udecl_lowp =
2490	"uniform usampler2D texture_input;\nout     uvec4         texture_output;\n";
2491template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2492const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_2D_fdecl_mediump =
2493	"uniform  sampler2D texture_input;\nout     vec4          texture_output;\n";
2494template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2495const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_2D_idecl_mediump =
2496	"uniform isampler2D texture_input;\nout     ivec4         texture_output;\n";
2497template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2498const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_2D_udecl_mediump =
2499	"uniform usampler2D texture_input;\nout     uvec4         texture_output;\n";
2500template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2501const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_2D_fdecl_highp =
2502	"uniform  sampler2D texture_input;\nout     vec4          texture_output;\n";
2503template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2504const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_2D_idecl_highp =
2505	"uniform isampler2D texture_input;\nout     ivec4         texture_output;\n";
2506template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2507const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_2D_udecl_highp =
2508	"uniform usampler2D texture_input;\nout     uvec4         texture_output;\n";
2509
2510template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2511const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_3D_fdecl_lowp =
2512	"uniform  sampler3D texture_input;\nout     vec4          texture_output;\n";
2513template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2514const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_3D_idecl_lowp =
2515	"uniform isampler3D texture_input;\nout     ivec4         texture_output;\n";
2516template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2517const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_3D_udecl_lowp =
2518	"uniform usampler3D texture_input;\nout     uvec4         texture_output;\n";
2519template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2520const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_3D_fdecl_mediump =
2521	"uniform  sampler3D texture_input;\nout     vec4          texture_output;\n";
2522template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2523const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_3D_idecl_mediump =
2524	"uniform isampler3D texture_input;\nout     ivec4         texture_output;\n";
2525template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2526const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_3D_udecl_mediump =
2527	"uniform usampler3D texture_input;\nout     uvec4         texture_output;\n";
2528template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2529const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_3D_fdecl_highp =
2530	"uniform  sampler3D texture_input;\nout     vec4          texture_output;\n";
2531template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2532const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_3D_idecl_highp =
2533	"uniform isampler3D texture_input;\nout     ivec4         texture_output;\n";
2534template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2535const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_3D_udecl_highp =
2536	"uniform usampler3D texture_input;\nout     uvec4         texture_output;\n";
2537
2538template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2539const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_1D_tail =
2540	"\n"
2541	"void main()\n"
2542	"{\n"
2543	"    texture_output = texelFetch(texture_input, int(gl_FragCoord.x), 0);\n"
2544	"}\n";
2545
2546template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2547const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_2D_tail =
2548	"\n"
2549	"void main()\n"
2550	"{\n"
2551	"    texture_output = texelFetch(texture_input, ivec2(int(gl_FragCoord.x) % 2, int(floor(gl_FragCoord.x / 2))), "
2552	"0);\n"
2553	"}\n";
2554
2555template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
2556const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_3D_tail =
2557	"\n"
2558	"void main()\n"
2559	"{\n"
2560	"    texture_output = texelFetch(texture_input, ivec3(int(gl_FragCoord.x) % 2, int(floor(gl_FragCoord.x / 2)) % 3, "
2561	"int(floor(gl_FragCoord.x / 2 / 3))), 0);\n"
2562	"}\n";
2563
2564template class StorageAndSubImageTest<glw::GLbyte, 1, false, 1, false>;
2565template class StorageAndSubImageTest<glw::GLbyte, 2, false, 1, false>;
2566template class StorageAndSubImageTest<glw::GLbyte, 4, false, 1, false>;
2567template class StorageAndSubImageTest<glw::GLbyte, 1, false, 2, false>;
2568template class StorageAndSubImageTest<glw::GLbyte, 2, false, 2, false>;
2569template class StorageAndSubImageTest<glw::GLbyte, 4, false, 2, false>;
2570template class StorageAndSubImageTest<glw::GLbyte, 1, false, 3, false>;
2571template class StorageAndSubImageTest<glw::GLbyte, 2, false, 3, false>;
2572template class StorageAndSubImageTest<glw::GLbyte, 4, false, 3, false>;
2573
2574template class StorageAndSubImageTest<glw::GLubyte, 1, false, 1, false>;
2575template class StorageAndSubImageTest<glw::GLubyte, 2, false, 1, false>;
2576template class StorageAndSubImageTest<glw::GLubyte, 4, false, 1, false>;
2577template class StorageAndSubImageTest<glw::GLubyte, 1, false, 2, false>;
2578template class StorageAndSubImageTest<glw::GLubyte, 2, false, 2, false>;
2579template class StorageAndSubImageTest<glw::GLubyte, 4, false, 2, false>;
2580template class StorageAndSubImageTest<glw::GLubyte, 1, false, 3, false>;
2581template class StorageAndSubImageTest<glw::GLubyte, 2, false, 3, false>;
2582template class StorageAndSubImageTest<glw::GLubyte, 4, false, 3, false>;
2583
2584template class StorageAndSubImageTest<glw::GLubyte, 1, true, 1, false>;
2585template class StorageAndSubImageTest<glw::GLubyte, 2, true, 1, false>;
2586template class StorageAndSubImageTest<glw::GLubyte, 4, true, 1, false>;
2587template class StorageAndSubImageTest<glw::GLubyte, 1, true, 2, false>;
2588template class StorageAndSubImageTest<glw::GLubyte, 2, true, 2, false>;
2589template class StorageAndSubImageTest<glw::GLubyte, 4, true, 2, false>;
2590template class StorageAndSubImageTest<glw::GLubyte, 1, true, 3, false>;
2591template class StorageAndSubImageTest<glw::GLubyte, 2, true, 3, false>;
2592template class StorageAndSubImageTest<glw::GLubyte, 4, true, 3, false>;
2593
2594template class StorageAndSubImageTest<glw::GLshort, 1, false, 1, false>;
2595template class StorageAndSubImageTest<glw::GLshort, 2, false, 1, false>;
2596template class StorageAndSubImageTest<glw::GLshort, 4, false, 1, false>;
2597template class StorageAndSubImageTest<glw::GLshort, 1, false, 2, false>;
2598template class StorageAndSubImageTest<glw::GLshort, 2, false, 2, false>;
2599template class StorageAndSubImageTest<glw::GLshort, 4, false, 2, false>;
2600template class StorageAndSubImageTest<glw::GLshort, 1, false, 3, false>;
2601template class StorageAndSubImageTest<glw::GLshort, 2, false, 3, false>;
2602template class StorageAndSubImageTest<glw::GLshort, 4, false, 3, false>;
2603
2604template class StorageAndSubImageTest<glw::GLushort, 1, false, 1, false>;
2605template class StorageAndSubImageTest<glw::GLushort, 2, false, 1, false>;
2606template class StorageAndSubImageTest<glw::GLushort, 4, false, 1, false>;
2607template class StorageAndSubImageTest<glw::GLushort, 1, false, 2, false>;
2608template class StorageAndSubImageTest<glw::GLushort, 2, false, 2, false>;
2609template class StorageAndSubImageTest<glw::GLushort, 4, false, 2, false>;
2610template class StorageAndSubImageTest<glw::GLushort, 1, false, 3, false>;
2611template class StorageAndSubImageTest<glw::GLushort, 2, false, 3, false>;
2612template class StorageAndSubImageTest<glw::GLushort, 4, false, 3, false>;
2613
2614template class StorageAndSubImageTest<glw::GLushort, 1, true, 1, false>;
2615template class StorageAndSubImageTest<glw::GLushort, 2, true, 1, false>;
2616template class StorageAndSubImageTest<glw::GLushort, 4, true, 1, false>;
2617template class StorageAndSubImageTest<glw::GLushort, 1, true, 2, false>;
2618template class StorageAndSubImageTest<glw::GLushort, 2, true, 2, false>;
2619template class StorageAndSubImageTest<glw::GLushort, 4, true, 2, false>;
2620template class StorageAndSubImageTest<glw::GLushort, 1, true, 3, false>;
2621template class StorageAndSubImageTest<glw::GLushort, 2, true, 3, false>;
2622template class StorageAndSubImageTest<glw::GLushort, 4, true, 3, false>;
2623
2624template class StorageAndSubImageTest<glw::GLint, 1, false, 1, false>;
2625template class StorageAndSubImageTest<glw::GLint, 2, false, 1, false>;
2626template class StorageAndSubImageTest<glw::GLint, 3, false, 1, false>;
2627template class StorageAndSubImageTest<glw::GLint, 4, false, 1, false>;
2628template class StorageAndSubImageTest<glw::GLint, 1, false, 2, false>;
2629template class StorageAndSubImageTest<glw::GLint, 2, false, 2, false>;
2630template class StorageAndSubImageTest<glw::GLint, 3, false, 2, false>;
2631template class StorageAndSubImageTest<glw::GLint, 4, false, 2, false>;
2632template class StorageAndSubImageTest<glw::GLint, 1, false, 3, false>;
2633template class StorageAndSubImageTest<glw::GLint, 2, false, 3, false>;
2634template class StorageAndSubImageTest<glw::GLint, 3, false, 3, false>;
2635template class StorageAndSubImageTest<glw::GLint, 4, false, 3, false>;
2636
2637template class StorageAndSubImageTest<glw::GLuint, 1, false, 1, false>;
2638template class StorageAndSubImageTest<glw::GLuint, 2, false, 1, false>;
2639template class StorageAndSubImageTest<glw::GLuint, 3, false, 1, false>;
2640template class StorageAndSubImageTest<glw::GLuint, 4, false, 1, false>;
2641template class StorageAndSubImageTest<glw::GLuint, 1, false, 2, false>;
2642template class StorageAndSubImageTest<glw::GLuint, 2, false, 2, false>;
2643template class StorageAndSubImageTest<glw::GLuint, 3, false, 2, false>;
2644template class StorageAndSubImageTest<glw::GLuint, 4, false, 2, false>;
2645template class StorageAndSubImageTest<glw::GLuint, 1, false, 3, false>;
2646template class StorageAndSubImageTest<glw::GLuint, 2, false, 3, false>;
2647template class StorageAndSubImageTest<glw::GLuint, 3, false, 3, false>;
2648template class StorageAndSubImageTest<glw::GLuint, 4, false, 3, false>;
2649
2650template class StorageAndSubImageTest<glw::GLfloat, 1, true, 1, false>;
2651template class StorageAndSubImageTest<glw::GLfloat, 2, true, 1, false>;
2652template class StorageAndSubImageTest<glw::GLfloat, 3, true, 1, false>;
2653template class StorageAndSubImageTest<glw::GLfloat, 4, true, 1, false>;
2654template class StorageAndSubImageTest<glw::GLfloat, 1, true, 2, false>;
2655template class StorageAndSubImageTest<glw::GLfloat, 2, true, 2, false>;
2656template class StorageAndSubImageTest<glw::GLfloat, 3, true, 2, false>;
2657template class StorageAndSubImageTest<glw::GLfloat, 4, true, 2, false>;
2658template class StorageAndSubImageTest<glw::GLfloat, 1, true, 3, false>;
2659template class StorageAndSubImageTest<glw::GLfloat, 2, true, 3, false>;
2660template class StorageAndSubImageTest<glw::GLfloat, 3, true, 3, false>;
2661template class StorageAndSubImageTest<glw::GLfloat, 4, true, 3, false>;
2662
2663template class StorageAndSubImageTest<glw::GLbyte, 1, false, 1, true>;
2664template class StorageAndSubImageTest<glw::GLbyte, 2, false, 1, true>;
2665template class StorageAndSubImageTest<glw::GLbyte, 4, false, 1, true>;
2666template class StorageAndSubImageTest<glw::GLbyte, 1, false, 2, true>;
2667template class StorageAndSubImageTest<glw::GLbyte, 2, false, 2, true>;
2668template class StorageAndSubImageTest<glw::GLbyte, 4, false, 2, true>;
2669template class StorageAndSubImageTest<glw::GLbyte, 1, false, 3, true>;
2670template class StorageAndSubImageTest<glw::GLbyte, 2, false, 3, true>;
2671template class StorageAndSubImageTest<glw::GLbyte, 4, false, 3, true>;
2672
2673template class StorageAndSubImageTest<glw::GLubyte, 1, false, 1, true>;
2674template class StorageAndSubImageTest<glw::GLubyte, 2, false, 1, true>;
2675template class StorageAndSubImageTest<glw::GLubyte, 4, false, 1, true>;
2676template class StorageAndSubImageTest<glw::GLubyte, 1, false, 2, true>;
2677template class StorageAndSubImageTest<glw::GLubyte, 2, false, 2, true>;
2678template class StorageAndSubImageTest<glw::GLubyte, 4, false, 2, true>;
2679template class StorageAndSubImageTest<glw::GLubyte, 1, false, 3, true>;
2680template class StorageAndSubImageTest<glw::GLubyte, 2, false, 3, true>;
2681template class StorageAndSubImageTest<glw::GLubyte, 4, false, 3, true>;
2682
2683template class StorageAndSubImageTest<glw::GLubyte, 1, true, 1, true>;
2684template class StorageAndSubImageTest<glw::GLubyte, 2, true, 1, true>;
2685template class StorageAndSubImageTest<glw::GLubyte, 4, true, 1, true>;
2686template class StorageAndSubImageTest<glw::GLubyte, 1, true, 2, true>;
2687template class StorageAndSubImageTest<glw::GLubyte, 2, true, 2, true>;
2688template class StorageAndSubImageTest<glw::GLubyte, 4, true, 2, true>;
2689template class StorageAndSubImageTest<glw::GLubyte, 1, true, 3, true>;
2690template class StorageAndSubImageTest<glw::GLubyte, 2, true, 3, true>;
2691template class StorageAndSubImageTest<glw::GLubyte, 4, true, 3, true>;
2692
2693template class StorageAndSubImageTest<glw::GLshort, 1, false, 1, true>;
2694template class StorageAndSubImageTest<glw::GLshort, 2, false, 1, true>;
2695template class StorageAndSubImageTest<glw::GLshort, 4, false, 1, true>;
2696template class StorageAndSubImageTest<glw::GLshort, 1, false, 2, true>;
2697template class StorageAndSubImageTest<glw::GLshort, 2, false, 2, true>;
2698template class StorageAndSubImageTest<glw::GLshort, 4, false, 2, true>;
2699template class StorageAndSubImageTest<glw::GLshort, 1, false, 3, true>;
2700template class StorageAndSubImageTest<glw::GLshort, 2, false, 3, true>;
2701template class StorageAndSubImageTest<glw::GLshort, 4, false, 3, true>;
2702
2703template class StorageAndSubImageTest<glw::GLushort, 1, false, 1, true>;
2704template class StorageAndSubImageTest<glw::GLushort, 2, false, 1, true>;
2705template class StorageAndSubImageTest<glw::GLushort, 4, false, 1, true>;
2706template class StorageAndSubImageTest<glw::GLushort, 1, false, 2, true>;
2707template class StorageAndSubImageTest<glw::GLushort, 2, false, 2, true>;
2708template class StorageAndSubImageTest<glw::GLushort, 4, false, 2, true>;
2709template class StorageAndSubImageTest<glw::GLushort, 1, false, 3, true>;
2710template class StorageAndSubImageTest<glw::GLushort, 2, false, 3, true>;
2711template class StorageAndSubImageTest<glw::GLushort, 4, false, 3, true>;
2712
2713template class StorageAndSubImageTest<glw::GLushort, 1, true, 1, true>;
2714template class StorageAndSubImageTest<glw::GLushort, 2, true, 1, true>;
2715template class StorageAndSubImageTest<glw::GLushort, 4, true, 1, true>;
2716template class StorageAndSubImageTest<glw::GLushort, 1, true, 2, true>;
2717template class StorageAndSubImageTest<glw::GLushort, 2, true, 2, true>;
2718template class StorageAndSubImageTest<glw::GLushort, 4, true, 2, true>;
2719template class StorageAndSubImageTest<glw::GLushort, 1, true, 3, true>;
2720template class StorageAndSubImageTest<glw::GLushort, 2, true, 3, true>;
2721template class StorageAndSubImageTest<glw::GLushort, 4, true, 3, true>;
2722
2723template class StorageAndSubImageTest<glw::GLint, 1, false, 1, true>;
2724template class StorageAndSubImageTest<glw::GLint, 2, false, 1, true>;
2725template class StorageAndSubImageTest<glw::GLint, 3, false, 1, true>;
2726template class StorageAndSubImageTest<glw::GLint, 4, false, 1, true>;
2727template class StorageAndSubImageTest<glw::GLint, 1, false, 2, true>;
2728template class StorageAndSubImageTest<glw::GLint, 2, false, 2, true>;
2729template class StorageAndSubImageTest<glw::GLint, 3, false, 2, true>;
2730template class StorageAndSubImageTest<glw::GLint, 4, false, 2, true>;
2731template class StorageAndSubImageTest<glw::GLint, 1, false, 3, true>;
2732template class StorageAndSubImageTest<glw::GLint, 2, false, 3, true>;
2733template class StorageAndSubImageTest<glw::GLint, 3, false, 3, true>;
2734template class StorageAndSubImageTest<glw::GLint, 4, false, 3, true>;
2735
2736template class StorageAndSubImageTest<glw::GLuint, 1, false, 1, true>;
2737template class StorageAndSubImageTest<glw::GLuint, 2, false, 1, true>;
2738template class StorageAndSubImageTest<glw::GLuint, 3, false, 1, true>;
2739template class StorageAndSubImageTest<glw::GLuint, 4, false, 1, true>;
2740template class StorageAndSubImageTest<glw::GLuint, 1, false, 2, true>;
2741template class StorageAndSubImageTest<glw::GLuint, 2, false, 2, true>;
2742template class StorageAndSubImageTest<glw::GLuint, 3, false, 2, true>;
2743template class StorageAndSubImageTest<glw::GLuint, 4, false, 2, true>;
2744template class StorageAndSubImageTest<glw::GLuint, 1, false, 3, true>;
2745template class StorageAndSubImageTest<glw::GLuint, 2, false, 3, true>;
2746template class StorageAndSubImageTest<glw::GLuint, 3, false, 3, true>;
2747template class StorageAndSubImageTest<glw::GLuint, 4, false, 3, true>;
2748
2749template class StorageAndSubImageTest<glw::GLfloat, 1, true, 1, true>;
2750template class StorageAndSubImageTest<glw::GLfloat, 2, true, 1, true>;
2751template class StorageAndSubImageTest<glw::GLfloat, 3, true, 1, true>;
2752template class StorageAndSubImageTest<glw::GLfloat, 4, true, 1, true>;
2753template class StorageAndSubImageTest<glw::GLfloat, 1, true, 2, true>;
2754template class StorageAndSubImageTest<glw::GLfloat, 2, true, 2, true>;
2755template class StorageAndSubImageTest<glw::GLfloat, 3, true, 2, true>;
2756template class StorageAndSubImageTest<glw::GLfloat, 4, true, 2, true>;
2757template class StorageAndSubImageTest<glw::GLfloat, 1, true, 3, true>;
2758template class StorageAndSubImageTest<glw::GLfloat, 2, true, 3, true>;
2759template class StorageAndSubImageTest<glw::GLfloat, 3, true, 3, true>;
2760template class StorageAndSubImageTest<glw::GLfloat, 4, true, 3, true>;
2761
2762/******************************** Storage Multisample Test Implementation   ********************************/
2763
2764/** @brief Storage Multisample Test constructor.
2765 *
2766 *  @param [in] context     OpenGL context.
2767 */
2768template <typename T, glw::GLint S, bool N, glw::GLuint D>
2769StorageMultisampleTest<T, S, N, D>::StorageMultisampleTest(deqp::Context& context, const char* name)
2770	: deqp::TestCase(context, name, "Texture Storage Multisample Test")
2771	, m_fbo_ms(0)
2772	, m_fbo_aux(0)
2773	, m_to_ms(0)
2774	, m_po_ms(0)
2775	, m_po_aux(0)
2776	, m_to(0)
2777	, m_to_aux(0)
2778	, m_vao(0)
2779{
2780	/* Intentionally left blank. */
2781}
2782
2783/** @brief Count of reference data to be teted.
2784 *
2785 *  @return Count.
2786 */
2787template <typename T, glw::GLint S, bool N, glw::GLuint D>
2788glw::GLuint StorageMultisampleTest<T, S, N, D>::TestReferenceDataCount()
2789{
2790	return 2 /* 1D */ * ((D > 1) ? 3 : 1) /* 2D */ * ((D > 2) ? 4 : 1) /* 3D */ * S /* components */;
2791}
2792
2793/** @brief Size of reference data to be teted.
2794 *
2795 *  @return Size.
2796 */
2797template <typename T, glw::GLint S, bool N, glw::GLuint D>
2798glw::GLuint StorageMultisampleTest<T, S, N, D>::TestReferenceDataSize()
2799{
2800	return TestReferenceDataCount() * sizeof(T);
2801}
2802
2803/** @brief Height, width or depth of reference data to be teted.
2804 *
2805 *  @return Height, width or depth.
2806 */
2807template <typename T, glw::GLint S, bool N, glw::GLuint D>
2808glw::GLuint StorageMultisampleTest<T, S, N, D>::TestReferenceDataHeight()
2809{
2810	switch(D)
2811	{
2812	case 3:
2813	case 2:
2814		return 3;
2815	default:
2816		return 1;
2817	}
2818}
2819
2820template <typename T, glw::GLint S, bool N, glw::GLuint D>
2821glw::GLuint StorageMultisampleTest<T, S, N, D>::TestReferenceDataDepth()
2822{
2823	switch(D)
2824	{
2825	case 3:
2826		return 4;
2827	default:
2828		return 1;
2829	}
2830}
2831
2832template <typename T, glw::GLint S, bool N, glw::GLuint D>
2833glw::GLuint	StorageMultisampleTest<T, S, N, D>::TestReferenceDataWidth()
2834{
2835	return 2;
2836}
2837
2838/** @brief Fragment shader declaration selector.
2839 *
2840 *  @return Frgment shader source code part.
2841 */
2842template <typename T, glw::GLint S, bool N, glw::GLuint D>
2843const glw::GLchar* StorageMultisampleTest<T, S, N, D>::FragmentShaderDeclarationMultisample()
2844{
2845	if (typeid(T) == typeid(glw::GLbyte))
2846	{
2847		switch (D)
2848		{
2849		case 2:
2850			return s_fragment_shader_ms_2D_idecl_lowp;
2851		case 3:
2852			return s_fragment_shader_ms_3D_idecl_lowp;
2853		default:
2854			DE_ASSERT("invalid texture dimension");
2855			return DE_NULL;
2856		}
2857	}
2858
2859	if (typeid(T) == typeid(glw::GLubyte))
2860	{
2861		if (N)
2862		{
2863			switch (D)
2864			{
2865			case 2:
2866				return s_fragment_shader_ms_2D_fdecl_lowp;
2867			case 3:
2868				return s_fragment_shader_ms_3D_fdecl_lowp;
2869			default:
2870				DE_ASSERT("invalid texture dimension");
2871				return DE_NULL;
2872			}
2873		}
2874		else
2875		{
2876			switch (D)
2877			{
2878			case 2:
2879				return s_fragment_shader_ms_2D_udecl_lowp;
2880			case 3:
2881				return s_fragment_shader_ms_3D_udecl_lowp;
2882			default:
2883				DE_ASSERT("invalid texture dimension");
2884				return DE_NULL;
2885			}
2886		}
2887	}
2888
2889	if (typeid(T) == typeid(glw::GLshort))
2890	{
2891		switch (D)
2892		{
2893		case 2:
2894			return s_fragment_shader_ms_2D_idecl_mediump;
2895		case 3:
2896			return s_fragment_shader_ms_3D_idecl_mediump;
2897		default:
2898			DE_ASSERT("invalid texture dimension");
2899			return DE_NULL;
2900		}
2901	}
2902
2903	if (typeid(T) == typeid(glw::GLushort))
2904	{
2905		if (N)
2906		{
2907			switch (D)
2908			{
2909			case 2:
2910				return s_fragment_shader_ms_2D_fdecl_mediump;
2911			case 3:
2912				return s_fragment_shader_ms_3D_fdecl_mediump;
2913			default:
2914				DE_ASSERT("invalid texture dimension");
2915				return DE_NULL;
2916			}
2917		}
2918		else
2919		{
2920			switch (D)
2921			{
2922			case 2:
2923				return s_fragment_shader_ms_2D_udecl_mediump;
2924			case 3:
2925				return s_fragment_shader_ms_3D_udecl_mediump;
2926			default:
2927				DE_ASSERT("invalid texture dimension");
2928				return DE_NULL;
2929			}
2930		}
2931	}
2932
2933	if (typeid(T) == typeid(glw::GLint))
2934	{
2935		switch (D)
2936		{
2937		case 2:
2938			return s_fragment_shader_ms_2D_idecl_highp;
2939		case 3:
2940			return s_fragment_shader_ms_3D_idecl_highp;
2941		default:
2942			DE_ASSERT("invalid texture dimension");
2943			return DE_NULL;
2944		}
2945	}
2946
2947	if (typeid(T) == typeid(glw::GLuint))
2948	{
2949		switch (D)
2950		{
2951		case 2:
2952			return s_fragment_shader_ms_2D_udecl_highp;
2953		case 3:
2954			return s_fragment_shader_ms_3D_udecl_highp;
2955		default:
2956			DE_ASSERT("invalid texture dimension");
2957			return DE_NULL;
2958		}
2959	}
2960
2961	if (typeid(T) == typeid(glw::GLfloat))
2962	{
2963		switch (D)
2964		{
2965		case 2:
2966			return s_fragment_shader_ms_2D_fdecl_highp;
2967		case 3:
2968			return s_fragment_shader_ms_3D_fdecl_highp;
2969		default:
2970			DE_ASSERT("invalid texture dimension");
2971			return DE_NULL;
2972		}
2973	}
2974
2975	DE_ASSERT("invalid type");
2976	return DE_NULL;
2977}
2978
2979/** @brief Fragment shader declaration selector.
2980 *
2981 *  @return Frgment shader source code part.
2982 */
2983template <typename T, glw::GLint S, bool N, glw::GLuint D>
2984const glw::GLchar* StorageMultisampleTest<T, S, N, D>::FragmentShaderDeclarationAuxiliary()
2985{
2986	if (typeid(T) == typeid(glw::GLbyte))
2987	{
2988		switch (D)
2989		{
2990		case 2:
2991			return s_fragment_shader_aux_2D_idecl_lowp;
2992		case 3:
2993			return s_fragment_shader_aux_3D_idecl_lowp;
2994		default:
2995			DE_ASSERT("invalid texture dimension");
2996			return DE_NULL;
2997		}
2998	}
2999
3000	if (typeid(T) == typeid(glw::GLubyte))
3001	{
3002		if (N)
3003		{
3004			switch (D)
3005			{
3006			case 2:
3007				return s_fragment_shader_aux_2D_fdecl_lowp;
3008			case 3:
3009				return s_fragment_shader_aux_3D_fdecl_lowp;
3010			default:
3011				DE_ASSERT("invalid texture dimension");
3012				return DE_NULL;
3013			}
3014		}
3015		else
3016		{
3017			switch (D)
3018			{
3019			case 2:
3020				return s_fragment_shader_aux_2D_udecl_lowp;
3021			case 3:
3022				return s_fragment_shader_aux_3D_udecl_lowp;
3023			default:
3024				DE_ASSERT("invalid texture dimension");
3025				return DE_NULL;
3026			}
3027		}
3028	}
3029
3030	if (typeid(T) == typeid(glw::GLshort))
3031	{
3032		switch (D)
3033		{
3034		case 2:
3035			return s_fragment_shader_aux_2D_idecl_mediump;
3036		case 3:
3037			return s_fragment_shader_aux_3D_idecl_mediump;
3038		default:
3039			DE_ASSERT("invalid texture dimension");
3040			return DE_NULL;
3041		}
3042	}
3043
3044	if (typeid(T) == typeid(glw::GLushort))
3045	{
3046		if (N)
3047		{
3048			switch (D)
3049			{
3050			case 2:
3051				return s_fragment_shader_aux_2D_fdecl_mediump;
3052			case 3:
3053				return s_fragment_shader_aux_3D_fdecl_mediump;
3054			default:
3055				DE_ASSERT("invalid texture dimension");
3056				return DE_NULL;
3057			}
3058		}
3059		else
3060		{
3061			switch (D)
3062			{
3063			case 2:
3064				return s_fragment_shader_aux_2D_udecl_mediump;
3065			case 3:
3066				return s_fragment_shader_aux_3D_udecl_mediump;
3067			default:
3068				DE_ASSERT("invalid texture dimension");
3069				return DE_NULL;
3070			}
3071		}
3072	}
3073
3074	if (typeid(T) == typeid(glw::GLint))
3075	{
3076		switch (D)
3077		{
3078		case 2:
3079			return s_fragment_shader_aux_2D_idecl_highp;
3080		case 3:
3081			return s_fragment_shader_aux_3D_idecl_highp;
3082		default:
3083			DE_ASSERT("invalid texture dimension");
3084			return DE_NULL;
3085		}
3086	}
3087
3088	if (typeid(T) == typeid(glw::GLuint))
3089	{
3090		switch (D)
3091		{
3092		case 2:
3093			return s_fragment_shader_aux_2D_udecl_highp;
3094		case 3:
3095			return s_fragment_shader_aux_3D_udecl_highp;
3096		default:
3097			DE_ASSERT("invalid texture dimension");
3098			return DE_NULL;
3099		}
3100	}
3101
3102	if (typeid(T) == typeid(glw::GLfloat))
3103	{
3104		switch (D)
3105		{
3106		case 2:
3107			return s_fragment_shader_aux_2D_fdecl_highp;
3108		case 3:
3109			return s_fragment_shader_aux_3D_fdecl_highp;
3110		default:
3111			DE_ASSERT("invalid texture dimension");
3112			return DE_NULL;
3113		}
3114	}
3115
3116	DE_ASSERT("invalid type");
3117	return DE_NULL;
3118}
3119
3120/** @brief Fragment shader tail selector.
3121 *
3122 *  @return Frgment shader source code part.
3123 */
3124template <typename T, glw::GLint S, bool N, glw::GLuint D>
3125const glw::GLchar* StorageMultisampleTest<T, S, N, D>::FragmentShaderTail()
3126{
3127	switch (D)
3128	{
3129	case 2:
3130		return s_fragment_shader_tail_2D;
3131	case 3:
3132		return s_fragment_shader_tail_3D;
3133	default:
3134		DE_ASSERT("invalid texture dimension");
3135		return DE_NULL;
3136	}
3137}
3138
3139/** @brief Multisample texture target selector.
3140 *
3141 *  @return Texture target.
3142 */
3143template <typename T, glw::GLint S, bool N, glw::GLuint D>
3144glw::GLenum StorageMultisampleTest<T, S, N, D>::MultisampleTextureTarget()
3145{
3146	switch (D)
3147	{
3148	case 2:
3149		return GL_TEXTURE_2D_MULTISAMPLE;
3150	case 3:
3151		return GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
3152	default:
3153		DE_ASSERT("invalid texture dimension");
3154		return DE_NULL;
3155	}
3156}
3157
3158/** @brief Input texture target selector.
3159 *
3160 *  @return Texture target.
3161 */
3162template <typename T, glw::GLint S, bool N, glw::GLuint D>
3163glw::GLenum StorageMultisampleTest<T, S, N, D>::InputTextureTarget()
3164{
3165	switch (D)
3166	{
3167	case 2:
3168		return GL_TEXTURE_2D;
3169	case 3:
3170		return GL_TEXTURE_2D_ARRAY;
3171	default:
3172		DE_ASSERT("invalid texture dimension");
3173		return DE_NULL;
3174	}
3175}
3176
3177/** @brief Prepare texture data for input texture.
3178 *
3179 *  @note parameters as passed to texImage*
3180 */
3181template <typename T, glw::GLint S, bool N, glw::GLuint D>
3182void StorageMultisampleTest<T, S, N, D>::InputTextureImage(const glw::GLenum internal_format, const glw::GLuint width,
3183														   const glw::GLuint height, const glw::GLuint depth,
3184														   const glw::GLenum format, const glw::GLenum type,
3185														   const glw::GLvoid* data)
3186{
3187	(void)depth;
3188	/* Shortcut for GL functionality. */
3189	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3190
3191	/* Data setup. */
3192	switch (D)
3193	{
3194	case 2:
3195		gl.texImage2D(InputTextureTarget(), 0, internal_format, width, height, 0, format, type, data);
3196		break;
3197	case 3:
3198		gl.texImage3D(InputTextureTarget(), 0, internal_format, width, height, depth, 0, format, type, data);
3199		break;
3200	default:
3201		DE_ASSERT("invalid texture dimension");
3202	}
3203
3204	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage has failed");
3205}
3206
3207/** @brief Create texture.
3208 *
3209 */
3210template <typename T, glw::GLint S, bool N, glw::GLuint D>
3211void StorageMultisampleTest<T, S, N, D>::CreateInputTexture()
3212{
3213	/* Shortcut for GL functionality. */
3214	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3215
3216	/* Objects creation. */
3217	gl.genTextures(1, &m_to);
3218	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
3219
3220	gl.bindTexture(InputTextureTarget(), m_to);
3221	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
3222
3223	/* Data setup. */
3224	InputTextureImage(InternalFormat<T, S, N>(), TestReferenceDataWidth(), TestReferenceDataHeight(),
3225					  TestReferenceDataDepth(), Format<S, N>(), Type<T>(), ReferenceData<T, N>());
3226
3227	/* Parameter setup. */
3228	gl.texParameteri(InputTextureTarget(), GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3229	gl.texParameteri(InputTextureTarget(), GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3230	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri call failed.");
3231}
3232
3233/** @brief Compre results with the reference.
3234 *
3235 *  @return True if equal, false otherwise.
3236 */
3237template <typename T, glw::GLint S, bool N, glw::GLuint D>
3238bool StorageMultisampleTest<T, S, N, D>::Check()
3239{
3240	/* Shortcut for GL functionality. */
3241	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3242
3243	/* Fetching data fro auxiliary texture. */
3244	std::vector<T> result(TestReferenceDataCount());
3245
3246	gl.bindTexture(InputTextureTarget() /* Auxiliary target is the same as input. */, m_to_aux);
3247	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
3248
3249	gl.getTexImage(InputTextureTarget() /* Auxiliary target is the same as input. */, 0, Format<S, N>(), Type<T>(),
3250				   (glw::GLvoid*)(&result[0]));
3251	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexImage has failed");
3252
3253	/* Comparison. */
3254	for (glw::GLuint i = 0; i < TestReferenceDataCount(); ++i)
3255	{
3256		if (!Compare<T>(result[i], ReferenceData<T, N>()[i]))
3257		{
3258			return false;
3259		}
3260	}
3261
3262	return true;
3263}
3264
3265/** @brief Test case function.
3266 *
3267 *  @return True if test succeeded, false otherwise.
3268 */
3269template <typename T, glw::GLint S, bool N, glw::GLuint D>
3270bool StorageMultisampleTest<T, S, N, D>::Test()
3271{
3272	/* Shortcut for GL functionality. */
3273	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3274
3275	/* Setup. */
3276	gl.pixelStorei(GL_UNPACK_ALIGNMENT, sizeof(T));
3277	GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed");
3278
3279	gl.pixelStorei(GL_PACK_ALIGNMENT, sizeof(T));
3280	GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed");
3281
3282	CreateInputTexture();
3283
3284	if (!PrepareFramebufferMultisample(InternalFormat<T, S, N>()))
3285	{
3286		CleanInputTexture();
3287
3288		return false;
3289	}
3290
3291	PrepareFramebufferAuxiliary(InternalFormat<T, S, N>());
3292
3293	/* Action. */
3294	Draw();
3295
3296	/* Compare results with reference. */
3297	bool result = Check();
3298
3299	/* Cleanup. */
3300	CleanAuxiliaryTexture();
3301	CleanFramebuffers();
3302	CleanInputTexture();
3303	CleanErrors();
3304
3305	/* Pass result. */
3306	return result;
3307}
3308
3309/** @brief Function prepares framebuffer with internal format color attachment.
3310 *         Viewport is set up. Content of the framebuffer is cleared.
3311 *
3312 *  @note The function may throw if unexpected error has occured.
3313 */
3314template <typename T, glw::GLint S, bool N, glw::GLuint D>
3315bool StorageMultisampleTest<T, S, N, D>::PrepareFramebufferMultisample(const glw::GLenum internal_format)
3316{
3317	/* Shortcut for GL functionality. */
3318	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3319
3320	/* Prepare framebuffer. */
3321	gl.genFramebuffers(1, &m_fbo_ms);
3322	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
3323
3324	gl.genTextures(1, &m_to_ms);
3325	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
3326
3327	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_ms);
3328	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
3329
3330	gl.bindTexture(MultisampleTextureTarget(), m_to_ms);
3331	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
3332
3333	switch (D)
3334	{
3335	case 2:
3336		gl.textureStorage2DMultisample(m_to_ms, 1, internal_format, TestReferenceDataWidth(),
3337									   TestReferenceDataHeight(), false);
3338		break;
3339	case 3:
3340		gl.textureStorage3DMultisample(m_to_ms, 1, internal_format, TestReferenceDataWidth(),
3341									   TestReferenceDataHeight(), TestReferenceDataDepth(), false);
3342		break;
3343	default:
3344		DE_ASSERT("invalid texture dimension");
3345		return false;
3346	}
3347
3348	glw::GLenum error;
3349
3350	if (GL_NO_ERROR != (error = gl.getError()))
3351	{
3352		CleanFramebuffers();
3353
3354		m_context.getTestContext().getLog()
3355			<< tcu::TestLog::Message << "glTextureStorageMultisample unexpectedly generated error "
3356			<< glu::getErrorStr(error) << " during the test of internal format "
3357			<< glu::getTextureFormatStr(internal_format) << ". Test fails." << tcu::TestLog::EndMessage;
3358
3359		return false;
3360	}
3361
3362	switch (D)
3363	{
3364	case 2:
3365		gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, m_to_ms, 0);
3366		break;
3367	case 3:
3368		for (glw::GLuint i = 0; i < TestReferenceDataDepth(); ++i)
3369		{
3370			gl.framebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, m_to_ms, 0, i);
3371			GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTextureLayer call failed.");
3372		}
3373		break;
3374	default:
3375		DE_ASSERT("invalid texture dimension");
3376		return false;
3377	}
3378	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed.");
3379
3380	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
3381	{
3382		if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_UNSUPPORTED)
3383			throw tcu::NotSupportedError("unsupported framebuffer configuration");
3384		else
3385			throw 0;
3386	}
3387
3388	gl.viewport(0, 0, TestReferenceDataWidth(), TestReferenceDataHeight());
3389	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
3390
3391	/* Clear framebuffer's content. */
3392	gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f);
3393	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");
3394
3395	gl.clear(GL_COLOR_BUFFER_BIT);
3396	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed.");
3397
3398	return true;
3399}
3400
3401/** @brief Function prepares framebuffer with internal format color attachment.
3402 *         Viewport is set up. Content of the framebuffer is cleared.
3403 *
3404 *  @note The function may throw if unexpected error has occured.
3405 */
3406template <typename T, glw::GLint S, bool N, glw::GLuint D>
3407void StorageMultisampleTest<T, S, N, D>::PrepareFramebufferAuxiliary(const glw::GLenum internal_format)
3408{
3409	/* Shortcut for GL functionality. */
3410	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3411
3412	/* Prepare framebuffer. */
3413	gl.genFramebuffers(1, &m_fbo_aux);
3414	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
3415
3416	gl.genTextures(1, &m_to_aux);
3417	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
3418
3419	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_aux);
3420	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
3421
3422	gl.bindTexture(InputTextureTarget(), m_to_aux);
3423	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
3424
3425	switch (D)
3426	{
3427	case 2:
3428		gl.textureStorage2D(m_to_aux, 1, internal_format, TestReferenceDataWidth(), TestReferenceDataHeight());
3429		break;
3430	case 3:
3431		gl.textureStorage3D(m_to_aux, 1, internal_format, TestReferenceDataWidth(), TestReferenceDataHeight(),
3432							TestReferenceDataDepth());
3433		break;
3434	default:
3435		DE_ASSERT("invalid texture dimension");
3436	}
3437	GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2D call failed.");
3438
3439	/* Parameter setup. */
3440	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3441	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3442	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri call failed.");
3443
3444	switch (D)
3445	{
3446	case 2:
3447		gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_to_aux, 0);
3448		break;
3449	case 3:
3450		for (glw::GLuint i = 0; i < TestReferenceDataDepth(); ++i)
3451		{
3452			gl.framebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, m_to_aux, 0, i);
3453			GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTextureLayer call failed.");
3454		}
3455		break;
3456	default:
3457		DE_ASSERT("invalid texture dimension");
3458	}
3459	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed.");
3460
3461	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
3462	{
3463		if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_UNSUPPORTED)
3464			throw tcu::NotSupportedError("unsupported framebuffer configuration");
3465		else
3466			throw 0;
3467	}
3468
3469	gl.viewport(0, 0, TestReferenceDataWidth(), TestReferenceDataHeight());
3470	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
3471
3472	/* Clear framebuffer's content. */
3473	gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f);
3474	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");
3475
3476	gl.clear(GL_COLOR_BUFFER_BIT);
3477	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed.");
3478}
3479
3480/** @brief Prepare program
3481 *
3482 *  @param [in] variable_declaration      Variables declaration part of fragment shader source code.
3483 *  @param [in] tail                      Tail part of fragment shader source code.
3484 */
3485template <typename T, glw::GLint S, bool N, glw::GLuint D>
3486glw::GLuint StorageMultisampleTest<T, S, N, D>::PrepareProgram(const glw::GLchar* variable_declaration, const glw::GLchar* tail)
3487{
3488	/* Shortcut for GL functionality */
3489	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3490
3491	struct Shader
3492	{
3493		glw::GLchar const* source[3];
3494		glw::GLsizei const count;
3495		glw::GLenum const  type;
3496		glw::GLuint		   id;
3497	} shader[] = { { { s_vertex_shader, NULL, NULL }, 1, GL_VERTEX_SHADER, 0 },
3498				   { { s_fragment_shader_head, variable_declaration, tail }, 3, GL_FRAGMENT_SHADER, 0 } };
3499
3500	glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);
3501
3502	glw::GLuint po = 0;
3503
3504	try
3505	{
3506		/* Create program. */
3507		po = gl.createProgram();
3508		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");
3509
3510		/* Shader compilation. */
3511
3512		for (glw::GLuint i = 0; i < shader_count; ++i)
3513		{
3514			{
3515				shader[i].id = gl.createShader(shader[i].type);
3516
3517				GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");
3518
3519				gl.attachShader(po, shader[i].id);
3520
3521				GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");
3522
3523				gl.shaderSource(shader[i].id, shader[i].count, shader[i].source, NULL);
3524
3525				GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");
3526
3527				gl.compileShader(shader[i].id);
3528
3529				GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");
3530
3531				glw::GLint status = GL_FALSE;
3532
3533				gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
3534				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
3535
3536				if (GL_FALSE == status)
3537				{
3538					glw::GLint log_size = 0;
3539					gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
3540					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
3541
3542					glw::GLchar* log_text = new glw::GLchar[log_size];
3543
3544					gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);
3545
3546					m_context.getTestContext().getLog()
3547						<< tcu::TestLog::Message << "Shader compilation has failed.\n"
3548						<< "Shader type: " << glu::getShaderTypeStr(shader[i].type) << "\n"
3549						<< "Shader compilation error log:\n"
3550						<< log_text << "\n"
3551						<< "Shader source code:\n"
3552						<< shader[i].source[0] << (shader[i].source[1] ? shader[i].source[1] : "")
3553						<< (shader[i].source[2] ? shader[i].source[2] : "") << "\n"
3554						<< tcu::TestLog::EndMessage;
3555
3556					delete[] log_text;
3557
3558					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");
3559
3560					throw 0;
3561				}
3562			}
3563		}
3564
3565		/* Link. */
3566		gl.linkProgram(po);
3567
3568		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
3569
3570		glw::GLint status = GL_FALSE;
3571
3572		gl.getProgramiv(po, GL_LINK_STATUS, &status);
3573
3574		if (GL_TRUE == status)
3575		{
3576			for (glw::GLuint i = 0; i < shader_count; ++i)
3577			{
3578				if (shader[i].id)
3579				{
3580					gl.detachShader(po, shader[i].id);
3581
3582					GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
3583				}
3584			}
3585		}
3586		else
3587		{
3588			glw::GLint log_size = 0;
3589
3590			gl.getProgramiv(po, GL_INFO_LOG_LENGTH, &log_size);
3591
3592			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");
3593
3594			glw::GLchar* log_text = new glw::GLchar[log_size];
3595
3596			gl.getProgramInfoLog(po, log_size, NULL, &log_text[0]);
3597
3598			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
3599												<< log_text << "\n"
3600												<< tcu::TestLog::EndMessage;
3601
3602			delete[] log_text;
3603
3604			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");
3605
3606			throw 0;
3607		}
3608	}
3609	catch (...)
3610	{
3611		if (po)
3612		{
3613			gl.deleteProgram(po);
3614
3615			po = 0;
3616		}
3617	}
3618
3619	for (glw::GLuint i = 0; i < shader_count; ++i)
3620	{
3621		if (0 != shader[i].id)
3622		{
3623			gl.deleteShader(shader[i].id);
3624
3625			shader[i].id = 0;
3626		}
3627	}
3628
3629	if (0 == po)
3630	{
3631		throw 0;
3632	}
3633
3634	return po;
3635}
3636
3637/** @brief Prepare VAO.
3638 */
3639template <typename T, glw::GLint S, bool N, glw::GLuint D>
3640void StorageMultisampleTest<T, S, N, D>::PrepareVertexArray()
3641{
3642	/* Shortcut for GL functionality. */
3643	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3644
3645	gl.genVertexArrays(1, &m_vao);
3646	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays has failed");
3647
3648	gl.bindVertexArray(m_vao);
3649	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray has failed");
3650}
3651
3652/** @brief Draw call
3653 */
3654template <typename T, glw::GLint S, bool N, glw::GLuint D>
3655void StorageMultisampleTest<T, S, N, D>::Draw()
3656{
3657	/* Shortcut for GL functionality. */
3658	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3659
3660	/* Prepare multisample texture using draw call. */
3661
3662	/* Prepare framebuffer with multisample texture. */
3663	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_ms);
3664	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
3665
3666	/* Use first program program. */
3667	gl.useProgram(m_po_ms);
3668	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram has failed");
3669
3670	/* Prepare texture to be drawn with. */
3671	gl.activeTexture(GL_TEXTURE0);
3672	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture has failed");
3673
3674	gl.bindTexture(InputTextureTarget(), m_to);
3675	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture has failed");
3676
3677	gl.uniform1i(gl.getUniformLocation(m_po_ms, "texture_input"), 0);
3678	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i or glGetUniformLocation has failed");
3679
3680	for (glw::GLuint i = 0; i < TestReferenceDataDepth(); ++i)
3681	{
3682		/* Select layer. */
3683		gl.drawBuffer(GL_COLOR_ATTACHMENT0 + i);
3684		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawBuffer has failed");
3685
3686		if (D == 3)
3687		{
3688			gl.uniform1i(gl.getUniformLocation(m_po_aux, "texture_layer"), i);
3689			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i or glGetUniformLocation has failed");
3690		}
3691
3692		/* Draw. */
3693		gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
3694		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays has failed");
3695	}
3696
3697	/* Copy multisample texture to auxiliary texture using draw call. */
3698
3699	/* Prepare framebuffer with auxiliary texture. */
3700	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_aux);
3701	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
3702
3703	/* Use first program program. */
3704	gl.useProgram(m_po_aux);
3705	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram has failed");
3706
3707	/* Prepare texture to be drawn with. */
3708	gl.activeTexture(GL_TEXTURE0);
3709	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture has failed");
3710
3711	gl.bindTexture(MultisampleTextureTarget(), m_to_ms);
3712	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture has failed");
3713
3714	gl.bindTextureUnit(0, m_to);
3715
3716	gl.uniform1i(gl.getUniformLocation(m_po_aux, "texture_input"), 0);
3717	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i or glGetUniformLocation has failed");
3718
3719	/* For each texture layer. */
3720	for (glw::GLuint i = 0; i < TestReferenceDataDepth(); ++i)
3721	{
3722		/* Select layer. */
3723		gl.drawBuffer(GL_COLOR_ATTACHMENT0 + i);
3724		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawBuffer has failed");
3725
3726		if (D == 3)
3727		{
3728			gl.uniform1i(gl.getUniformLocation(m_po_aux, "texture_layer"), i);
3729			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i or glGetUniformLocation has failed");
3730		}
3731
3732		/* Draw. */
3733		gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
3734		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays has failed");
3735	}
3736}
3737
3738/** @brief Clean GL objects, test variables and GL errors.
3739 */
3740template <typename T, glw::GLint S, bool N, glw::GLuint D>
3741void StorageMultisampleTest<T, S, N, D>::CleanInputTexture()
3742{
3743	/* Shortcut for GL functionality. */
3744	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3745
3746	/* Texture. */
3747	if (m_to)
3748	{
3749		gl.deleteTextures(1, &m_to);
3750
3751		m_to = 0;
3752	}
3753}
3754
3755/** @brief Clean GL objects, test variables and GL errors.
3756 */
3757template <typename T, glw::GLint S, bool N, glw::GLuint D>
3758void StorageMultisampleTest<T, S, N, D>::CleanAuxiliaryTexture()
3759{
3760	/* Shortcut for GL functionality. */
3761	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3762
3763	if (m_to_aux)
3764	{
3765		gl.deleteTextures(1, &m_to_aux);
3766
3767		m_to_aux = 0;
3768	}
3769}
3770
3771/** @brief Clean GL objects, test variables and GL errors.
3772 */
3773template <typename T, glw::GLint S, bool N, glw::GLuint D>
3774void StorageMultisampleTest<T, S, N, D>::CleanFramebuffers()
3775{
3776	/* Shortcut for GL functionality. */
3777	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3778
3779	/* Mulitsample framebuffer. */
3780	if (m_fbo_ms)
3781	{
3782		gl.deleteFramebuffers(1, &m_fbo_ms);
3783
3784		m_fbo_ms = 0;
3785	}
3786
3787	/* Mulitsample texture. */
3788	if (m_to_ms)
3789	{
3790		gl.deleteTextures(1, &m_to_ms);
3791
3792		m_to_ms = 0;
3793	}
3794
3795	/* Auxiliary framebuffer. */
3796	if (m_fbo_aux)
3797	{
3798		gl.deleteFramebuffers(1, &m_fbo_aux);
3799
3800		m_fbo_aux = 0;
3801	}
3802
3803	/* Auxiliary texture. */
3804	if (m_to_aux)
3805	{
3806		gl.deleteTextures(1, &m_to_aux);
3807
3808		m_to_aux = 0;
3809	}
3810}
3811
3812/** @brief Clean GL objects, test variables and GL errors.
3813 */
3814template <typename T, glw::GLint S, bool N, glw::GLuint D>
3815void StorageMultisampleTest<T, S, N, D>::CleanPrograms()
3816{
3817	/* Shortcut for GL functionality. */
3818	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3819
3820	/* Binding point. */
3821	gl.useProgram(0);
3822
3823	/* Multisample texture preparation program. */
3824	if (m_po_ms)
3825	{
3826		gl.deleteProgram(m_po_ms);
3827
3828		m_po_ms = 0;
3829	}
3830
3831	/* Auxiliary texture preparation program. */
3832	if (m_po_aux)
3833	{
3834		gl.deleteProgram(m_po_aux);
3835
3836		m_po_aux = 0;
3837	}
3838}
3839
3840/** @brief Clean GL objects, test variables and GL errors.
3841 */
3842template <typename T, glw::GLint S, bool N, glw::GLuint D>
3843void StorageMultisampleTest<T, S, N, D>::CleanErrors()
3844{
3845	/* Shortcut for GL functionality. */
3846	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3847
3848	/* Query all errors until GL_NO_ERROR occure. */
3849	while (GL_NO_ERROR != gl.getError())
3850		;
3851}
3852
3853/** @brief Clean GL objects, test variables and GL errors.
3854 */
3855template <typename T, glw::GLint S, bool N, glw::GLuint D>
3856void StorageMultisampleTest<T, S, N, D>::CleanVertexArray()
3857{
3858	/* Shortcut for GL functionality. */
3859	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3860
3861	if (m_vao)
3862	{
3863		gl.bindVertexArray(0);
3864
3865		gl.deleteVertexArrays(1, &m_vao);
3866
3867		m_vao = 0;
3868	}
3869}
3870
3871/** @brief Iterate Storage Multisample Test cases.
3872 *
3873 *  @return Iteration result.
3874 */
3875template <typename T, glw::GLint S, bool N, glw::GLuint D>
3876tcu::TestNode::IterateResult StorageMultisampleTest<T, S, N, D>::iterate()
3877{
3878	/* Shortcut for GL functionality. */
3879	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3880
3881	/* Get context setup. */
3882	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
3883	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
3884
3885	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
3886	{
3887		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
3888
3889		return STOP;
3890	}
3891
3892	/* Running tests. */
3893	bool is_ok	= true;
3894	bool is_error = false;
3895
3896	try
3897	{
3898		PrepareVertexArray();
3899
3900		//  gl.enable(GL_MULTISAMPLE);
3901
3902		m_po_ms  = PrepareProgram(FragmentShaderDeclarationMultisample(), FragmentShaderTail());
3903		m_po_aux = PrepareProgram(FragmentShaderDeclarationAuxiliary(), FragmentShaderTail());
3904
3905		is_ok = Test();
3906	}
3907	catch (tcu::NotSupportedError e)
3908	{
3909		throw e;
3910	}
3911	catch (...)
3912	{
3913		is_ok	= false;
3914		is_error = true;
3915	}
3916
3917	/* Cleanup. */
3918	CleanInputTexture();
3919	CleanAuxiliaryTexture();
3920	CleanFramebuffers();
3921	CleanPrograms();
3922	CleanErrors();
3923	CleanVertexArray();
3924	gl.disable(GL_MULTISAMPLE);
3925
3926	/* Errors clean up. */
3927	while (gl.getError())
3928		;
3929
3930	/* Result's setup. */
3931	if (is_ok)
3932	{
3933		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3934	}
3935	else
3936	{
3937		if (is_error)
3938		{
3939			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
3940		}
3941		else
3942		{
3943			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
3944		}
3945	}
3946
3947	return STOP;
3948}
3949
3950/* Vertex shader source code. */
3951template <typename T, glw::GLint S, bool N, glw::GLuint D>
3952const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_vertex_shader =
3953	"#version 450\n"
3954	"\n"
3955	"void main()\n"
3956	"{\n"
3957	"    switch(gl_VertexID)\n"
3958	"    {\n"
3959	"        case 0:\n"
3960	"            gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
3961	"            break;\n"
3962	"        case 1:\n"
3963	"            gl_Position = vec4( 1.0, 1.0, 0.0, 1.0);\n"
3964	"            break;\n"
3965	"        case 2:\n"
3966	"            gl_Position = vec4(-1.0,-1.0, 0.0, 1.0);\n"
3967	"            break;\n"
3968	"        case 3:\n"
3969	"            gl_Position = vec4( 1.0,-1.0, 0.0, 1.0);\n"
3970	"            break;\n"
3971	"    }\n"
3972	"}\n";
3973
3974/* Fragment shader source program. */
3975template <typename T, glw::GLint S, bool N, glw::GLuint D>
3976const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_head =
3977	"#version 450\n"
3978	"\n"
3979	"layout(pixel_center_integer) in vec4 gl_FragCoord;\n"
3980	"\n";
3981
3982template <typename T, glw::GLint S, bool N, glw::GLuint D>
3983const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_2D_fdecl_lowp =
3984	"uniform  sampler2D texture_input;\nout     vec4          texture_output;\n";
3985template <typename T, glw::GLint S, bool N, glw::GLuint D>
3986const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_2D_idecl_lowp =
3987	"uniform isampler2D texture_input;\nout     ivec4         texture_output;\n";
3988template <typename T, glw::GLint S, bool N, glw::GLuint D>
3989const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_2D_udecl_lowp =
3990	"uniform usampler2D texture_input;\nout     uvec4         texture_output;\n";
3991template <typename T, glw::GLint S, bool N, glw::GLuint D>
3992const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_2D_fdecl_mediump =
3993	"uniform  sampler2D texture_input;\nout     vec4          texture_output;\n";
3994template <typename T, glw::GLint S, bool N, glw::GLuint D>
3995const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_2D_idecl_mediump =
3996	"uniform isampler2D texture_input;\nout     ivec4         texture_output;\n";
3997template <typename T, glw::GLint S, bool N, glw::GLuint D>
3998const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_2D_udecl_mediump =
3999	"uniform usampler2D texture_input;\nout     uvec4         texture_output;\n";
4000template <typename T, glw::GLint S, bool N, glw::GLuint D>
4001const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_2D_fdecl_highp =
4002	"uniform  sampler2D texture_input;\nout     vec4          texture_output;\n";
4003template <typename T, glw::GLint S, bool N, glw::GLuint D>
4004const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_2D_idecl_highp =
4005	"uniform isampler2D texture_input;\nout     ivec4         texture_output;\n";
4006template <typename T, glw::GLint S, bool N, glw::GLuint D>
4007const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_2D_udecl_highp =
4008	"uniform usampler2D texture_input;\nout     uvec4         texture_output;\n";
4009
4010template <typename T, glw::GLint S, bool N, glw::GLuint D>
4011const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_3D_fdecl_lowp =
4012	"uniform  sampler2DArray texture_input;\nout     vec4          texture_output;\n";
4013
4014template <typename T, glw::GLint S, bool N, glw::GLuint D>
4015const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_3D_idecl_lowp =
4016	"uniform isampler2DArray texture_input;\nout     ivec4         texture_output;\n";
4017
4018template <typename T, glw::GLint S, bool N, glw::GLuint D>
4019const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_3D_udecl_lowp =
4020	"uniform usampler2DArray texture_input;\nout     uvec4         texture_output;\n";
4021
4022template <typename T, glw::GLint S, bool N, glw::GLuint D>
4023const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_3D_fdecl_mediump =
4024	"uniform  sampler2DArray texture_input;\nout     vec4          texture_output;\n";
4025
4026template <typename T, glw::GLint S, bool N, glw::GLuint D>
4027const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_3D_idecl_mediump =
4028	"uniform isampler2DArray texture_input;\nout     ivec4         texture_output;\n";
4029
4030template <typename T, glw::GLint S, bool N, glw::GLuint D>
4031const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_3D_udecl_mediump =
4032	"uniform usampler2DArray texture_input;\nout     uvec4         texture_output;\n";
4033
4034template <typename T, glw::GLint S, bool N, glw::GLuint D>
4035const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_3D_fdecl_highp =
4036	"uniform  sampler2DArray texture_input;\nout     vec4          texture_output;\n";
4037
4038template <typename T, glw::GLint S, bool N, glw::GLuint D>
4039const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_3D_idecl_highp =
4040	"uniform isampler2DArray texture_input;\nout     ivec4         texture_output;\n";
4041
4042template <typename T, glw::GLint S, bool N, glw::GLuint D>
4043const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_3D_udecl_highp =
4044	"uniform usampler2DArray texture_input;\nout     uvec4         texture_output;\n";
4045
4046template <typename T, glw::GLint S, bool N, glw::GLuint D>
4047const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_2D_fdecl_lowp =
4048	"uniform  sampler2DMS texture_input;\nout     vec4          texture_output;\n";
4049template <typename T, glw::GLint S, bool N, glw::GLuint D>
4050const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_2D_idecl_lowp =
4051	"uniform isampler2DMS texture_input;\nout     ivec4         texture_output;\n";
4052template <typename T, glw::GLint S, bool N, glw::GLuint D>
4053const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_2D_udecl_lowp =
4054	"uniform usampler2DMS texture_input;\nout     uvec4         texture_output;\n";
4055
4056template <typename T, glw::GLint S, bool N, glw::GLuint D>
4057const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_2D_fdecl_mediump =
4058	"uniform  sampler2DMS texture_input;\nout     vec4          texture_output;\n";
4059
4060template <typename T, glw::GLint S, bool N, glw::GLuint D>
4061const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_2D_idecl_mediump =
4062	"uniform isampler2DMS texture_input;\nout     ivec4         texture_output;\n";
4063
4064template <typename T, glw::GLint S, bool N, glw::GLuint D>
4065const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_2D_udecl_mediump =
4066	"uniform usampler2DMS texture_input;\nout     uvec4         texture_output;\n";
4067
4068template <typename T, glw::GLint S, bool N, glw::GLuint D>
4069const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_2D_fdecl_highp =
4070	"uniform  sampler2DMS texture_input;\nout     vec4          texture_output;\n";
4071template <typename T, glw::GLint S, bool N, glw::GLuint D>
4072const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_2D_idecl_highp =
4073	"uniform isampler2DMS texture_input;\nout     ivec4         texture_output;\n";
4074template <typename T, glw::GLint S, bool N, glw::GLuint D>
4075const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_2D_udecl_highp =
4076	"uniform usampler2DMS texture_input;\nout     uvec4         texture_output;\n";
4077
4078template <typename T, glw::GLint S, bool N, glw::GLuint D>
4079const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_3D_fdecl_lowp =
4080	"uniform  sampler2DMSArray texture_input;\nout     vec4          texture_output;\n";
4081
4082template <typename T, glw::GLint S, bool N, glw::GLuint D>
4083const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_3D_idecl_lowp =
4084	"uniform isampler2DMSArray texture_input;\nout     ivec4         texture_output;\n";
4085
4086template <typename T, glw::GLint S, bool N, glw::GLuint D>
4087const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_3D_udecl_lowp =
4088	"uniform usampler2DMSArray texture_input;\nout     uvec4         texture_output;\n";
4089
4090template <typename T, glw::GLint S, bool N, glw::GLuint D>
4091const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_3D_fdecl_mediump =
4092	"uniform  sampler2DMSArray texture_input;\nout     vec4          texture_output;\n";
4093
4094template <typename T, glw::GLint S, bool N, glw::GLuint D>
4095const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_3D_idecl_mediump =
4096	"uniform isampler2DMSArray texture_input;\nout     ivec4         texture_output;\n";
4097
4098template <typename T, glw::GLint S, bool N, glw::GLuint D>
4099const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_3D_udecl_mediump =
4100	"uniform usampler2DMSArray texture_input;\nout     uvec4         texture_output;\n";
4101
4102template <typename T, glw::GLint S, bool N, glw::GLuint D>
4103const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_3D_fdecl_highp =
4104	"uniform  sampler2DMSArray texture_input;\nout     vec4          texture_output;\n";
4105
4106template <typename T, glw::GLint S, bool N, glw::GLuint D>
4107const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_3D_idecl_highp =
4108	"uniform isampler2DMSArray texture_input;\nout     ivec4         texture_output;\n";
4109
4110template <typename T, glw::GLint S, bool N, glw::GLuint D>
4111const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_3D_udecl_highp =
4112	"uniform usampler2DMSArray texture_input;\nout     uvec4         texture_output;\n";
4113
4114template <typename T, glw::GLint S, bool N, glw::GLuint D>
4115const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_tail_2D =
4116	"\n"
4117	"void main()\n"
4118	"{\n"
4119	"    texture_output = texelFetch(texture_input, ivec2(gl_FragCoord.xy), 0);\n"
4120	"}\n";
4121
4122template <typename T, glw::GLint S, bool N, glw::GLuint D>
4123const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_tail_3D =
4124	"\n"
4125	"uniform int texture_layer;\n"
4126	"\n"
4127	"void main()\n"
4128	"{\n"
4129	"    texture_output = texelFetch(texture_input, ivec3(gl_FragCoord.xy, texture_layer), 0);\n"
4130	"}\n";
4131
4132template class StorageMultisampleTest<glw::GLbyte, 1, false, 2>;
4133template class StorageMultisampleTest<glw::GLbyte, 2, false, 2>;
4134template class StorageMultisampleTest<glw::GLbyte, 4, false, 2>;
4135template class StorageMultisampleTest<glw::GLbyte, 1, false, 3>;
4136template class StorageMultisampleTest<glw::GLbyte, 2, false, 3>;
4137template class StorageMultisampleTest<glw::GLbyte, 4, false, 3>;
4138
4139template class StorageMultisampleTest<glw::GLubyte, 1, false, 2>;
4140template class StorageMultisampleTest<glw::GLubyte, 2, false, 2>;
4141template class StorageMultisampleTest<glw::GLubyte, 4, false, 2>;
4142template class StorageMultisampleTest<glw::GLubyte, 1, false, 3>;
4143template class StorageMultisampleTest<glw::GLubyte, 2, false, 3>;
4144template class StorageMultisampleTest<glw::GLubyte, 4, false, 3>;
4145
4146template class StorageMultisampleTest<glw::GLubyte, 1, true, 2>;
4147template class StorageMultisampleTest<glw::GLubyte, 2, true, 2>;
4148template class StorageMultisampleTest<glw::GLubyte, 4, true, 2>;
4149template class StorageMultisampleTest<glw::GLubyte, 1, true, 3>;
4150template class StorageMultisampleTest<glw::GLubyte, 2, true, 3>;
4151template class StorageMultisampleTest<glw::GLubyte, 4, true, 3>;
4152
4153template class StorageMultisampleTest<glw::GLshort, 1, false, 2>;
4154template class StorageMultisampleTest<glw::GLshort, 2, false, 2>;
4155template class StorageMultisampleTest<glw::GLshort, 4, false, 2>;
4156template class StorageMultisampleTest<glw::GLshort, 1, false, 3>;
4157template class StorageMultisampleTest<glw::GLshort, 2, false, 3>;
4158template class StorageMultisampleTest<glw::GLshort, 4, false, 3>;
4159
4160template class StorageMultisampleTest<glw::GLushort, 1, false, 2>;
4161template class StorageMultisampleTest<glw::GLushort, 2, false, 2>;
4162template class StorageMultisampleTest<glw::GLushort, 4, false, 2>;
4163template class StorageMultisampleTest<glw::GLushort, 1, false, 3>;
4164template class StorageMultisampleTest<glw::GLushort, 2, false, 3>;
4165template class StorageMultisampleTest<glw::GLushort, 4, false, 3>;
4166
4167template class StorageMultisampleTest<glw::GLushort, 1, true, 2>;
4168template class StorageMultisampleTest<glw::GLushort, 2, true, 2>;
4169template class StorageMultisampleTest<glw::GLushort, 4, true, 2>;
4170template class StorageMultisampleTest<glw::GLushort, 1, true, 3>;
4171template class StorageMultisampleTest<glw::GLushort, 2, true, 3>;
4172template class StorageMultisampleTest<glw::GLushort, 4, true, 3>;
4173
4174template class StorageMultisampleTest<glw::GLint, 1, false, 2>;
4175template class StorageMultisampleTest<glw::GLint, 2, false, 2>;
4176template class StorageMultisampleTest<glw::GLint, 3, false, 2>;
4177template class StorageMultisampleTest<glw::GLint, 4, false, 2>;
4178template class StorageMultisampleTest<glw::GLint, 1, false, 3>;
4179template class StorageMultisampleTest<glw::GLint, 2, false, 3>;
4180template class StorageMultisampleTest<glw::GLint, 3, false, 3>;
4181template class StorageMultisampleTest<glw::GLint, 4, false, 3>;
4182
4183template class StorageMultisampleTest<glw::GLuint, 1, false, 2>;
4184template class StorageMultisampleTest<glw::GLuint, 2, false, 2>;
4185template class StorageMultisampleTest<glw::GLuint, 3, false, 2>;
4186template class StorageMultisampleTest<glw::GLuint, 4, false, 2>;
4187template class StorageMultisampleTest<glw::GLuint, 1, false, 3>;
4188template class StorageMultisampleTest<glw::GLuint, 2, false, 3>;
4189template class StorageMultisampleTest<glw::GLuint, 3, false, 3>;
4190template class StorageMultisampleTest<glw::GLuint, 4, false, 3>;
4191
4192template class StorageMultisampleTest<glw::GLfloat, 1, true, 2>;
4193template class StorageMultisampleTest<glw::GLfloat, 2, true, 2>;
4194template class StorageMultisampleTest<glw::GLfloat, 3, true, 2>;
4195template class StorageMultisampleTest<glw::GLfloat, 4, true, 2>;
4196template class StorageMultisampleTest<glw::GLfloat, 1, true, 3>;
4197template class StorageMultisampleTest<glw::GLfloat, 2, true, 3>;
4198template class StorageMultisampleTest<glw::GLfloat, 3, true, 3>;
4199template class StorageMultisampleTest<glw::GLfloat, 4, true, 3>;
4200
4201/******************************** Compressed SubImage Test Implementation   ********************************/
4202
4203/** @brief Compressed SubImage Test constructor.
4204 *
4205 *  @param [in] context     OpenGL context.
4206 */
4207CompressedSubImageTest::CompressedSubImageTest(deqp::Context& context)
4208	: deqp::TestCase(context, "textures_compressed_subimage", "Texture Compressed SubImage Test")
4209	, m_to(0)
4210	, m_to_aux(0)
4211	, m_compressed_texture_data(DE_NULL)
4212	, m_reference(DE_NULL)
4213	, m_result(DE_NULL)
4214	, m_reference_size(0)
4215	, m_reference_internalformat(0)
4216{
4217	/* Intentionally left blank. */
4218}
4219
4220/** @brief Create texture.
4221 *
4222 *  @param [in] target      Texture target.
4223 */
4224void CompressedSubImageTest::CreateTextures(glw::GLenum target)
4225{
4226	/* Shortcut for GL functionality. */
4227	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4228
4229	/* Auxiliary texture (for content creation). */
4230	gl.genTextures(1, &m_to_aux);
4231	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
4232
4233	gl.bindTexture(target, m_to_aux);
4234	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
4235
4236	/* Test texture (for data upload). */
4237	gl.genTextures(1, &m_to);
4238	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
4239
4240	gl.bindTexture(target, m_to);
4241	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
4242}
4243
4244/** @brief Texture target selector.
4245 *
4246 *  @tparam D      Texture dimenisons.
4247 *
4248 *  @return Texture target.
4249 */
4250template <>
4251glw::GLenum CompressedSubImageTest::TextureTarget<1>()
4252{
4253	return GL_TEXTURE_1D;
4254}
4255
4256template <>
4257glw::GLenum CompressedSubImageTest::TextureTarget<2>()
4258{
4259	return GL_TEXTURE_2D;
4260}
4261
4262template <>
4263glw::GLenum CompressedSubImageTest::TextureTarget<3>()
4264{
4265	return GL_TEXTURE_2D_ARRAY;
4266}
4267
4268/** @brief Prepare texture data for the auxiliary texture.
4269 *
4270 *  @tparam D      Texture dimenisons.
4271 *
4272 *  @note parameters as passed to texImage*
4273 */
4274template <>
4275void CompressedSubImageTest::TextureImage<1>(glw::GLint internalformat)
4276{
4277	/* Shortcut for GL functionality. */
4278	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4279
4280	gl.texImage1D(TextureTarget<1>(), 0, internalformat, s_texture_width, 0, GL_RGBA, GL_UNSIGNED_BYTE, s_texture_data);
4281	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");
4282}
4283
4284/** @brief Prepare texture data for the auxiliary texture.
4285 *
4286 *  @tparam D      Texture dimenisons.
4287 *
4288 *  @note parameters as passed to texImage*
4289 */
4290template <>
4291void CompressedSubImageTest::TextureImage<2>(glw::GLint internalformat)
4292{
4293	/* Shortcut for GL functionality. */
4294	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4295
4296	gl.texImage2D(TextureTarget<2>(), 0, internalformat, s_texture_width, s_texture_height, 0, GL_RGBA,
4297				  GL_UNSIGNED_BYTE, s_texture_data);
4298	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");
4299}
4300
4301/** @brief Prepare texture data for the auxiliary texture.
4302 *
4303 *  @tparam D      Texture dimenisons.
4304 *
4305 *  @note parameters as passed to texImage*
4306 */
4307template <>
4308void CompressedSubImageTest::TextureImage<3>(glw::GLint internalformat)
4309{
4310	/* Shortcut for GL functionality. */
4311	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4312
4313	gl.texImage3D(TextureTarget<3>(), 0, internalformat, s_texture_width, s_texture_height, s_texture_depth, 0, GL_RGBA,
4314				  GL_UNSIGNED_BYTE, s_texture_data);
4315	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage3D has failed");
4316}
4317
4318/** @brief Prepare texture data for the auxiliary texture.
4319 *
4320 *  @tparam D      Texture dimensions.
4321 *
4322 *  @note parameters as passed to compressedTexImage*
4323 */
4324template <>
4325void CompressedSubImageTest::CompressedTexImage<1>(glw::GLint internalformat)
4326{
4327	/* Shortcut for GL functionality. */
4328	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4329
4330	gl.compressedTexImage1D(TextureTarget<1>(), 0, internalformat, s_texture_width, 0, m_reference_size,
4331							m_compressed_texture_data);
4332	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage1D has failed");
4333}
4334
4335/** @brief Prepare texture data for the auxiliary texture.
4336 *
4337 *  @tparam D      Texture dimensions.
4338 *
4339 *  @note parameters as passed to compressedTexImage*
4340 */
4341template <>
4342void CompressedSubImageTest::CompressedTexImage<2>(glw::GLint internalformat)
4343{
4344	/* Shortcut for GL functionality. */
4345	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4346
4347	gl.compressedTexImage2D(TextureTarget<2>(), 0, internalformat, s_texture_width, s_texture_height, 0,
4348							m_reference_size, m_compressed_texture_data);
4349	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage2D has failed");
4350}
4351
4352/** @brief Prepare texture data for the auxiliary texture.
4353 *
4354 *  @tparam D      Texture dimensions.
4355 *
4356 *  @note parameters as passed to compressedTexImage*
4357 */
4358template <>
4359void CompressedSubImageTest::CompressedTexImage<3>(glw::GLint internalformat)
4360{
4361	/* Shortcut for GL functionality. */
4362	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4363
4364	gl.compressedTexImage3D(TextureTarget<3>(), 0, internalformat, s_texture_width, s_texture_height, s_texture_depth,
4365							0, m_reference_size, m_compressed_texture_data);
4366	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage3D has failed");
4367}
4368
4369/** @brief Prepare texture data for the compressed texture.
4370 *
4371 *  @tparam D      Texture dimenisons.
4372 *
4373 *  @param [in] internalformat      Texture internal format.
4374 *
4375 *  @return True if tested function succeeded, false otherwise.
4376 */
4377template <>
4378bool CompressedSubImageTest::CompressedTextureSubImage<1>(glw::GLint internalformat)
4379{
4380	/* Shortcut for GL functionality. */
4381	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4382
4383	/* Load texture image with tested function. */
4384	if (m_reference_size)
4385	{
4386		for (glw::GLuint block = 0; block < s_block_count; ++block)
4387		{
4388			gl.compressedTextureSubImage1D(m_to, 0, s_texture_width * block, s_texture_width, internalformat,
4389										   m_reference_size, m_compressed_texture_data);
4390		}
4391	}
4392	else
4393	{
4394		/* For 1D version there is no specific compressed texture internal format spcified in OpenGL 4.5 core profile documentation.
4395		 Only implementation depended specific internalformats may provide this functionality. As a result there may be no reference data to be substituted.
4396		 Due to this reason there is no use of CompressedTextureSubImage1D and particulary it cannot be tested. */
4397		return true;
4398	}
4399
4400	/* Check errors. */
4401	glw::GLenum error;
4402
4403	if (GL_NO_ERROR != (error = gl.getError()))
4404	{
4405		m_context.getTestContext().getLog()
4406			<< tcu::TestLog::Message << "glCompressedTextureSubImage1D unexpectedly generated error "
4407			<< glu::getErrorStr(error) << " during the test with internal format "
4408			<< glu::getTextureFormatStr(internalformat) << ". Test fails." << tcu::TestLog::EndMessage;
4409
4410		return false;
4411	}
4412
4413	return true;
4414}
4415
4416/** @brief Prepare texture data for the compressed texture.
4417 *
4418 *  @tparam D      Texture dimenisons.
4419 *
4420 *  @param [in] internalformat      Texture internal format.
4421 *
4422 *  @return True if tested function succeeded, false otherwise.
4423 */
4424template <>
4425bool CompressedSubImageTest::CompressedTextureSubImage<2>(glw::GLint internalformat)
4426{
4427	/* Shortcut for GL functionality. */
4428	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4429
4430	for (glw::GLuint y = 0; y < s_block_2d_size_y; ++y)
4431	{
4432		for (glw::GLuint x = 0; x < s_block_2d_size_x; ++x)
4433		{
4434			/* Load texture image with tested function. */
4435			gl.compressedTextureSubImage2D(m_to, 0, s_texture_width * x, s_texture_height * y, s_texture_width,
4436										   s_texture_height, internalformat, m_reference_size,
4437										   m_compressed_texture_data);
4438		}
4439	}
4440	/* Check errors. */
4441	glw::GLenum error;
4442
4443	if (GL_NO_ERROR != (error = gl.getError()))
4444	{
4445		m_context.getTestContext().getLog()
4446			<< tcu::TestLog::Message << "glCompressedTextureSubImage2D unexpectedly generated error "
4447			<< glu::getErrorStr(error) << " during the test with internal format "
4448			<< glu::getTextureFormatStr(internalformat) << ". Test fails." << tcu::TestLog::EndMessage;
4449
4450		return false;
4451	}
4452
4453	return true;
4454}
4455
4456/** @brief Prepare texture data for the compressed texture.
4457 *
4458 *  @tparam D      Texture dimenisons.
4459 *
4460 *  @param [in] internalformat      Texture internal format.
4461 *
4462 *  @return True if tested function succeeded, false otherwise.
4463 */
4464template <>
4465bool CompressedSubImageTest::CompressedTextureSubImage<3>(glw::GLint internalformat)
4466{
4467	/* Shortcut for GL functionality. */
4468	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4469
4470	for (glw::GLuint z = 0; z < s_block_3d_size; ++z)
4471	{
4472		for (glw::GLuint y = 0; y < s_block_3d_size; ++y)
4473		{
4474			for (glw::GLuint x = 0; x < s_block_3d_size; ++x)
4475			{
4476				/* Load texture image with tested function. */
4477				gl.compressedTextureSubImage3D(m_to, 0, s_texture_width * x, s_texture_height * y, s_texture_depth * z,
4478											   s_texture_width, s_texture_height, s_texture_depth, internalformat,
4479											   m_reference_size, m_compressed_texture_data);
4480			}
4481		}
4482	}
4483
4484	/* Check errors. */
4485	glw::GLenum error;
4486
4487	if (GL_NO_ERROR != (error = gl.getError()))
4488	{
4489		m_context.getTestContext().getLog()
4490			<< tcu::TestLog::Message << "glCompressedTextureSubImage2D unexpectedly generated error "
4491			<< glu::getErrorStr(error) << " during the test with internal format "
4492			<< glu::getTextureFormatStr(internalformat) << ". Test fails." << tcu::TestLog::EndMessage;
4493
4494		return false;
4495	}
4496	return true;
4497}
4498
4499/** @brief Prepare the reference data.
4500 *
4501 *  @tparam D      Texture dimenisons.
4502 */
4503template <glw::GLuint D>
4504void CompressedSubImageTest::PrepareReferenceData(glw::GLenum internalformat)
4505{
4506	/* Shortcut for GL functionality. */
4507	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4508
4509	/* Using OpenGL to compress raw data. */
4510	gl.bindTexture(TextureTarget<D>(), m_to_aux);
4511	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
4512
4513	TextureImage<D>(internalformat);
4514
4515	/* Sanity checks. */
4516	if ((DE_NULL != m_reference) || (DE_NULL != m_compressed_texture_data))
4517	{
4518		throw 0;
4519	}
4520
4521	/* Check that really compressed texture. */
4522	glw::GLint is_compressed_texture = 0;
4523	gl.getTexLevelParameteriv(TextureTarget<D>(), 0, GL_TEXTURE_COMPRESSED, &is_compressed_texture);
4524
4525	if (is_compressed_texture)
4526	{
4527		/* Query texture size. */
4528		glw::GLint compressed_texture_size = 0;
4529		gl.getTexLevelParameteriv(TextureTarget<D>(), 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &compressed_texture_size);
4530
4531		/* If compressed then download. */
4532		if (compressed_texture_size)
4533		{
4534			/* Prepare storage. */
4535			m_compressed_texture_data = new glw::GLubyte[compressed_texture_size];
4536
4537			if (DE_NULL != m_compressed_texture_data)
4538			{
4539				m_reference_size = compressed_texture_size;
4540			}
4541			else
4542			{
4543				throw 0;
4544			}
4545
4546			/* Download the source compressed texture image. */
4547			gl.getCompressedTexImage(TextureTarget<D>(), 0, m_compressed_texture_data);
4548			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");
4549
4550			// Upload the source compressed texture image to the texture object.
4551			// Some compressed texture format can be emulated by the driver (like the ETC2/EAC formats)
4552			// The compressed data sent by CompressedTexImage will be stored uncompressed by the driver
4553			// and will be re-compressed if the application call glGetCompressedTexImage.
4554			// The compression/decompression is not lossless, so when this happen it's possible for the source
4555			// and destination (from glGetCompressedTexImage) compressed data to be different.
4556			// To avoid that we will store both the source (in m_compressed_texture_data) and the destination
4557			// (in m_reference). The destination will be used later to make sure getCompressedTextureSubImage
4558			// return the expected value
4559			CompressedTexImage<D>(internalformat);
4560
4561			m_reference = new glw::GLubyte[m_reference_size];
4562
4563			if (DE_NULL == m_reference)
4564			{
4565				throw 0;
4566			}
4567
4568			/* Download compressed texture image. */
4569			gl.getCompressedTexImage(TextureTarget<D>(), 0, m_reference);
4570			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");
4571		}
4572	}
4573}
4574
4575/** @brief Prepare texture storage.
4576 *
4577 *  @tparam D      Texture dimenisons.
4578 *
4579 *  @param [in] internalformat      Texture internal format.
4580 */
4581template <>
4582void CompressedSubImageTest::PrepareStorage<1>(glw::GLenum internalformat)
4583{
4584	/* Shortcut for GL functionality. */
4585	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4586
4587	gl.bindTexture(TextureTarget<1>(), m_to);
4588	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
4589
4590	gl.texImage1D(TextureTarget<1>(), 0, internalformat, s_texture_width * s_block_count, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4591				  NULL);
4592	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");
4593}
4594
4595/** @brief Prepare texture storage.
4596 *
4597 *  @tparam D      Texture dimenisons.
4598 *
4599 *  @param [in] internalformat      Texture internal format.
4600 */
4601template <>
4602void CompressedSubImageTest::PrepareStorage<2>(glw::GLenum internalformat)
4603{
4604	/* Shortcut for GL functionality. */
4605	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4606
4607	gl.bindTexture(TextureTarget<2>(), m_to);
4608	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
4609
4610	gl.texImage2D(TextureTarget<2>(), 0, internalformat, s_texture_width * s_block_2d_size_x,
4611				  s_texture_height * s_block_2d_size_y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
4612	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");
4613}
4614
4615/** @brief Prepare texture storage.
4616 *
4617 *  @tparam D      Texture dimenisons.
4618 *
4619 *  @param [in] internalformat      Texture internal format.
4620 */
4621template <>
4622void CompressedSubImageTest::PrepareStorage<3>(glw::GLenum internalformat)
4623{
4624	/* Shortcut for GL functionality. */
4625	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4626
4627	gl.bindTexture(TextureTarget<3>(), m_to);
4628	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
4629
4630	gl.texImage3D(TextureTarget<3>(), 0, internalformat, s_texture_width * s_block_3d_size,
4631				  s_texture_height * s_block_3d_size, s_texture_depth * s_block_3d_size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4632				  NULL);
4633	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");
4634}
4635
4636/** @brief Compare results with the reference.
4637 *
4638 *  @tparam T      Type.
4639 *  @tparam S      Size (# of components).
4640 *  @tparam N      Is normalized.
4641 *
4642 *  @param [in] internalformat      Texture internal format.
4643 *
4644 *  @return True if equal, false otherwise.
4645 */
4646template <glw::GLuint D>
4647bool CompressedSubImageTest::CheckData(glw::GLenum internalformat)
4648{
4649	/* Shortcut for GL functionality. */
4650	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4651
4652	/* Check texture content with reference. */
4653	m_result = new glw::GLubyte[m_reference_size * s_block_count];
4654
4655	if (DE_NULL == m_result)
4656	{
4657		throw 0;
4658	}
4659
4660	gl.getCompressedTexImage(TextureTarget<D>(), 0, m_result);
4661	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");
4662	for (glw::GLuint block = 0; block < s_block_count; ++block)
4663	{
4664		for (glw::GLuint i = 0; i < m_reference_size; ++i)
4665		{
4666			if (m_reference[i] != m_result[block * m_reference_size + i])
4667			{
4668				m_context.getTestContext().getLog()
4669					<< tcu::TestLog::Message << "glCompressedTextureSubImage*D created texture with data "
4670					<< DataToString(m_reference_size, m_reference) << " however texture contains data "
4671					<< DataToString(m_reference_size, &(m_result[block * m_reference_size])) << ". Texture target was "
4672					<< glu::getTextureTargetStr(TextureTarget<D>()) << " and internal format was "
4673					<< glu::getTextureFormatStr(internalformat) << ". Test fails." << tcu::TestLog::EndMessage;
4674
4675				return false;
4676			}
4677		}
4678	}
4679
4680	return true;
4681}
4682
4683/** @brief Compare results with the reference.
4684 *
4685 *  @tparam T      Type.
4686 *  @tparam S      Size (# of components).
4687 *  @tparam N      Is normalized.
4688 *
4689 *  @param [in] internalformat      Texture internal format.
4690 *
4691 *  @return True if equal, false otherwise.
4692 */
4693template <>
4694bool CompressedSubImageTest::CheckData<3>(glw::GLenum internalformat)
4695{
4696	/* Shortcut for GL functionality. */
4697	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4698
4699	/* Check texture content with reference. */
4700	m_result = new glw::GLubyte[m_reference_size * s_block_count];
4701
4702	if (DE_NULL == m_result)
4703	{
4704		throw 0;
4705	}
4706
4707	gl.getCompressedTexImage(TextureTarget<3>(), 0, m_result);
4708	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");
4709
4710	glw::GLuint reference_layer_size = m_reference_size / s_texture_depth;
4711
4712	for (glw::GLuint i = 0; i < m_reference_size * s_block_count; ++i)
4713	{
4714		// we will read the result one bytes at the time and compare with the reference
4715		// for each bytes of the result image we need to figure out which byte in the reference image it corresponds to
4716		glw::GLuint refIdx		= i % reference_layer_size;
4717		glw::GLuint refLayerIdx = (i / (reference_layer_size * s_block_3d_size * s_block_3d_size)) % s_texture_depth;
4718		if (m_reference[refLayerIdx * reference_layer_size + refIdx] != m_result[i])
4719		{
4720			m_context.getTestContext().getLog()
4721				<< tcu::TestLog::Message << "glCompressedTextureSubImage3D created texture with data "
4722				<< DataToString(reference_layer_size, &(m_reference[refLayerIdx * reference_layer_size]))
4723				<< " however texture contains data "
4724				<< DataToString(reference_layer_size, &(m_result[i % reference_layer_size])) << ". Texture target was "
4725				<< glu::getTextureTargetStr(TextureTarget<3>()) << " and internal format was "
4726				<< glu::getTextureFormatStr(internalformat) << ". Test fails." << tcu::TestLog::EndMessage;
4727
4728			return false;
4729		}
4730	}
4731
4732	return true;
4733}
4734/** @brief Test case function.
4735 *
4736 *  @tparam D       Number of texture dimensions.
4737 *
4738 *  @param [in] internal format     Texture internal format.
4739 *
4740 *  @return True if test succeeded, false otherwise.
4741 */
4742template <glw::GLuint D>
4743bool CompressedSubImageTest::Test(glw::GLenum internalformat)
4744{
4745	/* Create texture image. */
4746	CreateTextures(TextureTarget<D>());
4747	PrepareReferenceData<D>(internalformat);
4748	PrepareStorage<D>(internalformat);
4749
4750	/* Setup data with CompressedTextureSubImage<D>D function and check for errors. */
4751	if (!CompressedTextureSubImage<D>(internalformat))
4752	{
4753		CleanAll();
4754
4755		return false;
4756	}
4757
4758	/* If compressed reference data was generated than compare values. */
4759	if (m_reference)
4760	{
4761		if (!CheckData<D>(internalformat))
4762		{
4763			CleanAll();
4764
4765			return false;
4766		}
4767	}
4768
4769	CleanAll();
4770
4771	return true;
4772}
4773
4774/** @brief Clean GL objects, test variables and GL errors.
4775 */
4776void CompressedSubImageTest::CleanAll()
4777{
4778	/* Shortcut for GL functionality. */
4779	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4780
4781	/* Textures. */
4782	if (m_to)
4783	{
4784		gl.deleteTextures(1, &m_to);
4785
4786		m_to = 0;
4787	}
4788
4789	if (m_to_aux)
4790	{
4791		gl.deleteTextures(1, &m_to_aux);
4792
4793		m_to_aux = 0;
4794	}
4795
4796	/* Reference data storage. */
4797	if (DE_NULL != m_reference)
4798	{
4799		delete[] m_reference;
4800
4801		m_reference = DE_NULL;
4802	}
4803
4804	if (DE_NULL != m_compressed_texture_data)
4805	{
4806		delete[] m_compressed_texture_data;
4807
4808		m_compressed_texture_data = DE_NULL;
4809	}
4810
4811	if (DE_NULL != m_result)
4812	{
4813		delete[] m_result;
4814
4815		m_result = DE_NULL;
4816	}
4817
4818	m_reference_size = 0;
4819
4820	/* Errors. */
4821	while (GL_NO_ERROR != gl.getError())
4822		;
4823}
4824
4825/** @brief Convert raw data into string for logging purposes.
4826 *
4827 *  @param [in] count      Count of the data.
4828 *  @param [in] data       Raw data.
4829 *
4830 *  @return String representation of data.
4831 */
4832std::string CompressedSubImageTest::DataToString(glw::GLuint count, const glw::GLubyte data[])
4833{
4834	std::string data_str = "[";
4835
4836	for (glw::GLuint i = 0; i < count; ++i)
4837	{
4838		std::stringstream int_sstream;
4839
4840		int_sstream << unsigned(data[i]);
4841
4842		data_str.append(int_sstream.str());
4843
4844		if (i + 1 < count)
4845		{
4846			data_str.append(", ");
4847		}
4848		else
4849		{
4850			data_str.append("]");
4851		}
4852	}
4853
4854	return data_str;
4855}
4856
4857/** @brief Iterate Compressed SubImage Test cases.
4858 *
4859 *  @return Iteration result.
4860 */
4861tcu::TestNode::IterateResult CompressedSubImageTest::iterate()
4862{
4863	/* Shortcut for GL functionality. */
4864	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4865
4866	/* Get context setup. */
4867	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
4868	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
4869
4870	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
4871	{
4872		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
4873
4874		return STOP;
4875	}
4876
4877	/* Running tests. */
4878	bool is_ok	= true;
4879	bool is_error = false;
4880
4881	try
4882	{
4883		is_ok &= Test<1>(GL_COMPRESSED_RGB);
4884
4885		is_ok &= Test<2>(GL_COMPRESSED_RED_RGTC1);
4886		is_ok &= Test<2>(GL_COMPRESSED_SIGNED_RED_RGTC1);
4887		is_ok &= Test<2>(GL_COMPRESSED_RG_RGTC2);
4888		is_ok &= Test<2>(GL_COMPRESSED_SIGNED_RG_RGTC2);
4889		is_ok &= Test<2>(GL_COMPRESSED_RGBA_BPTC_UNORM);
4890		is_ok &= Test<2>(GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM);
4891		is_ok &= Test<2>(GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT);
4892		is_ok &= Test<2>(GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT);
4893		is_ok &= Test<2>(GL_COMPRESSED_RGB8_ETC2);
4894		is_ok &= Test<2>(GL_COMPRESSED_SRGB8_ETC2);
4895		is_ok &= Test<2>(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2);
4896		is_ok &= Test<2>(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2);
4897		is_ok &= Test<2>(GL_COMPRESSED_RGBA8_ETC2_EAC);
4898		is_ok &= Test<2>(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC);
4899		is_ok &= Test<2>(GL_COMPRESSED_R11_EAC);
4900		is_ok &= Test<2>(GL_COMPRESSED_SIGNED_R11_EAC);
4901		is_ok &= Test<2>(GL_COMPRESSED_RG11_EAC);
4902		is_ok &= Test<2>(GL_COMPRESSED_SIGNED_RG11_EAC);
4903
4904		is_ok &= Test<3>(GL_COMPRESSED_RED_RGTC1);
4905		is_ok &= Test<3>(GL_COMPRESSED_SIGNED_RED_RGTC1);
4906		is_ok &= Test<3>(GL_COMPRESSED_RG_RGTC2);
4907		is_ok &= Test<3>(GL_COMPRESSED_SIGNED_RG_RGTC2);
4908		is_ok &= Test<3>(GL_COMPRESSED_RGBA_BPTC_UNORM);
4909		is_ok &= Test<3>(GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM);
4910		is_ok &= Test<3>(GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT);
4911		is_ok &= Test<3>(GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT);
4912		is_ok &= Test<3>(GL_COMPRESSED_RGB8_ETC2);
4913		is_ok &= Test<3>(GL_COMPRESSED_SRGB8_ETC2);
4914		is_ok &= Test<3>(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2);
4915		is_ok &= Test<3>(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2);
4916		is_ok &= Test<3>(GL_COMPRESSED_RGBA8_ETC2_EAC);
4917		is_ok &= Test<3>(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC);
4918		is_ok &= Test<3>(GL_COMPRESSED_R11_EAC);
4919		is_ok &= Test<3>(GL_COMPRESSED_SIGNED_R11_EAC);
4920		is_ok &= Test<3>(GL_COMPRESSED_RG11_EAC);
4921		is_ok &= Test<3>(GL_COMPRESSED_SIGNED_RG11_EAC);
4922	}
4923	catch (...)
4924	{
4925		is_ok	= false;
4926		is_error = true;
4927	}
4928
4929	/* Cleanup. */
4930	CleanAll();
4931
4932	/* Errors clean up. */
4933	while (gl.getError())
4934		;
4935
4936	/* Result's setup. */
4937	if (is_ok)
4938	{
4939		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
4940	}
4941	else
4942	{
4943		if (is_error)
4944		{
4945			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
4946		}
4947		else
4948		{
4949			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
4950		}
4951	}
4952
4953	return STOP;
4954}
4955
4956/** Reference data. */
4957const glw::GLubyte CompressedSubImageTest::s_texture_data[] = {
4958	0x00, 0x00, 0x00, 0xFF, 0x7f, 0x7f, 0x7f, 0x00, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0x00,
4959	0x88, 0x00, 0x15, 0xFF, 0xed, 0x1c, 0x24, 0x00, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x00, 0x00,
4960	0xc8, 0xbf, 0xe7, 0xFF, 0x70, 0x92, 0xbe, 0x00, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0x00,
4961	0xa3, 0x49, 0xa4, 0xFF, 0x3f, 0x48, 0xcc, 0x00, 0x00, 0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0x00,
4962
4963	0xa3, 0x49, 0xa4, 0xFF, 0xc8, 0xbf, 0xe7, 0x00, 0x88, 0x00, 0x15, 0xff, 0x00, 0x00, 0x00, 0x00,
4964	0x3f, 0x48, 0xcc, 0xFF, 0x70, 0x92, 0xbe, 0x00, 0xed, 0x1c, 0x24, 0xff, 0x7f, 0x7f, 0x7f, 0x00,
4965	0x00, 0xa2, 0xe8, 0xFF, 0x99, 0xd9, 0xea, 0x00, 0xff, 0x7f, 0x27, 0xff, 0xc3, 0xc3, 0xc3, 0x00,
4966	0x22, 0xb1, 0x4c, 0xFF, 0xb5, 0xe6, 0x1d, 0x00, 0xff, 0xf2, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
4967
4968	0x22, 0xb1, 0x4c, 0xFF, 0x00, 0xa2, 0xe8, 0x00, 0x3f, 0x48, 0xcc, 0xff, 0xa3, 0x49, 0xa4, 0x00,
4969	0xb5, 0xe6, 0x1d, 0xFF, 0x99, 0xd9, 0xea, 0x00, 0x70, 0x92, 0xbe, 0xff, 0xc8, 0xbf, 0xe7, 0x00,
4970	0xff, 0xf2, 0x00, 0xFF, 0xff, 0x7f, 0x27, 0x00, 0xed, 0x1c, 0x24, 0xff, 0x88, 0x00, 0x15, 0x00,
4971	0xff, 0xff, 0xff, 0xFF, 0xc3, 0xc3, 0xc3, 0x00, 0x7f, 0x7f, 0x7f, 0xff, 0x00, 0x00, 0x00, 0x00,
4972
4973	0xff, 0xff, 0xff, 0xFF, 0xff, 0xf2, 0x00, 0x00, 0xb5, 0xe6, 0x1d, 0xff, 0x22, 0xb1, 0x4c, 0x00,
4974	0xc3, 0xc3, 0xc3, 0xFF, 0xff, 0x7f, 0x27, 0x00, 0x99, 0xd9, 0xea, 0xff, 0x00, 0xa2, 0xe8, 0x00,
4975	0x7f, 0x7f, 0x7f, 0xFF, 0xed, 0x1c, 0x24, 0x00, 0x70, 0x92, 0xbe, 0xff, 0x3f, 0x48, 0xcc, 0x00,
4976	0x00, 0x00, 0x00, 0xFF, 0x88, 0x00, 0x15, 0x00, 0xc8, 0xbf, 0xe7, 0xff, 0xa3, 0x49, 0xa4, 0x00
4977};
4978
4979/** Reference data parameters. */
4980const glw::GLuint CompressedSubImageTest::s_texture_width   = 4;
4981const glw::GLuint CompressedSubImageTest::s_texture_height  = 4;
4982const glw::GLuint CompressedSubImageTest::s_texture_depth   = 4;
4983const glw::GLuint CompressedSubImageTest::s_block_count		= 8;
4984const glw::GLuint CompressedSubImageTest::s_block_2d_size_x = 4;
4985const glw::GLuint CompressedSubImageTest::s_block_2d_size_y = 2;
4986const glw::GLuint CompressedSubImageTest::s_block_3d_size   = 2;
4987
4988/******************************** Copy SubImage Test Implementation   ********************************/
4989
4990/** @brief Compressed SubImage Test constructor.
4991 *
4992 *  @param [in] context     OpenGL context.
4993 */
4994CopyTest::CopyTest(deqp::Context& context)
4995	: deqp::TestCase(context, "textures_copy", "Texture Copy Test")
4996	, m_fbo(0)
4997	, m_to_src(0)
4998	, m_to_dst(0)
4999	, m_result(DE_NULL)
5000{
5001	/* Intentionally left blank. */
5002}
5003
5004/** @brief Texture target selector.
5005 *
5006 *  @tparam D      Texture dimenisons.
5007 *
5008 *  @return Texture target.
5009 */
5010template <>
5011glw::GLenum CopyTest::TextureTarget<1>()
5012{
5013	return GL_TEXTURE_1D;
5014}
5015template <>
5016glw::GLenum CopyTest::TextureTarget<2>()
5017{
5018	return GL_TEXTURE_2D;
5019}
5020template <>
5021glw::GLenum CopyTest::TextureTarget<3>()
5022{
5023	return GL_TEXTURE_3D;
5024}
5025
5026/** @brief Copy texture, check errors and log.
5027 *
5028 *  @note Parameters as passed to CopyTextureSubImage*D
5029 *
5030 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
5031 */
5032bool CopyTest::CopyTextureSubImage1DAndCheckErrors(glw::GLuint texture, glw::GLint level, glw::GLint xoffset,
5033												   glw::GLint x, glw::GLint y, glw::GLsizei width)
5034{
5035	/* Shortcut for GL functionality. */
5036	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5037
5038	gl.readBuffer(GL_COLOR_ATTACHMENT0);
5039	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");
5040
5041	gl.copyTextureSubImage1D(texture, level, xoffset, x, y, width);
5042
5043	/* Check errors. */
5044	glw::GLenum error;
5045
5046	if (GL_NO_ERROR != (error = gl.getError()))
5047	{
5048		m_context.getTestContext().getLog() << tcu::TestLog::Message
5049											<< "glCopyTextureSubImage1D unexpectedly generated error "
5050											<< glu::getErrorStr(error) << ". Test fails." << tcu::TestLog::EndMessage;
5051
5052		return false;
5053	}
5054
5055	return true;
5056}
5057
5058/** @brief Copy texture, check errors and log.
5059 *
5060 *  @note Parameters as passed to CopyTextureSubImage*D
5061 *
5062 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
5063 */
5064bool CopyTest::CopyTextureSubImage2DAndCheckErrors(glw::GLuint texture, glw::GLint level, glw::GLint xoffset,
5065												   glw::GLint yoffset, glw::GLint x, glw::GLint y, glw::GLsizei width,
5066												   glw::GLsizei height)
5067{
5068	/* Shortcut for GL functionality. */
5069	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5070
5071	gl.readBuffer(GL_COLOR_ATTACHMENT0);
5072	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");
5073
5074	gl.copyTextureSubImage2D(texture, level, xoffset, yoffset, x, y, width, height);
5075
5076	/* Check errors. */
5077	glw::GLenum error;
5078
5079	if (GL_NO_ERROR != (error = gl.getError()))
5080	{
5081		m_context.getTestContext().getLog() << tcu::TestLog::Message
5082											<< "glCopyTextureSubImage2D unexpectedly generated error "
5083											<< glu::getErrorStr(error) << ". Test fails." << tcu::TestLog::EndMessage;
5084
5085		return false;
5086	}
5087
5088	return true;
5089}
5090
5091/** @brief Copy texture, check errors and log.
5092 *
5093 *  @note Parameters as passed to CopyTextureSubImage*D
5094 *
5095 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
5096 */
5097bool CopyTest::CopyTextureSubImage3DAndCheckErrors(glw::GLuint texture, glw::GLint level, glw::GLint xoffset,
5098												   glw::GLint yoffset, glw::GLint zoffset, glw::GLint x, glw::GLint y,
5099												   glw::GLsizei width, glw::GLsizei height)
5100{
5101	/* Shortcut for GL functionality. */
5102	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5103
5104	gl.readBuffer(GL_COLOR_ATTACHMENT0 + zoffset);
5105	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");
5106
5107	gl.copyTextureSubImage3D(texture, level, xoffset, yoffset, zoffset, x, y, width, height);
5108
5109	/* Check errors. */
5110	glw::GLenum error;
5111
5112	if (GL_NO_ERROR != (error = gl.getError()))
5113	{
5114		m_context.getTestContext().getLog() << tcu::TestLog::Message
5115											<< "glCopyTextureSubImage3D unexpectedly generated error "
5116											<< glu::getErrorStr(error) << ". Test fails." << tcu::TestLog::EndMessage;
5117
5118		return false;
5119	}
5120
5121	return true;
5122}
5123
5124/** @brief Create texture.
5125 *
5126 *  @tparam D      Dimmensions.
5127 */
5128template <>
5129void CopyTest::CreateSourceTexture<1>()
5130{
5131	/* Shortcut for GL functionality. */
5132	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5133
5134	gl.genTextures(1, &m_to_src);
5135	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
5136
5137	gl.bindTexture(TextureTarget<1>(), m_to_src);
5138	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
5139
5140	gl.texImage1D(TextureTarget<1>(), 0, GL_RGBA8, s_texture_width, 0, GL_RGBA, GL_UNSIGNED_BYTE, s_texture_data);
5141	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D call failed.");
5142}
5143
5144/** @brief Create texture.
5145 *
5146 *  @tparam D      Dimmensions.
5147 */
5148template <>
5149void CopyTest::CreateSourceTexture<2>()
5150{
5151	/* Shortcut for GL functionality. */
5152	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5153
5154	gl.genTextures(1, &m_to_src);
5155	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
5156
5157	gl.bindTexture(TextureTarget<2>(), m_to_src);
5158	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
5159
5160	gl.texImage2D(TextureTarget<2>(), 0, GL_RGBA8, s_texture_width, s_texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5161				  s_texture_data);
5162	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D call failed.");
5163}
5164
5165/** @brief Create texture.
5166 *
5167 *  @tparam D      Dimmensions.
5168 */
5169template <>
5170void CopyTest::CreateSourceTexture<3>()
5171{
5172	/* Shortcut for GL functionality. */
5173	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5174
5175	gl.genTextures(1, &m_to_src);
5176	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
5177
5178	gl.bindTexture(TextureTarget<3>(), m_to_src);
5179	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
5180
5181	gl.texImage3D(TextureTarget<3>(), 0, GL_RGBA8, s_texture_width, s_texture_height, s_texture_depth, 0, GL_RGBA,
5182				  GL_UNSIGNED_BYTE, s_texture_data);
5183	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D call failed.");
5184}
5185
5186/** @brief Create texture.
5187 *
5188 *  @tparam D      Dimmensions.
5189 */
5190template <>
5191void CopyTest::CreateDestinationTexture<1>()
5192{
5193	/* Shortcut for GL functionality. */
5194	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5195
5196	gl.genTextures(1, &m_to_dst);
5197	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
5198
5199	gl.bindTexture(TextureTarget<1>(), m_to_dst);
5200	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
5201
5202	gl.texImage1D(TextureTarget<1>(), 0, GL_RGBA8, s_texture_width, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
5203	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D call failed.");
5204}
5205
5206/** @brief Create texture.
5207 *
5208 *  @tparam D      Dimmensions.
5209 */
5210template <>
5211void CopyTest::CreateDestinationTexture<2>()
5212{
5213	/* Shortcut for GL functionality. */
5214	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5215
5216	gl.genTextures(1, &m_to_dst);
5217	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
5218
5219	gl.bindTexture(TextureTarget<2>(), m_to_dst);
5220	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
5221
5222	gl.texImage2D(TextureTarget<2>(), 0, GL_RGBA8, s_texture_width, s_texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5223				  DE_NULL);
5224	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D call failed.");
5225}
5226
5227/** @brief Create texture.
5228 *
5229 *  @tparam D      Dimmensions.
5230 */
5231template <>
5232void CopyTest::CreateDestinationTexture<3>()
5233{
5234	/* Shortcut for GL functionality. */
5235	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5236
5237	gl.genTextures(1, &m_to_dst);
5238	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
5239
5240	gl.bindTexture(TextureTarget<3>(), m_to_dst);
5241	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
5242
5243	gl.texImage3D(TextureTarget<3>(), 0, GL_RGBA8, s_texture_width, s_texture_height, s_texture_depth, 0, GL_RGBA,
5244				  GL_UNSIGNED_BYTE, DE_NULL);
5245	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D call failed.");
5246}
5247
5248/** @brief Create framebuffer.
5249 *
5250 *  @tparam D      Dimmensions.
5251 */
5252template <>
5253void CopyTest::CreateSourceFramebuffer<1>()
5254{
5255	/* Shortcut for GL functionality. */
5256	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5257
5258	/* Prepare framebuffer. */
5259	gl.genFramebuffers(1, &m_fbo);
5260	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
5261
5262	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
5263	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
5264
5265	gl.framebufferTexture1D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, TextureTarget<1>(), m_to_src, 0);
5266	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture1D call failed.");
5267
5268	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
5269	{
5270		throw 0;
5271	}
5272
5273	gl.viewport(0, 0, s_texture_width, 1);
5274	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
5275}
5276
5277/** @brief Create framebuffer.
5278 *
5279 *  @tparam D      Dimmensions.
5280 */
5281template <>
5282void CopyTest::CreateSourceFramebuffer<2>()
5283{
5284	/* Shortcut for GL functionality. */
5285	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5286
5287	/* Prepare framebuffer. */
5288	gl.genFramebuffers(1, &m_fbo);
5289	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
5290
5291	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
5292	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
5293
5294	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, TextureTarget<2>(), m_to_src, 0);
5295	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture1D call failed.");
5296
5297	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
5298	{
5299		throw 0;
5300	}
5301
5302	gl.viewport(0, 0, s_texture_width, s_texture_height);
5303	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
5304}
5305
5306/** @brief Create framebuffer.
5307 *
5308 *  @tparam D      Dimmensions.
5309 */
5310template <>
5311void CopyTest::CreateSourceFramebuffer<3>()
5312{
5313	/* Shortcut for GL functionality. */
5314	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5315
5316	/* Prepare framebuffer. */
5317	gl.genFramebuffers(1, &m_fbo);
5318	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
5319
5320	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
5321	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
5322
5323	for (glw::GLuint i = 0; i < s_texture_depth; ++i)
5324	{
5325		gl.framebufferTexture3D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, TextureTarget<3>(), m_to_src, 0, i);
5326		GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture1D call failed.");
5327	}
5328
5329	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
5330	{
5331		throw 0;
5332	}
5333
5334	gl.viewport(0, 0, s_texture_width, s_texture_height);
5335	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
5336}
5337
5338/** @brief Dispatch function to create test objects */
5339template <glw::GLuint D>
5340void				  CopyTest::CreateAll()
5341{
5342	CreateSourceTexture<D>();
5343	CreateSourceFramebuffer<D>();
5344	CreateDestinationTexture<D>();
5345}
5346
5347/** @brief Test function */
5348template <>
5349bool CopyTest::Test<1>()
5350{
5351	CreateAll<1>();
5352
5353	bool result = true;
5354
5355	result &= CopyTextureSubImage1DAndCheckErrors(m_to_dst, 0, 0, 0, 0, s_texture_width / 2);
5356	result &= CopyTextureSubImage1DAndCheckErrors(m_to_dst, 0, s_texture_width / 2, s_texture_width / 2, 0,
5357												  s_texture_width / 2);
5358
5359	result &= CheckData(TextureTarget<1>(), 4 /* RGBA */ * s_texture_width);
5360
5361	CleanAll();
5362
5363	return result;
5364}
5365
5366/** @brief Test function */
5367template <>
5368bool CopyTest::Test<2>()
5369{
5370	CreateAll<2>();
5371
5372	bool result = true;
5373
5374	result &= CopyTextureSubImage2DAndCheckErrors(m_to_dst, 0, 0, 0, 0, 0, s_texture_width / 2, s_texture_height / 2);
5375	result &= CopyTextureSubImage2DAndCheckErrors(m_to_dst, 0, s_texture_width / 2, 0, s_texture_width / 2, 0,
5376												  s_texture_width / 2, s_texture_height / 2);
5377	result &= CopyTextureSubImage2DAndCheckErrors(m_to_dst, 0, 0, s_texture_height / 2, 0, s_texture_height / 2,
5378												  s_texture_width / 2, s_texture_height / 2);
5379	result &=
5380		CopyTextureSubImage2DAndCheckErrors(m_to_dst, 0, s_texture_width / 2, s_texture_height / 2, s_texture_width / 2,
5381											s_texture_height / 2, s_texture_width / 2, s_texture_height / 2);
5382
5383	result &= CheckData(TextureTarget<2>(), 4 /* RGBA */ * s_texture_width * s_texture_height);
5384
5385	CleanAll();
5386
5387	return result;
5388}
5389
5390/** @brief Test function */
5391template <>
5392bool CopyTest::Test<3>()
5393{
5394	CreateAll<3>();
5395
5396	bool result = true;
5397
5398	for (glw::GLuint i = 0; i < s_texture_depth; ++i)
5399	{
5400		result &=
5401			CopyTextureSubImage3DAndCheckErrors(m_to_dst, 0, 0, 0, i, 0, 0, s_texture_width / 2, s_texture_height / 2);
5402		result &= CopyTextureSubImage3DAndCheckErrors(m_to_dst, 0, s_texture_width / 2, 0, i, s_texture_width / 2, 0,
5403													  s_texture_width / 2, s_texture_height / 2);
5404		result &= CopyTextureSubImage3DAndCheckErrors(m_to_dst, 0, 0, s_texture_height / 2, i, 0, s_texture_height / 2,
5405													  s_texture_width / 2, s_texture_height / 2);
5406		result &= CopyTextureSubImage3DAndCheckErrors(m_to_dst, 0, s_texture_width / 2, s_texture_height / 2, i,
5407													  s_texture_width / 2, s_texture_height / 2, s_texture_width / 2,
5408													  s_texture_height / 2);
5409	}
5410
5411	result &= CheckData(TextureTarget<3>(), 4 /* RGBA */ * s_texture_width * s_texture_height * s_texture_depth);
5412
5413	CleanAll();
5414
5415	return result;
5416}
5417
5418/** @brief Compre results with the reference.
5419 *
5420 *  @param [in] target      Texture target.
5421 *  @param [in] size        Size of the buffer.
5422 *
5423 *  @return True if equal, false otherwise.
5424 */
5425bool CopyTest::CheckData(glw::GLenum target, glw::GLuint size)
5426{
5427	/* Shortcut for GL functionality. */
5428	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5429
5430	/* Check texture content with reference. */
5431	m_result = new glw::GLubyte[size];
5432
5433	if (DE_NULL == m_result)
5434	{
5435		throw 0;
5436	}
5437
5438	gl.getTexImage(target, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_result);
5439	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");
5440
5441	for (glw::GLuint i = 0; i < size; ++i)
5442	{
5443		if (s_texture_data[i] != m_result[i])
5444		{
5445			m_context.getTestContext().getLog()
5446				<< tcu::TestLog::Message << "glCopyTextureSubImage*D created texture with data "
5447				<< DataToString(size, s_texture_data) << " however texture contains data "
5448				<< DataToString(size, m_result) << ". Texture target was " << glu::getTextureTargetStr(target)
5449				<< ". Test fails." << tcu::TestLog::EndMessage;
5450
5451			return false;
5452		}
5453	}
5454
5455	return true;
5456}
5457
5458/** @brief Convert raw data into string for logging purposes.
5459 *
5460 *  @param [in] count      Count of the data.
5461 *  @param [in] data       Raw data.
5462 *
5463 *  @return String representation of data.
5464 */
5465std::string CopyTest::DataToString(glw::GLuint count, const glw::GLubyte data[])
5466{
5467	std::string data_str = "[";
5468
5469	for (glw::GLuint i = 0; i < count; ++i)
5470	{
5471		std::stringstream int_sstream;
5472
5473		int_sstream << unsigned(data[i]);
5474
5475		data_str.append(int_sstream.str());
5476
5477		if (i + 1 < count)
5478		{
5479			data_str.append(", ");
5480		}
5481		else
5482		{
5483			data_str.append("]");
5484		}
5485	}
5486
5487	return data_str;
5488}
5489
5490/** @brief Clean GL objects, test variables and GL errors.
5491 */
5492void CopyTest::CleanAll()
5493{
5494	/* Shortcut for GL functionality. */
5495	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5496
5497	if (m_fbo)
5498	{
5499		gl.deleteFramebuffers(1, &m_fbo);
5500
5501		m_fbo = 0;
5502	}
5503
5504	if (m_to_src)
5505	{
5506		gl.deleteTextures(1, &m_to_src);
5507
5508		m_to_src = 0;
5509	}
5510
5511	if (m_to_dst)
5512	{
5513		gl.deleteTextures(1, &m_to_dst);
5514
5515		m_to_dst = 0;
5516	}
5517
5518	if (DE_NULL == m_result)
5519	{
5520		delete[] m_result;
5521
5522		m_result = DE_NULL;
5523	}
5524
5525	while (GL_NO_ERROR != gl.getError())
5526		;
5527}
5528
5529/** @brief Iterate Copy Test cases.
5530 *
5531 *  @return Iteration result.
5532 */
5533tcu::TestNode::IterateResult CopyTest::iterate()
5534{
5535	/* Get context setup. */
5536	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
5537	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
5538
5539	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
5540	{
5541		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
5542
5543		return STOP;
5544	}
5545
5546	/* Running tests. */
5547	bool is_ok	= true;
5548	bool is_error = false;
5549
5550	try
5551	{
5552		is_ok &= Test<1>();
5553		is_ok &= Test<2>();
5554		is_ok &= Test<3>();
5555	}
5556	catch (...)
5557	{
5558		is_ok	= false;
5559		is_error = true;
5560	}
5561
5562	/* Cleanup. */
5563	CleanAll();
5564
5565	/* Result's setup. */
5566	if (is_ok)
5567	{
5568		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
5569	}
5570	else
5571	{
5572		if (is_error)
5573		{
5574			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
5575		}
5576		else
5577		{
5578			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
5579		}
5580	}
5581
5582	return STOP;
5583}
5584
5585/** Reference data. */
5586const glw::GLubyte CopyTest::s_texture_data[] = {
5587	0x00, 0x00, 0x00, 0xFF, 0x7f, 0x7f, 0x7f, 0x00, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0x00,
5588	0x88, 0x00, 0x15, 0xFF, 0xed, 0x1c, 0x24, 0x00, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x00, 0x00,
5589	0xc8, 0xbf, 0xe7, 0xFF, 0x70, 0x92, 0xbe, 0x00, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0x00,
5590	0xa3, 0x49, 0xa4, 0xFF, 0x3f, 0x48, 0xcc, 0x00, 0x00, 0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0x00,
5591
5592	0xa3, 0x49, 0xa4, 0xFF, 0xc8, 0xbf, 0xe7, 0x00, 0x88, 0x00, 0x15, 0xff, 0x00, 0x00, 0x00, 0x00,
5593	0x3f, 0x48, 0xcc, 0xFF, 0x70, 0x92, 0xbe, 0x00, 0xed, 0x1c, 0x24, 0xff, 0x7f, 0x7f, 0x7f, 0x00,
5594	0x00, 0xa2, 0xe8, 0xFF, 0x99, 0xd9, 0xea, 0x00, 0xff, 0x7f, 0x27, 0xff, 0xc3, 0xc3, 0xc3, 0x00,
5595	0x22, 0xb1, 0x4c, 0xFF, 0xb5, 0xe6, 0x1d, 0x00, 0xff, 0xf2, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
5596
5597	0x22, 0xb1, 0x4c, 0xFF, 0x00, 0xa2, 0xe8, 0x00, 0x3f, 0x48, 0xcc, 0xff, 0xa3, 0x49, 0xa4, 0x00,
5598	0xb5, 0xe6, 0x1d, 0xFF, 0x99, 0xd9, 0xea, 0x00, 0x70, 0x92, 0xbe, 0xff, 0xc8, 0xbf, 0xe7, 0x00,
5599	0xff, 0xf2, 0x00, 0xFF, 0xff, 0x7f, 0x27, 0x00, 0xed, 0x1c, 0x24, 0xff, 0x88, 0x00, 0x15, 0x00,
5600	0xff, 0xff, 0xff, 0xFF, 0xc3, 0xc3, 0xc3, 0x00, 0x7f, 0x7f, 0x7f, 0xff, 0x00, 0x00, 0x00, 0x00,
5601
5602	0xff, 0xff, 0xff, 0xFF, 0xff, 0xf2, 0x00, 0x00, 0xb5, 0xe6, 0x1d, 0xff, 0x22, 0xb1, 0x4c, 0x00,
5603	0xc3, 0xc3, 0xc3, 0xFF, 0xff, 0x7f, 0x27, 0x00, 0x99, 0xd9, 0xea, 0xff, 0x00, 0xa2, 0xe8, 0x00,
5604	0x7f, 0x7f, 0x7f, 0xFF, 0xed, 0x1c, 0x24, 0x00, 0x70, 0x92, 0xbe, 0xff, 0x3f, 0x48, 0xcc, 0x00,
5605	0x00, 0x00, 0x00, 0xFF, 0x88, 0x00, 0x15, 0x00, 0xc8, 0xbf, 0xe7, 0xff, 0xa3, 0x49, 0xa4, 0x00
5606};
5607
5608/** Reference data parameters. */
5609const glw::GLuint CopyTest::s_texture_width  = 4;
5610const glw::GLuint CopyTest::s_texture_height = 4;
5611const glw::GLuint CopyTest::s_texture_depth  = 4;
5612
5613/******************************** Get Set Parameter Test Implementation   ********************************/
5614
5615/** @brief Get Set Parameter Test constructor.
5616 *
5617 *  @param [in] context     OpenGL context.
5618 */
5619GetSetParameterTest::GetSetParameterTest(deqp::Context& context)
5620	: deqp::TestCase(context, "textures_get_set_parameter", "Texture Get Set Parameter Test")
5621{
5622	/* Intentionally left blank. */
5623}
5624
5625/** @brief Iterate Get Set Parameter Test cases.
5626 *
5627 *  @return Iteration result.
5628 */
5629tcu::TestNode::IterateResult GetSetParameterTest::iterate()
5630{
5631	/* Shortcut for GL functionality. */
5632	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5633
5634	/* Get context setup. */
5635	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
5636	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
5637
5638	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
5639	{
5640		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
5641
5642		return STOP;
5643	}
5644
5645	/* Running tests. */
5646	bool is_ok	= true;
5647	bool is_error = false;
5648
5649	/* Texture. */
5650	glw::GLuint texture = 0;
5651
5652	try
5653	{
5654		gl.genTextures(1, &texture);
5655		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
5656
5657		gl.bindTexture(GL_TEXTURE_3D, texture);
5658		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
5659
5660		{
5661			glw::GLenum name	  = GL_DEPTH_STENCIL_TEXTURE_MODE;
5662			glw::GLint  value_src = GL_DEPTH_COMPONENT;
5663			glw::GLint  value_dst = 0;
5664
5665			gl.textureParameteri(texture, name, value_src);
5666			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
5667
5668			gl.getTextureParameteriv(texture, name, &value_dst);
5669			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
5670
5671			is_ok &= CompareAndLog(value_src, value_dst, name);
5672		}
5673
5674		{
5675			glw::GLenum name	  = GL_TEXTURE_BASE_LEVEL;
5676			glw::GLint  value_src = 2;
5677			glw::GLint  value_dst = 0;
5678
5679			gl.textureParameteri(texture, name, value_src);
5680			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
5681
5682			gl.getTextureParameteriv(texture, name, &value_dst);
5683			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
5684
5685			is_ok &= CompareAndLog(value_src, value_dst, name);
5686		}
5687
5688		{
5689			glw::GLenum  name		  = GL_TEXTURE_BORDER_COLOR;
5690			glw::GLfloat value_src[4] = { 0.25, 0.5, 0.75, 1.0 };
5691			glw::GLfloat value_dst[4] = {};
5692
5693			gl.textureParameterfv(texture, name, value_src);
5694			is_ok &= CheckErrorAndLog("glTextureParameterfv", name);
5695
5696			gl.getTextureParameterfv(texture, name, value_dst);
5697			is_ok &= CheckErrorAndLog("glGetTextureParameterfv", name);
5698
5699			is_ok &= CompareAndLog(value_src, value_dst, name);
5700		}
5701
5702		{
5703			glw::GLenum name		 = GL_TEXTURE_BORDER_COLOR;
5704			glw::GLint  value_src[4] = { 0, 64, -64, -32 };
5705			glw::GLint  value_dst[4] = {};
5706
5707			gl.textureParameterIiv(texture, name, value_src);
5708			is_ok &= CheckErrorAndLog("glTextureParameterIiv", name);
5709
5710			gl.getTextureParameterIiv(texture, name, value_dst);
5711			is_ok &= CheckErrorAndLog("glGetTextureParameterIiv", name);
5712
5713			is_ok &= CompareAndLog(value_src, value_dst, name);
5714		}
5715
5716		{
5717			glw::GLenum name		 = GL_TEXTURE_BORDER_COLOR;
5718			glw::GLuint value_src[4] = { 0, 64, 128, 192 };
5719			glw::GLuint value_dst[4] = {};
5720
5721			gl.textureParameterIuiv(texture, name, value_src);
5722			is_ok &= CheckErrorAndLog("glTextureParameterIuiv", name);
5723
5724			gl.getTextureParameterIuiv(texture, name, value_dst);
5725			is_ok &= CheckErrorAndLog("glGetTextureParameterIuiv", name);
5726
5727			is_ok &= CompareAndLog(value_src, value_dst, name);
5728		}
5729
5730		{
5731			glw::GLenum name	  = GL_TEXTURE_COMPARE_FUNC;
5732			glw::GLint  value_src = GL_LEQUAL;
5733			glw::GLint  value_dst = 0;
5734
5735			gl.textureParameteri(texture, name, value_src);
5736			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
5737
5738			gl.getTextureParameteriv(texture, name, &value_dst);
5739			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
5740
5741			is_ok &= CompareAndLog(value_src, value_dst, name);
5742		}
5743
5744		{
5745			glw::GLenum name	  = GL_TEXTURE_COMPARE_MODE;
5746			glw::GLint  value_src = GL_COMPARE_REF_TO_TEXTURE;
5747			glw::GLint  value_dst = 0;
5748
5749			gl.textureParameteri(texture, name, value_src);
5750			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
5751
5752			gl.getTextureParameteriv(texture, name, &value_dst);
5753			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
5754
5755			is_ok &= CompareAndLog(value_src, value_dst, name);
5756		}
5757
5758		{
5759			glw::GLenum  name	  = GL_TEXTURE_LOD_BIAS;
5760			glw::GLfloat value_src = -2.f;
5761			glw::GLfloat value_dst = 0.f;
5762
5763			gl.textureParameterf(texture, name, value_src);
5764			is_ok &= CheckErrorAndLog("glTextureParameterf", name);
5765
5766			gl.getTextureParameterfv(texture, name, &value_dst);
5767			is_ok &= CheckErrorAndLog("glGetTextureParameterfv", name);
5768
5769			is_ok &= CompareAndLog(value_src, value_dst, name);
5770		}
5771
5772		{
5773			glw::GLenum name	  = GL_TEXTURE_MIN_FILTER;
5774			glw::GLint  value_src = GL_LINEAR_MIPMAP_NEAREST;
5775			glw::GLint  value_dst = 0;
5776
5777			gl.textureParameteri(texture, name, value_src);
5778			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
5779
5780			gl.getTextureParameteriv(texture, name, &value_dst);
5781			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
5782
5783			is_ok &= CompareAndLog(value_src, value_dst, name);
5784		}
5785
5786		{
5787			glw::GLenum name	  = GL_TEXTURE_MAG_FILTER;
5788			glw::GLint  value_src = GL_NEAREST;
5789			glw::GLint  value_dst = 0;
5790
5791			gl.textureParameteri(texture, name, value_src);
5792			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
5793
5794			gl.getTextureParameteriv(texture, name, &value_dst);
5795			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
5796
5797			is_ok &= CompareAndLog(value_src, value_dst, name);
5798		}
5799
5800		{
5801			glw::GLenum name	  = GL_TEXTURE_MIN_LOD;
5802			glw::GLint  value_src = -100;
5803			glw::GLint  value_dst = 0;
5804
5805			gl.textureParameteri(texture, name, value_src);
5806			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
5807
5808			gl.getTextureParameteriv(texture, name, &value_dst);
5809			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
5810
5811			is_ok &= CompareAndLog(value_src, value_dst, name);
5812		}
5813
5814		{
5815			glw::GLenum name	  = GL_TEXTURE_MAX_LOD;
5816			glw::GLint  value_src = 100;
5817			glw::GLint  value_dst = 0;
5818
5819			gl.textureParameteri(texture, name, value_src);
5820			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
5821
5822			gl.getTextureParameteriv(texture, name, &value_dst);
5823			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
5824
5825			is_ok &= CompareAndLog(value_src, value_dst, name);
5826		}
5827
5828		{
5829			glw::GLenum name	  = GL_TEXTURE_MAX_LEVEL;
5830			glw::GLint  value_src = 100;
5831			glw::GLint  value_dst = 0;
5832
5833			gl.textureParameteri(texture, name, value_src);
5834			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
5835
5836			gl.getTextureParameteriv(texture, name, &value_dst);
5837			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
5838
5839			is_ok &= CompareAndLog(value_src, value_dst, name);
5840		}
5841
5842		{
5843			glw::GLenum name	  = GL_TEXTURE_SWIZZLE_R;
5844			glw::GLint  value_src = GL_BLUE;
5845			glw::GLint  value_dst = 0;
5846
5847			gl.textureParameteri(texture, name, value_src);
5848			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
5849
5850			gl.getTextureParameteriv(texture, name, &value_dst);
5851			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
5852
5853			is_ok &= CompareAndLog(value_src, value_dst, name);
5854		}
5855
5856		{
5857			glw::GLenum name	  = GL_TEXTURE_SWIZZLE_G;
5858			glw::GLint  value_src = GL_ALPHA;
5859			glw::GLint  value_dst = 0;
5860
5861			gl.textureParameteri(texture, name, value_src);
5862			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
5863
5864			gl.getTextureParameteriv(texture, name, &value_dst);
5865			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
5866
5867			is_ok &= CompareAndLog(value_src, value_dst, name);
5868		}
5869
5870		{
5871			glw::GLenum name	  = GL_TEXTURE_SWIZZLE_B;
5872			glw::GLint  value_src = GL_RED;
5873			glw::GLint  value_dst = 0;
5874
5875			gl.textureParameteri(texture, name, value_src);
5876			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
5877
5878			gl.getTextureParameteriv(texture, name, &value_dst);
5879			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
5880
5881			is_ok &= CompareAndLog(value_src, value_dst, name);
5882		}
5883
5884		{
5885			glw::GLenum name	  = GL_TEXTURE_SWIZZLE_A;
5886			glw::GLint  value_src = GL_GREEN;
5887			glw::GLint  value_dst = 0;
5888
5889			gl.textureParameteri(texture, name, value_src);
5890			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
5891
5892			gl.getTextureParameteriv(texture, name, &value_dst);
5893			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
5894
5895			is_ok &= CompareAndLog(value_src, value_dst, name);
5896		}
5897
5898		{
5899			glw::GLenum name		 = GL_TEXTURE_SWIZZLE_RGBA;
5900			glw::GLint  value_src[4] = { GL_ZERO, GL_ONE, GL_ZERO, GL_ONE };
5901			glw::GLint  value_dst[4] = {};
5902
5903			gl.textureParameteriv(texture, name, value_src);
5904			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
5905
5906			gl.getTextureParameteriv(texture, name, value_dst);
5907			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
5908
5909			is_ok &= CompareAndLog(value_src, value_dst, name);
5910		}
5911
5912		{
5913			glw::GLenum name	  = GL_TEXTURE_WRAP_S;
5914			glw::GLint  value_src = GL_MIRROR_CLAMP_TO_EDGE;
5915			glw::GLint  value_dst = 11;
5916
5917			gl.textureParameteri(texture, name, value_src);
5918			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
5919
5920			gl.getTextureParameteriv(texture, name, &value_dst);
5921			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
5922
5923			is_ok &= CompareAndLog(value_src, value_dst, name);
5924		}
5925
5926		{
5927			glw::GLenum name	  = GL_TEXTURE_WRAP_T;
5928			glw::GLint  value_src = GL_CLAMP_TO_EDGE;
5929			glw::GLint  value_dst = 11;
5930
5931			gl.textureParameteri(texture, name, value_src);
5932			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
5933
5934			gl.getTextureParameteriv(texture, name, &value_dst);
5935			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
5936
5937			is_ok &= CompareAndLog(value_src, value_dst, name);
5938		}
5939
5940		{
5941			glw::GLenum name	  = GL_TEXTURE_WRAP_R;
5942			glw::GLint  value_src = GL_CLAMP_TO_EDGE;
5943			glw::GLint  value_dst = 11;
5944
5945			gl.textureParameteriv(texture, name, &value_src);
5946			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
5947
5948			gl.getTextureParameteriv(texture, name, &value_dst);
5949			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
5950
5951			is_ok &= CompareAndLog(value_src, value_dst, name);
5952		}
5953	}
5954	catch (...)
5955	{
5956		is_ok	= false;
5957		is_error = true;
5958	}
5959
5960	/* Cleanup. */
5961	if (texture)
5962	{
5963		gl.deleteTextures(1, &texture);
5964	}
5965
5966	while (GL_NO_ERROR != gl.getError())
5967		;
5968
5969	/* Result's setup. */
5970	if (is_ok)
5971	{
5972		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
5973	}
5974	else
5975	{
5976		if (is_error)
5977		{
5978			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
5979		}
5980		else
5981		{
5982			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
5983		}
5984	}
5985
5986	return STOP;
5987}
5988
5989/** @brief Check for errors and log.
5990 *
5991 *  @param [in] fname     Name of the function (to be logged).
5992 *  @param [in] pname     Parameter name with which function was called.
5993 *
5994 *  @return True if no error, false otherwise.
5995 */
5996bool GetSetParameterTest::CheckErrorAndLog(const glw::GLchar* fname, glw::GLenum pname)
5997{
5998	/* Shortcut for GL functionality. */
5999	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6000
6001	/* Check errors. */
6002	glw::GLenum error;
6003
6004	if (GL_NO_ERROR != (error = gl.getError()))
6005	{
6006		m_context.getTestContext().getLog() << tcu::TestLog::Message << fname << " unexpectedly generated error "
6007											<< glu::getErrorStr(error) << " during test of pname "
6008											<< glu::getTextureParameterStr(pname) << ". Test fails."
6009											<< tcu::TestLog::EndMessage;
6010
6011		return false;
6012	}
6013
6014	return true;
6015}
6016
6017/** @brief Compare queried value of parameter with the expected vale.
6018 *
6019 *  @param [in] value_src           First value.
6020 *  @param [in] value_dst           Second value.
6021 *  @param [in] pname               Parameter name.
6022 *
6023 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
6024 */
6025bool GetSetParameterTest::CompareAndLog(glw::GLint value_src, glw::GLint value_dst, glw::GLenum pname)
6026{
6027	if (value_src != value_dst)
6028	{
6029		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Queried value of pname "
6030											<< glu::getTextureParameterStr(pname) << " is equal to " << value_dst
6031											<< ", however " << value_src << " was expected. Test fails."
6032											<< tcu::TestLog::EndMessage;
6033
6034		return false;
6035	}
6036
6037	return true;
6038}
6039
6040/** @brief Compare queried value of parameter with the expected vale.
6041 *
6042 *  @param [in] value_src           First value.
6043 *  @param [in] value_dst           Second value.
6044 *  @param [in] pname               Parameter name.
6045 *
6046 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
6047 */
6048bool GetSetParameterTest::CompareAndLog(glw::GLuint value_src, glw::GLuint value_dst, glw::GLenum pname)
6049{
6050	if (value_src != value_dst)
6051	{
6052		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Queried value of pname "
6053											<< glu::getTextureParameterStr(pname) << " is equal to " << value_dst
6054											<< ", however " << value_src << " was expected. Test fails."
6055											<< tcu::TestLog::EndMessage;
6056
6057		return false;
6058	}
6059
6060	return true;
6061}
6062
6063/** @brief Compare queried value of parameter with the expected vale.
6064 *
6065 *  @param [in] value_src           First value.
6066 *  @param [in] value_dst           Second value.
6067 *  @param [in] pname               Parameter name.
6068 *
6069 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
6070 */
6071bool GetSetParameterTest::CompareAndLog(glw::GLfloat value_src, glw::GLfloat value_dst, glw::GLenum pname)
6072{
6073	if (de::abs(value_src - value_dst) > 0.0125 /* Precision */)
6074	{
6075		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Queried value of pname "
6076											<< glu::getTextureParameterStr(pname) << " is equal to " << value_dst
6077											<< ", however " << value_src << " was expected. Test fails."
6078											<< tcu::TestLog::EndMessage;
6079
6080		return false;
6081	}
6082
6083	return true;
6084}
6085
6086/** @brief Compare queried value of parameter with the expected vale.
6087 *
6088 *  @param [in] value_src           First value.
6089 *  @param [in] value_dst           Second value.
6090 *  @param [in] pname               Parameter name.
6091 *
6092 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
6093 */
6094bool GetSetParameterTest::CompareAndLog(glw::GLint value_src[4], glw::GLint value_dst[4], glw::GLenum pname)
6095{
6096	if ((value_src[0] != value_dst[0]) || (value_src[1] != value_dst[1]) || (value_src[2] != value_dst[2]) ||
6097		(value_src[3] != value_dst[3]))
6098	{
6099		m_context.getTestContext().getLog()
6100			<< tcu::TestLog::Message << "Queried value of pname " << glu::getTextureParameterStr(pname)
6101			<< " is equal to [" << value_dst[0] << ", " << value_dst[1] << ", " << value_dst[2] << ", " << value_dst[3]
6102			<< "], however " << value_src[0] << ", " << value_src[1] << ", " << value_src[2] << ", " << value_src[3]
6103			<< "] was expected. Test fails." << tcu::TestLog::EndMessage;
6104
6105		return false;
6106	}
6107
6108	return true;
6109}
6110
6111/** @brief Compare queried value of parameter with the expected vale.
6112 *
6113 *  @param [in] value_src           First value.
6114 *  @param [in] value_dst           Second value.
6115 *  @param [in] pname               Parameter name.
6116 *
6117 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
6118 */
6119bool GetSetParameterTest::CompareAndLog(glw::GLuint value_src[4], glw::GLuint value_dst[4], glw::GLenum pname)
6120{
6121	if ((value_src[0] != value_dst[0]) || (value_src[1] != value_dst[1]) || (value_src[2] != value_dst[2]) ||
6122		(value_src[3] != value_dst[3]))
6123	{
6124		m_context.getTestContext().getLog()
6125			<< tcu::TestLog::Message << "Queried value of pname " << glu::getTextureParameterStr(pname)
6126			<< " is equal to [" << value_dst[0] << ", " << value_dst[1] << ", " << value_dst[2] << ", " << value_dst[3]
6127			<< "], however " << value_src[0] << ", " << value_src[1] << ", " << value_src[2] << ", " << value_src[3]
6128			<< "] was expected. Test fails." << tcu::TestLog::EndMessage;
6129
6130		return false;
6131	}
6132
6133	return true;
6134}
6135
6136/** @brief Compare queried value of parameter with the expected vale.
6137 *
6138 *  @param [in] value_src           First value.
6139 *  @param [in] value_dst           Second value.
6140 *  @param [in] pname               Parameter name.
6141 *
6142 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
6143 */
6144bool GetSetParameterTest::CompareAndLog(glw::GLfloat value_src[4], glw::GLfloat value_dst[4], glw::GLenum pname)
6145{
6146	if ((de::abs(value_src[0] - value_dst[0]) > 0.0125 /* Precision */) ||
6147		(de::abs(value_src[1] - value_dst[1]) > 0.0125 /* Precision */) ||
6148		(de::abs(value_src[2] - value_dst[2]) > 0.0125 /* Precision */) ||
6149		(de::abs(value_src[3] - value_dst[3]) > 0.0125 /* Precision */))
6150	{
6151		m_context.getTestContext().getLog()
6152			<< tcu::TestLog::Message << "Queried value of pname " << glu::getTextureParameterStr(pname)
6153			<< " is equal to [" << value_dst[0] << ", " << value_dst[1] << ", " << value_dst[2] << ", " << value_dst[3]
6154			<< "], however " << value_src[0] << ", " << value_src[1] << ", " << value_src[2] << ", " << value_src[3]
6155			<< "] was expected. Test fails." << tcu::TestLog::EndMessage;
6156
6157		return false;
6158	}
6159
6160	return true;
6161}
6162
6163/******************************** Defaults Test Implementation   ********************************/
6164
6165/** @brief Defaults Test constructor.
6166 *
6167 *  @param [in] context     OpenGL context.
6168 */
6169DefaultsTest::DefaultsTest(deqp::Context& context)
6170	: deqp::TestCase(context, "textures_defaults", "Texture Defaults Test")
6171{
6172	/* Intentionally left blank. */
6173}
6174
6175/** @brief Defaults Test cases.
6176 *
6177 *  @return Iteration result.
6178 */
6179tcu::TestNode::IterateResult DefaultsTest::iterate()
6180{
6181	/* Shortcut for GL functionality. */
6182	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6183
6184	/* Get context setup. */
6185	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
6186	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
6187
6188	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
6189	{
6190		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
6191
6192		return STOP;
6193	}
6194
6195	/* Running tests. */
6196	bool is_ok	= true;
6197	bool is_error = false;
6198
6199	/* Texture. */
6200	glw::GLuint texture = 0;
6201
6202	try
6203	{
6204		gl.createTextures(GL_TEXTURE_3D, 1, &texture);
6205		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
6206
6207		{
6208			glw::GLenum name	  = GL_DEPTH_STENCIL_TEXTURE_MODE;
6209			glw::GLint  value_ref = GL_DEPTH_COMPONENT;
6210			glw::GLint  value_dst = 0;
6211
6212			gl.getTextureParameteriv(texture, name, &value_dst);
6213			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6214
6215			is_ok &= CompareAndLog(value_ref, value_dst, name);
6216		}
6217
6218		{
6219			glw::GLenum name	  = GL_TEXTURE_BASE_LEVEL;
6220			glw::GLint  value_ref = 0;
6221			glw::GLint  value_dst = 1;
6222
6223			gl.getTextureParameteriv(texture, name, &value_dst);
6224			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6225
6226			is_ok &= CompareAndLog(value_ref, value_dst, name);
6227		}
6228
6229		{
6230			glw::GLenum  name		  = GL_TEXTURE_BORDER_COLOR;
6231			glw::GLfloat value_ref[4] = { 0.f, 0.f, 0.f, 0.f };
6232			glw::GLfloat value_dst[4] = {};
6233
6234			gl.getTextureParameterfv(texture, name, value_dst);
6235			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6236
6237			is_ok &= CompareAndLog(value_ref, value_dst, name);
6238		}
6239
6240		{
6241			glw::GLenum name	  = GL_TEXTURE_COMPARE_FUNC;
6242			glw::GLint  value_ref = GL_LEQUAL;
6243			glw::GLint  value_dst = 0;
6244
6245			gl.getTextureParameteriv(texture, name, &value_dst);
6246			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6247
6248			is_ok &= CompareAndLog(value_ref, value_dst, name);
6249		}
6250
6251		{
6252			glw::GLenum name	  = GL_TEXTURE_COMPARE_MODE;
6253			glw::GLint  value_ref = GL_NONE;
6254			glw::GLint  value_dst = 0;
6255
6256			gl.getTextureParameteriv(texture, name, &value_dst);
6257			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6258
6259			is_ok &= CompareAndLog(value_ref, value_dst, name);
6260		}
6261
6262		{
6263			glw::GLenum  name	  = GL_TEXTURE_LOD_BIAS;
6264			glw::GLfloat value_ref = 0.f;
6265			glw::GLfloat value_dst = 0.f;
6266
6267			gl.getTextureParameterfv(texture, name, &value_dst);
6268			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6269
6270			is_ok &= CompareAndLog(value_ref, value_dst, name);
6271		}
6272
6273		{
6274			glw::GLenum name	  = GL_TEXTURE_MIN_FILTER;
6275			glw::GLint  value_ref = GL_NEAREST_MIPMAP_LINEAR;
6276			glw::GLint  value_dst = 0;
6277
6278			gl.getTextureParameteriv(texture, name, &value_dst);
6279			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6280
6281			is_ok &= CompareAndLog(value_ref, value_dst, name);
6282		}
6283
6284		{
6285			glw::GLenum name	  = GL_TEXTURE_MAG_FILTER;
6286			glw::GLint  value_ref = GL_LINEAR;
6287			glw::GLint  value_dst = 0;
6288
6289			gl.getTextureParameteriv(texture, name, &value_dst);
6290			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6291
6292			is_ok &= CompareAndLog(value_ref, value_dst, name);
6293		}
6294
6295		{
6296			glw::GLenum name	  = GL_TEXTURE_MIN_LOD;
6297			glw::GLint  value_ref = -1000;
6298			glw::GLint  value_dst = 0;
6299
6300			gl.getTextureParameteriv(texture, name, &value_dst);
6301			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6302
6303			is_ok &= CompareAndLog(value_ref, value_dst, name);
6304		}
6305
6306		{
6307			glw::GLenum name	  = GL_TEXTURE_MAX_LOD;
6308			glw::GLint  value_ref = 1000;
6309			glw::GLint  value_dst = 0;
6310
6311			gl.getTextureParameteriv(texture, name, &value_dst);
6312			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6313
6314			is_ok &= CompareAndLog(value_ref, value_dst, name);
6315		}
6316
6317		{
6318			glw::GLenum name	  = GL_TEXTURE_MAX_LEVEL;
6319			glw::GLint  value_ref = 1000;
6320			glw::GLint  value_dst = 0;
6321
6322			gl.getTextureParameteriv(texture, name, &value_dst);
6323			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6324
6325			is_ok &= CompareAndLog(value_ref, value_dst, name);
6326		}
6327
6328		{
6329			glw::GLenum name	  = GL_TEXTURE_SWIZZLE_R;
6330			glw::GLint  value_ref = GL_RED;
6331			glw::GLint  value_dst = 0;
6332
6333			gl.getTextureParameteriv(texture, name, &value_dst);
6334			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6335
6336			is_ok &= CompareAndLog(value_ref, value_dst, name);
6337		}
6338
6339		{
6340			glw::GLenum name	  = GL_TEXTURE_SWIZZLE_G;
6341			glw::GLint  value_ref = GL_GREEN;
6342			glw::GLint  value_dst = 0;
6343
6344			gl.getTextureParameteriv(texture, name, &value_dst);
6345			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6346
6347			is_ok &= CompareAndLog(value_ref, value_dst, name);
6348		}
6349
6350		{
6351			glw::GLenum name	  = GL_TEXTURE_SWIZZLE_B;
6352			glw::GLint  value_ref = GL_BLUE;
6353			glw::GLint  value_dst = 0;
6354
6355			gl.getTextureParameteriv(texture, name, &value_dst);
6356			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6357
6358			is_ok &= CompareAndLog(value_ref, value_dst, name);
6359		}
6360
6361		{
6362			glw::GLenum name	  = GL_TEXTURE_SWIZZLE_A;
6363			glw::GLint  value_ref = GL_ALPHA;
6364			glw::GLint  value_dst = 0;
6365
6366			gl.getTextureParameteriv(texture, name, &value_dst);
6367			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6368
6369			is_ok &= CompareAndLog(value_ref, value_dst, name);
6370		}
6371
6372		{
6373			glw::GLenum name	  = GL_TEXTURE_WRAP_S;
6374			glw::GLint  value_ref = GL_REPEAT;
6375			glw::GLint  value_dst = 11;
6376
6377			gl.getTextureParameteriv(texture, name, &value_dst);
6378			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6379
6380			is_ok &= CompareAndLog(value_ref, value_dst, name);
6381		}
6382
6383		{
6384			glw::GLenum name	  = GL_TEXTURE_WRAP_T;
6385			glw::GLint  value_ref = GL_REPEAT;
6386			glw::GLint  value_dst = 11;
6387
6388			gl.getTextureParameteriv(texture, name, &value_dst);
6389			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6390
6391			is_ok &= CompareAndLog(value_ref, value_dst, name);
6392		}
6393
6394		{
6395			glw::GLenum name	  = GL_TEXTURE_WRAP_R;
6396			glw::GLint  value_ref = GL_REPEAT;
6397			glw::GLint  value_dst = 11;
6398
6399			gl.getTextureParameteriv(texture, name, &value_dst);
6400			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6401
6402			is_ok &= CompareAndLog(value_ref, value_dst, name);
6403		}
6404	}
6405	catch (...)
6406	{
6407		is_ok	= false;
6408		is_error = true;
6409	}
6410
6411	/* Cleanup. */
6412	if (texture)
6413	{
6414		gl.deleteTextures(1, &texture);
6415	}
6416
6417	while (GL_NO_ERROR != gl.getError())
6418		;
6419
6420	/* Result's setup. */
6421	if (is_ok)
6422	{
6423		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
6424	}
6425	else
6426	{
6427		if (is_error)
6428		{
6429			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
6430		}
6431		else
6432		{
6433			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
6434		}
6435	}
6436
6437	return STOP;
6438}
6439
6440/** @brief Compare queried value of parameter with the expected vale.
6441 *
6442 *  @param [in] value_src           First value.
6443 *  @param [in] value_dst           Second value.
6444 *  @param [in] pname               Parameter name.
6445 *
6446 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
6447 */
6448bool DefaultsTest::CompareAndLog(glw::GLint value_ref, glw::GLint value_dst, glw::GLenum pname)
6449{
6450	if (value_ref != value_dst)
6451	{
6452		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Queried value of pname "
6453											<< glu::getTextureParameterStr(pname) << " is equal to " << value_dst
6454											<< ", however " << value_ref << " was expected. Test fails."
6455											<< tcu::TestLog::EndMessage;
6456
6457		return false;
6458	}
6459
6460	return true;
6461}
6462
6463/** @brief Compare queried value of parameter with the expected vale.
6464 *
6465 *  @param [in] value_src           First value.
6466 *  @param [in] value_dst           Second value.
6467 *  @param [in] pname               Parameter name.
6468 *
6469 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
6470 */
6471bool DefaultsTest::CompareAndLog(glw::GLuint value_ref, glw::GLuint value_dst, glw::GLenum pname)
6472{
6473	if (value_ref != value_dst)
6474	{
6475		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Queried value of pname "
6476											<< glu::getTextureParameterStr(pname) << " is equal to " << value_dst
6477											<< ", however " << value_ref << " was expected. Test fails."
6478											<< tcu::TestLog::EndMessage;
6479
6480		return false;
6481	}
6482
6483	return true;
6484}
6485
6486/** @brief Compare queried value of parameter with the expected vale.
6487 *
6488 *  @param [in] value_src           First value.
6489 *  @param [in] value_dst           Second value.
6490 *  @param [in] pname               Parameter name.
6491 *
6492 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
6493 */
6494bool DefaultsTest::CompareAndLog(glw::GLfloat value_ref, glw::GLfloat value_dst, glw::GLenum pname)
6495{
6496	if (de::abs(value_ref - value_dst) > 0.0125 /* Precision */)
6497	{
6498		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Queried value of pname "
6499											<< glu::getTextureParameterStr(pname) << " is equal to " << value_dst
6500											<< ", however " << value_ref << " was expected. Test fails."
6501											<< tcu::TestLog::EndMessage;
6502
6503		return false;
6504	}
6505
6506	return true;
6507}
6508
6509/** @brief Compare queried value of parameter with the expected vale.
6510 *
6511 *  @param [in] value_src           First value.
6512 *  @param [in] value_dst           Second value.
6513 *  @param [in] pname               Parameter name.
6514 *
6515 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
6516 */
6517bool DefaultsTest::CompareAndLog(glw::GLint value_ref[4], glw::GLint value_dst[4], glw::GLenum pname)
6518{
6519	if ((value_ref[0] != value_dst[0]) || (value_ref[1] != value_dst[1]) || (value_ref[2] != value_dst[2]) ||
6520		(value_ref[3] != value_dst[3]))
6521	{
6522		m_context.getTestContext().getLog()
6523			<< tcu::TestLog::Message << "Queried value of pname " << glu::getTextureParameterStr(pname)
6524			<< " is equal to [" << value_dst[0] << ", " << value_dst[1] << ", " << value_dst[2] << ", " << value_dst[3]
6525			<< "], however " << value_ref[0] << ", " << value_ref[1] << ", " << value_ref[2] << ", " << value_ref[3]
6526			<< "] was expected. Test fails." << tcu::TestLog::EndMessage;
6527
6528		return false;
6529	}
6530
6531	return true;
6532}
6533
6534/** @brief Compare queried value of parameter with the expected vale.
6535 *
6536 *  @param [in] value_src           First value.
6537 *  @param [in] value_dst           Second value.
6538 *  @param [in] pname               Parameter name.
6539 *
6540 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
6541 */
6542bool DefaultsTest::CompareAndLog(glw::GLuint value_ref[4], glw::GLuint value_dst[4], glw::GLenum pname)
6543{
6544	if ((value_ref[0] != value_dst[0]) || (value_ref[1] != value_dst[1]) || (value_ref[2] != value_dst[2]) ||
6545		(value_ref[3] != value_dst[3]))
6546	{
6547		m_context.getTestContext().getLog()
6548			<< tcu::TestLog::Message << "Queried value of pname " << glu::getTextureParameterStr(pname)
6549			<< " is equal to [" << value_dst[0] << ", " << value_dst[1] << ", " << value_dst[2] << ", " << value_dst[3]
6550			<< "], however " << value_ref[0] << ", " << value_ref[1] << ", " << value_ref[2] << ", " << value_ref[3]
6551			<< "] was expected. Test fails." << tcu::TestLog::EndMessage;
6552
6553		return false;
6554	}
6555
6556	return true;
6557}
6558
6559/** @brief Compare queried value of parameter with the expected vale.
6560 *
6561 *  @param [in] value_src           First value.
6562 *  @param [in] value_dst           Second value.
6563 *  @param [in] pname               Parameter name.
6564 *
6565 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
6566 */
6567bool DefaultsTest::CompareAndLog(glw::GLfloat value_ref[4], glw::GLfloat value_dst[4], glw::GLenum pname)
6568{
6569	if ((de::abs(value_ref[0] - value_dst[0]) > 0.0125 /* Precision */) ||
6570		(de::abs(value_ref[1] - value_dst[1]) > 0.0125 /* Precision */) ||
6571		(de::abs(value_ref[2] - value_dst[2]) > 0.0125 /* Precision */) ||
6572		(de::abs(value_ref[3] - value_dst[3]) > 0.0125 /* Precision */))
6573	{
6574		m_context.getTestContext().getLog()
6575			<< tcu::TestLog::Message << "Queried value of pname " << glu::getTextureParameterStr(pname)
6576			<< " is equal to [" << value_dst[0] << ", " << value_dst[1] << ", " << value_dst[2] << ", " << value_dst[3]
6577			<< "], however " << value_ref[0] << ", " << value_ref[1] << ", " << value_ref[2] << ", " << value_ref[3]
6578			<< "] was expected. Test fails." << tcu::TestLog::EndMessage;
6579
6580		return false;
6581	}
6582
6583	return true;
6584}
6585
6586/******************************** Generate Mipmap Test Implementation   ********************************/
6587
6588/** @brief Generate Mipmap Test constructor.
6589 *
6590 *  @param [in] context     OpenGL context.
6591 */
6592GenerateMipmapTest::GenerateMipmapTest(deqp::Context& context)
6593	: deqp::TestCase(context, "textures_generate_mipmaps", "Textures Generate Mipmap Test")
6594{
6595	/* Intentionally left blank. */
6596}
6597
6598/** @brief Generate Mipmap Test cases.
6599 *
6600 *  @return Iteration result.
6601 */
6602tcu::TestNode::IterateResult GenerateMipmapTest::iterate()
6603{
6604	/* Shortcut for GL functionality. */
6605	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6606
6607	/* Get context setup. */
6608	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
6609	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
6610
6611	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
6612	{
6613		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
6614
6615		return STOP;
6616	}
6617
6618	/* Running tests. */
6619	bool is_ok	= true;
6620	bool is_error = false;
6621
6622	/* Texture and cpu results storage. */
6623	glw::GLuint   texture = 0;
6624	glw::GLubyte* result  = DE_NULL;
6625
6626	try
6627	{
6628		/* Prepare texture. */
6629		gl.genTextures(1, &texture);
6630		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
6631
6632		gl.bindTexture(GL_TEXTURE_1D, texture);
6633		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
6634
6635		gl.texImage1D(GL_TEXTURE_1D, 0, GL_R8, s_texture_width, 0, GL_RED, GL_UNSIGNED_BYTE, s_texture_data);
6636		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");
6637
6638		/* Generate mipmaps with tested function. */
6639		gl.generateTextureMipmap(texture);
6640
6641		glw::GLenum error = GL_NO_ERROR;
6642
6643		if (GL_NO_ERROR != (error = gl.getError()))
6644		{
6645			m_context.getTestContext().getLog()
6646				<< tcu::TestLog::Message << "GenerateTextureMipmap unexpectedly generated error "
6647				<< glu::getErrorStr(error) << ". Test fails." << tcu::TestLog::EndMessage;
6648
6649			is_ok = false;
6650		}
6651
6652		/* Continue only if mipmaps has been generated. */
6653		if (is_ok)
6654		{
6655			result = new glw::GLubyte[s_texture_width];
6656
6657			if (DE_NULL == result)
6658			{
6659				throw 0;
6660			}
6661
6662			/* For each mipmap. */
6663			for (glw::GLuint i = 0, j = s_texture_width;
6664				 i < s_texture_width_log - 1 /* Do not test single pixel mipmap. */; ++i, j /= 2)
6665			{
6666				/* Check mipmap size. */
6667				glw::GLint mipmap_size = 0;
6668
6669				gl.getTexLevelParameteriv(GL_TEXTURE_1D, i, GL_TEXTURE_WIDTH, &mipmap_size);
6670				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
6671
6672				if (mipmap_size != (glw::GLint)j)
6673				{
6674					m_context.getTestContext().getLog()
6675						<< tcu::TestLog::Message
6676						<< "GenerateTextureMipmap unexpectedly generated mipmap with improper size. Mipmap size is "
6677						<< mipmap_size << ", but " << j << " was expected. Test fails." << tcu::TestLog::EndMessage;
6678
6679					is_ok = false;
6680
6681					break;
6682				}
6683
6684				/* Fetch data. */
6685				gl.getTexImage(GL_TEXTURE_1D, i, GL_RED, GL_UNSIGNED_BYTE, result);
6686				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexImage has failed");
6687
6688				/* Make comparison. */
6689				for (glw::GLuint k = 0; k < j - 1; ++k)
6690				{
6691					if (((glw::GLint)result[k + 1]) - ((glw::GLint)result[k]) < 0)
6692					{
6693						m_context.getTestContext().getLog() << tcu::TestLog::Message
6694															<< "GenerateTextureMipmap unexpectedly generated improper "
6695															   "mipmap (not descending). Test fails."
6696															<< tcu::TestLog::EndMessage;
6697
6698						is_ok = false;
6699
6700						break;
6701					}
6702				}
6703			}
6704		}
6705	}
6706	catch (...)
6707	{
6708		is_ok	= false;
6709		is_error = true;
6710	}
6711
6712	/* Cleanup. */
6713	if (texture)
6714	{
6715		gl.deleteTextures(1, &texture);
6716	}
6717
6718	if (DE_NULL != result)
6719	{
6720		delete[] result;
6721	}
6722
6723	while (GL_NO_ERROR != gl.getError())
6724		;
6725
6726	/* Result's setup. */
6727	if (is_ok)
6728	{
6729		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
6730	}
6731	else
6732	{
6733		if (is_error)
6734		{
6735			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
6736		}
6737		else
6738		{
6739			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
6740		}
6741	}
6742
6743	return STOP;
6744}
6745
6746/** Reference data. */
6747const glw::GLubyte GenerateMipmapTest::s_texture_data[] = {
6748	0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,
6749	22,  23,  24,  25,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,
6750	44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,  64,  65,
6751	66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,  86,  87,
6752	88,  89,  90,  91,  92,  93,  94,  95,  96,  97,  98,  99,  100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
6753	110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131,
6754	132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153,
6755	154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
6756	176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197,
6757	198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
6758	220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241,
6759	242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
6760};
6761
6762/** Reference data parameters. */
6763const glw::GLuint GenerateMipmapTest::s_texture_width	 = 256;
6764const glw::GLuint GenerateMipmapTest::s_texture_width_log = 8;
6765
6766/******************************** Bind Unit Test Implementation   ********************************/
6767
6768/** @brief Bind Unit Test constructor.
6769 *
6770 *  @param [in] context     OpenGL context.
6771 */
6772BindUnitTest::BindUnitTest(deqp::Context& context)
6773	: deqp::TestCase(context, "textures_bind_unit", "Textures Bind Unit Test")
6774	, m_po(0)
6775	, m_fbo(0)
6776	, m_rbo(0)
6777	, m_vao(0)
6778	, m_result(DE_NULL)
6779{
6780	m_to[0] = 0;
6781	m_to[1] = 0;
6782	m_to[2] = 0;
6783	m_to[3] = 0;
6784}
6785
6786/** @brief Bind Unit Test cases.
6787 *
6788 *  @return Iteration result.
6789 */
6790tcu::TestNode::IterateResult BindUnitTest::iterate()
6791{
6792	/* Get context setup. */
6793	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
6794	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
6795
6796	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
6797	{
6798		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
6799
6800		return STOP;
6801	}
6802
6803	/* Running tests. */
6804	bool is_ok	= true;
6805	bool is_error = false;
6806
6807	try
6808	{
6809		CreateProgram();
6810		CreateTextures();
6811		CreateFrambuffer();
6812		CreateVertexArray();
6813		is_ok &= Draw();
6814		is_ok &= Check();
6815	}
6816	catch (...)
6817	{
6818		is_ok	= false;
6819		is_error = true;
6820	}
6821
6822	/* Cleanup. */
6823	CleanAll();
6824
6825	/* Result's setup. */
6826	if (is_ok)
6827	{
6828		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
6829	}
6830	else
6831	{
6832		if (is_error)
6833		{
6834			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
6835		}
6836		else
6837		{
6838			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
6839		}
6840	}
6841
6842	return STOP;
6843}
6844
6845/** @brief Create test program.
6846 */
6847void BindUnitTest::CreateProgram()
6848{
6849	/* Shortcut for GL functionality */
6850	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6851
6852	struct Shader
6853	{
6854		glw::GLchar const* source;
6855		glw::GLenum const  type;
6856		glw::GLuint		   id;
6857	} shader[] = { { s_vertex_shader, GL_VERTEX_SHADER, 0 }, { s_fragment_shader, GL_FRAGMENT_SHADER, 0 } };
6858
6859	glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);
6860
6861	try
6862	{
6863		/* Create program. */
6864		m_po = gl.createProgram();
6865		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");
6866
6867		/* Shader compilation. */
6868
6869		for (glw::GLuint i = 0; i < shader_count; ++i)
6870		{
6871			if (DE_NULL != shader[i].source)
6872			{
6873				shader[i].id = gl.createShader(shader[i].type);
6874
6875				GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");
6876
6877				gl.attachShader(m_po, shader[i].id);
6878
6879				GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");
6880
6881				gl.shaderSource(shader[i].id, 1, &shader[i].source, NULL);
6882
6883				GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");
6884
6885				gl.compileShader(shader[i].id);
6886
6887				GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");
6888
6889				glw::GLint status = GL_FALSE;
6890
6891				gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
6892				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
6893
6894				if (GL_FALSE == status)
6895				{
6896					glw::GLint log_size = 0;
6897					gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
6898					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
6899
6900					glw::GLchar* log_text = new glw::GLchar[log_size];
6901
6902					gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);
6903
6904					m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation has failed.\n"
6905														<< "Shader type: " << glu::getShaderTypeStr(shader[i].type)
6906														<< "\n"
6907														<< "Shader compilation error log:\n"
6908														<< log_text << "\n"
6909														<< "Shader source code:\n"
6910														<< shader[i].source << "\n"
6911														<< tcu::TestLog::EndMessage;
6912
6913					delete[] log_text;
6914
6915					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");
6916
6917					throw 0;
6918				}
6919			}
6920		}
6921
6922		/* Link. */
6923		gl.linkProgram(m_po);
6924
6925		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
6926
6927		glw::GLint status = GL_FALSE;
6928
6929		gl.getProgramiv(m_po, GL_LINK_STATUS, &status);
6930
6931		if (GL_TRUE == status)
6932		{
6933			for (glw::GLuint i = 0; i < shader_count; ++i)
6934			{
6935				if (shader[i].id)
6936				{
6937					gl.detachShader(m_po, shader[i].id);
6938
6939					GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
6940				}
6941			}
6942		}
6943		else
6944		{
6945			glw::GLint log_size = 0;
6946
6947			gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);
6948
6949			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");
6950
6951			glw::GLchar* log_text = new glw::GLchar[log_size];
6952
6953			gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);
6954
6955			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
6956												<< log_text << "\n"
6957												<< tcu::TestLog::EndMessage;
6958
6959			delete[] log_text;
6960
6961			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");
6962
6963			throw 0;
6964		}
6965	}
6966	catch (...)
6967	{
6968		if (m_po)
6969		{
6970			gl.deleteProgram(m_po);
6971
6972			m_po = 0;
6973		}
6974	}
6975
6976	for (glw::GLuint i = 0; i < shader_count; ++i)
6977	{
6978		if (0 != shader[i].id)
6979		{
6980			gl.deleteShader(shader[i].id);
6981
6982			shader[i].id = 0;
6983		}
6984	}
6985
6986	if (0 == m_po)
6987	{
6988		throw 0;
6989	}
6990}
6991
6992/** @brief Create texture.
6993 */
6994void BindUnitTest::CreateTextures()
6995{
6996	/* Shortcut for GL functionality. */
6997	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6998
6999	/* Prepare texture. */
7000	gl.genTextures(4, m_to);
7001	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
7002
7003	/* Setup pixel sotre modes.*/
7004	gl.pixelStorei(GL_UNPACK_ALIGNMENT, sizeof(glw::GLubyte));
7005	GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed");
7006
7007	gl.pixelStorei(GL_PACK_ALIGNMENT, sizeof(glw::GLubyte));
7008	GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed");
7009
7010	/* Red texture. */
7011	gl.bindTexture(GL_TEXTURE_2D, m_to[0]);
7012	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
7013
7014	gl.texImage2D(GL_TEXTURE_2D, 0, GL_R8, s_texture_width, s_texture_height, 0, GL_RED, GL_UNSIGNED_BYTE,
7015				  s_texture_data_r);
7016	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");
7017
7018	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7019	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7020	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri call failed.");
7021
7022	/* Green texture. */
7023	gl.bindTexture(GL_TEXTURE_2D, m_to[1]);
7024	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
7025
7026	gl.texImage2D(GL_TEXTURE_2D, 0, GL_R8, s_texture_width, s_texture_height, 0, GL_RED, GL_UNSIGNED_BYTE,
7027				  s_texture_data_g);
7028	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");
7029
7030	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7031	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7032	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri call failed.");
7033
7034	/* Blue texture. */
7035	gl.bindTexture(GL_TEXTURE_2D, m_to[2]);
7036	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
7037
7038	gl.texImage2D(GL_TEXTURE_2D, 0, GL_R8, s_texture_width, s_texture_height, 0, GL_RED, GL_UNSIGNED_BYTE,
7039				  s_texture_data_b);
7040	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");
7041
7042	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7043	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7044	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri call failed.");
7045
7046	/* Alpha texture. */
7047	gl.bindTexture(GL_TEXTURE_2D, m_to[3]);
7048	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
7049
7050	gl.texImage2D(GL_TEXTURE_2D, 0, GL_R8, s_texture_width, s_texture_height, 0, GL_RED, GL_UNSIGNED_BYTE,
7051				  s_texture_data_a);
7052	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");
7053
7054	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7055	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7056	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri call failed.");
7057}
7058
7059/** @brief Create framebuffer.
7060 */
7061void BindUnitTest::CreateFrambuffer()
7062{
7063	/* Shortcut for GL functionality. */
7064	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7065
7066	/* Prepare framebuffer. */
7067	gl.genFramebuffers(1, &m_fbo);
7068	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
7069
7070	gl.genRenderbuffers(1, &m_rbo);
7071	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
7072
7073	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
7074	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
7075
7076	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo);
7077	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
7078
7079	gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, s_texture_width, s_texture_height);
7080	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed.");
7081
7082	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo);
7083	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed.");
7084
7085	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
7086	{
7087		throw 0;
7088	}
7089
7090	gl.viewport(0, 0, s_texture_width, s_texture_height);
7091	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
7092
7093	/* Clear framebuffer's content. */
7094	gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f);
7095	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");
7096
7097	gl.clear(GL_COLOR_BUFFER_BIT);
7098	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed.");
7099}
7100
7101/** @brief Create vertex array object.
7102 */
7103void BindUnitTest::CreateVertexArray()
7104{
7105	/* Shortcut for GL functionality. */
7106	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7107
7108	gl.genVertexArrays(1, &m_vao);
7109	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call has failed.");
7110
7111	gl.bindVertexArray(m_vao);
7112	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call has failed.");
7113}
7114
7115bool BindUnitTest::Draw()
7116{
7117	/* Shortcut for GL functionality. */
7118	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7119
7120	/* Setup program. */
7121	gl.useProgram(m_po);
7122	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call has failed.");
7123
7124	/* Bind textures to proper units and setup program's samplers. */
7125	for (glw::GLuint i = 0; i < 4; ++i)
7126	{
7127		/* Tested binding funcion. */
7128		gl.bindTextureUnit(i, m_to[i]);
7129
7130		/* Check for errors. */
7131		glw::GLenum error = GL_NO_ERROR;
7132
7133		if (GL_NO_ERROR != (error = gl.getError()))
7134		{
7135			m_context.getTestContext().getLog()
7136				<< tcu::TestLog::Message << "BindTextureUnit unexpectedly generated error " << glu::getErrorStr(error)
7137				<< " when binding texture " << m_to[i] << " to texture unit " << i << ". Test fails."
7138				<< tcu::TestLog::EndMessage;
7139
7140			return false;
7141		}
7142
7143		/* Sampler setup. */
7144		gl.uniform1i(gl.getUniformLocation(m_po, s_fragment_shader_samplers[i]), i);
7145		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation or glUniform1i call has failed.");
7146	}
7147
7148	/* Draw call. */
7149	gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
7150	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call has failed.");
7151
7152	return true;
7153}
7154
7155/** @brief Compare results with reference.
7156 *
7157 *  @return True if equal, false otherwise.
7158 */
7159bool BindUnitTest::Check()
7160{
7161	/* Shortcut for GL functionality. */
7162	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7163
7164	/* Setup storage for results. */
7165	m_result = new glw::GLubyte[s_texture_count_rgba];
7166
7167	/* Setup pixel sotre modes.*/
7168	gl.pixelStorei(GL_UNPACK_ALIGNMENT, sizeof(glw::GLubyte));
7169	GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed");
7170
7171	gl.pixelStorei(GL_PACK_ALIGNMENT, sizeof(glw::GLubyte));
7172	GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed");
7173
7174	/* Query framebuffer's image. */
7175	gl.readPixels(0, 0, s_texture_width, s_texture_height, GL_RGBA, GL_UNSIGNED_BYTE, m_result);
7176	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call has failed.");
7177
7178	/* Compare values with reference. */
7179	for (glw::GLuint i = 0; i < s_texture_count_rgba; ++i)
7180	{
7181		if (s_texture_data_rgba[i] != m_result[i])
7182		{
7183			m_context.getTestContext().getLog()
7184				<< tcu::TestLog::Message << "Framebuffer data " << DataToString(s_texture_count_rgba, m_result)
7185				<< " does not match the reference values " << DataToString(s_texture_count_rgba, s_texture_data_rgba)
7186				<< "." << tcu::TestLog::EndMessage;
7187
7188			return false;
7189		}
7190	}
7191
7192	return true;
7193}
7194
7195/** @brief Clean GL objects, test variables and GL errors.
7196 */
7197void BindUnitTest::CleanAll()
7198{
7199	/* Shortcut for GL functionality. */
7200	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7201
7202	/* Release GL objects. */
7203	if (m_po)
7204	{
7205		gl.useProgram(0);
7206
7207		gl.deleteProgram(m_po);
7208
7209		m_po = 0;
7210	}
7211
7212	if (m_to[0] || m_to[1] || m_to[2] || m_to[3])
7213	{
7214		gl.deleteTextures(4, m_to);
7215
7216		m_to[0] = 0;
7217		m_to[1] = 0;
7218		m_to[2] = 0;
7219		m_to[3] = 0;
7220	}
7221
7222	if (m_fbo)
7223	{
7224		gl.deleteFramebuffers(1, &m_fbo);
7225
7226		m_fbo = 0;
7227	}
7228
7229	if (m_rbo)
7230	{
7231		gl.deleteRenderbuffers(1, &m_rbo);
7232
7233		m_rbo = 0;
7234	}
7235
7236	/* Release heap. */
7237	if (DE_NULL != m_result)
7238	{
7239		delete[] m_result;
7240	}
7241
7242	/* Erros clean-up. */
7243	while (GL_NO_ERROR != gl.getError())
7244		;
7245}
7246
7247/** @brief Convert raw data into string for logging purposes.
7248 *
7249 *  @param [in] count      Count of the data.
7250 *  @param [in] data       Raw data.
7251 *
7252 *  @return String representation of data.
7253 */
7254std::string BindUnitTest::DataToString(glw::GLuint count, const glw::GLubyte data[])
7255{
7256	std::string data_str = "[";
7257
7258	for (glw::GLuint i = 0; i < count; ++i)
7259	{
7260		std::stringstream int_sstream;
7261
7262		int_sstream << unsigned(data[i]);
7263
7264		data_str.append(int_sstream.str());
7265
7266		if (i + 1 < count)
7267		{
7268			data_str.append(", ");
7269		}
7270		else
7271		{
7272			data_str.append("]");
7273		}
7274	}
7275
7276	return data_str;
7277}
7278
7279/** Reference data and parameters. */
7280const glw::GLubyte BindUnitTest::s_texture_data_r[]	= { 0, 4, 8, 12, 16, 20 };
7281const glw::GLubyte BindUnitTest::s_texture_data_g[]	= { 1, 5, 9, 13, 17, 21 };
7282const glw::GLubyte BindUnitTest::s_texture_data_b[]	= { 2, 6, 10, 14, 18, 22 };
7283const glw::GLubyte BindUnitTest::s_texture_data_a[]	= { 3, 7, 11, 15, 19, 23 };
7284const glw::GLubyte BindUnitTest::s_texture_data_rgba[] = { 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11,
7285														   12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 };
7286const glw::GLuint BindUnitTest::s_texture_width		 = 2;
7287const glw::GLuint BindUnitTest::s_texture_height	 = 3;
7288const glw::GLuint BindUnitTest::s_texture_count_rgba = sizeof(s_texture_data_rgba) / sizeof(s_texture_data_rgba[0]);
7289
7290/* Vertex shader source code. */
7291const glw::GLchar* BindUnitTest::s_vertex_shader = "#version 450\n"
7292												   "\n"
7293												   "void main()\n"
7294												   "{\n"
7295												   "    switch(gl_VertexID)\n"
7296												   "    {\n"
7297												   "        case 0:\n"
7298												   "            gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
7299												   "            break;\n"
7300												   "        case 1:\n"
7301												   "            gl_Position = vec4( 1.0, 1.0, 0.0, 1.0);\n"
7302												   "            break;\n"
7303												   "        case 2:\n"
7304												   "            gl_Position = vec4(-1.0,-1.0, 0.0, 1.0);\n"
7305												   "            break;\n"
7306												   "        case 3:\n"
7307												   "            gl_Position = vec4( 1.0,-1.0, 0.0, 1.0);\n"
7308												   "            break;\n"
7309												   "    }\n"
7310												   "}\n";
7311
7312/* Fragment shader source program. */
7313const glw::GLchar* BindUnitTest::s_fragment_shader =
7314	"#version 450\n"
7315	"\n"
7316	"layout(pixel_center_integer) in vec4 gl_FragCoord;\n"
7317	"\n"
7318	"uniform sampler2D texture_input_r;\n"
7319	"uniform sampler2D texture_input_g;\n"
7320	"uniform sampler2D texture_input_b;\n"
7321	"uniform sampler2D texture_input_a;\n"
7322	"\n"
7323	"out     vec4      color_output;\n"
7324	"\n"
7325	"void main()\n"
7326	"{\n"
7327	"    color_output = vec4(texelFetch(texture_input_r, ivec2(gl_FragCoord.xy), 0).r,\n"
7328	"                        texelFetch(texture_input_g, ivec2(gl_FragCoord.xy), 0).r,\n"
7329	"                        texelFetch(texture_input_b, ivec2(gl_FragCoord.xy), 0).r,\n"
7330	"                        texelFetch(texture_input_a, ivec2(gl_FragCoord.xy), 0).r);\n"
7331	"}\n";
7332
7333const glw::GLchar* BindUnitTest::s_fragment_shader_samplers[4] = { "texture_input_r", "texture_input_g",
7334																   "texture_input_b", "texture_input_a" };
7335
7336/******************************** Get Image Test Implementation   ********************************/
7337
7338/** @brief Get Image Test constructor.
7339 *
7340 *  @param [in] context     OpenGL context.
7341 */
7342GetImageTest::GetImageTest(deqp::Context& context)
7343	: deqp::TestCase(context, "textures_get_image", "Textures Get Image Test")
7344{
7345	/* Intentionally left blank */
7346}
7347
7348/** Reference data. */
7349const glw::GLubyte GetImageTest::s_texture_data[] = { 0x0,  0x0,  0x0,  0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3,
7350													  0xff, 0xff, 0xff, 0xff, 0xff, 0x88, 0x0,  0x15, 0xff, 0xed, 0x1c,
7351													  0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0,  0xff, 0xc8,
7352													  0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff,
7353													  0xb5, 0xe6, 0x1d, 0xff, 0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc,
7354													  0xff, 0x0,  0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff };
7355
7356/** Reference data (compressed). */
7357const glw::GLubyte GetImageTest::s_texture_data_compressed[] = { 0x90, 0x2b, 0x8f, 0x0f, 0xfe, 0x0f, 0x98, 0x99,
7358																 0x99, 0x99, 0x59, 0x8f, 0x8c, 0xa6, 0xb7, 0x71 };
7359
7360/** Reference data parameters. */
7361const glw::GLuint GetImageTest::s_texture_width			  = 4;
7362const glw::GLuint GetImageTest::s_texture_height		  = 4;
7363const glw::GLuint GetImageTest::s_texture_size			  = sizeof(s_texture_data);
7364const glw::GLuint GetImageTest::s_texture_size_compressed = sizeof(s_texture_data_compressed);
7365const glw::GLuint GetImageTest::s_texture_count			  = s_texture_size / sizeof(s_texture_data[0]);
7366const glw::GLuint GetImageTest::s_texture_count_compressed =
7367	s_texture_size_compressed / sizeof(s_texture_data_compressed[0]);
7368
7369/** @brief Get Image Test cases.
7370 *
7371 *  @return Iteration result.
7372 */
7373tcu::TestNode::IterateResult GetImageTest::iterate()
7374{
7375	/* Shortcut for GL functionality. */
7376	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7377
7378	/* Get context setup. */
7379	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
7380	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
7381
7382	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
7383	{
7384		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
7385
7386		return STOP;
7387	}
7388
7389	/* Running tests. */
7390	bool is_ok	= true;
7391	bool is_error = false;
7392
7393	/* Objects. */
7394	glw::GLuint  texture									   = 0;
7395	glw::GLubyte result[s_texture_count]					   = {};
7396	glw::GLubyte result_compressed[s_texture_count_compressed] = {};
7397
7398	try
7399	{
7400		/* Uncompressed case. */
7401		{
7402			/* Texture initiation. */
7403			gl.genTextures(1, &texture);
7404			GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
7405
7406			gl.bindTexture(GL_TEXTURE_2D, texture);
7407			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
7408
7409			gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, s_texture_width, s_texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7410						  s_texture_data);
7411			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");
7412
7413			/* Quering image with tested function. */
7414			gl.getTextureImage(texture, 0, GL_RGBA, GL_UNSIGNED_BYTE, sizeof(result), result);
7415
7416			/* Check for errors. */
7417			glw::GLenum error = GL_NO_ERROR;
7418
7419			if (GL_NO_ERROR != (error = gl.getError()))
7420			{
7421				m_context.getTestContext().getLog()
7422					<< tcu::TestLog::Message << "GetTextureImage unexpectedly generated error "
7423					<< glu::getErrorStr(error) << ". Test fails." << tcu::TestLog::EndMessage;
7424
7425				is_ok = false;
7426			}
7427			else
7428			{
7429				/* No error, so compare images. */
7430				for (glw::GLuint i = 0; i < s_texture_count; ++i)
7431				{
7432					if (s_texture_data[i] != result[i])
7433					{
7434						m_context.getTestContext().getLog() << tcu::TestLog::Message << "GetTextureImage returned "
7435															<< DataToString(s_texture_count, result) << ", but "
7436															<< DataToString(s_texture_count, s_texture_data)
7437															<< " was expected. Test fails." << tcu::TestLog::EndMessage;
7438
7439						is_ok = false;
7440
7441						break;
7442					}
7443				}
7444			}
7445		}
7446
7447		/* Clean up texture .*/
7448		gl.deleteTextures(1, &texture);
7449		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
7450
7451		texture = 0;
7452
7453		/* Compressed case. */
7454		{
7455			/* Texture initiation. */
7456			gl.genTextures(1, &texture);
7457			GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
7458
7459			gl.bindTexture(GL_TEXTURE_2D, texture);
7460			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
7461
7462			gl.compressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_BPTC_UNORM, s_texture_width, s_texture_height,
7463									0, s_texture_size_compressed, s_texture_data_compressed);
7464			GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage2D has failed");
7465
7466			/* Quering image with tested function. */
7467			gl.getCompressedTextureImage(texture, 0, s_texture_count_compressed * sizeof(result_compressed[0]),
7468										 result_compressed);
7469
7470			/* Check for errors. */
7471			glw::GLenum error = GL_NO_ERROR;
7472
7473			if (GL_NO_ERROR != (error = gl.getError()))
7474			{
7475				m_context.getTestContext().getLog()
7476					<< tcu::TestLog::Message << "GetCompressedTextureImage unexpectedly generated error "
7477					<< glu::getErrorStr(error) << ". Test fails." << tcu::TestLog::EndMessage;
7478
7479				is_ok = false;
7480			}
7481			else
7482			{
7483				/* No error, so compare images. */
7484				for (glw::GLuint i = 0; i < s_texture_count_compressed; ++i)
7485				{
7486					if (s_texture_data_compressed[i] != result_compressed[i])
7487					{
7488						m_context.getTestContext().getLog()
7489							<< tcu::TestLog::Message << "GetCompressedTextureImage returned "
7490							<< DataToString(s_texture_count_compressed, result_compressed) << ", but "
7491							<< DataToString(s_texture_count_compressed, s_texture_data_compressed)
7492							<< " was expected. Test fails." << tcu::TestLog::EndMessage;
7493
7494						is_ok = false;
7495
7496						break;
7497					}
7498				}
7499			}
7500		}
7501	}
7502	catch (...)
7503	{
7504		is_ok	= false;
7505		is_error = true;
7506	}
7507
7508	/* Cleanup. */
7509	if (texture)
7510	{
7511		gl.deleteTextures(1, &texture);
7512	}
7513
7514	/* Result's setup. */
7515	if (is_ok)
7516	{
7517		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
7518	}
7519	else
7520	{
7521		if (is_error)
7522		{
7523			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
7524		}
7525		else
7526		{
7527			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
7528		}
7529	}
7530
7531	return STOP;
7532}
7533
7534/** @brief Convert raw data into string for logging purposes.
7535 *
7536 *  @param [in] count      Count of the data.
7537 *  @param [in] data       Raw data.
7538 *
7539 *  @return String representation of data.
7540 */
7541std::string GetImageTest::DataToString(glw::GLuint count, const glw::GLubyte data[])
7542{
7543	std::string data_str = "[";
7544
7545	for (glw::GLuint i = 0; i < count; ++i)
7546	{
7547		std::stringstream int_sstream;
7548
7549		int_sstream << unsigned(data[i]);
7550
7551		data_str.append(int_sstream.str());
7552
7553		if (i + 1 < count)
7554		{
7555			data_str.append(", ");
7556		}
7557		else
7558		{
7559			data_str.append("]");
7560		}
7561	}
7562
7563	return data_str;
7564}
7565
7566/******************************** Get Level Parameter Test Implementation   ********************************/
7567
7568/** @brief Get Level Parameter Test constructor.
7569 *
7570 *  @param [in] context     OpenGL context.
7571 */
7572GetLevelParameterTest::GetLevelParameterTest(deqp::Context& context)
7573	: deqp::TestCase(context, "textures_get_level_parameter", "Textures Get Level Parameter Test")
7574{
7575	/* Intentionally left blank */
7576}
7577
7578/** Reference data. */
7579const glw::GLubyte GetLevelParameterTest::s_texture_data[] = {
7580	0x0,  0x0,  0x0,  0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
7581	0x88, 0x0,  0x15, 0xff, 0xed, 0x1c, 0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0,  0xff,
7582	0xc8, 0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0xff,
7583	0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc, 0xff, 0x0,  0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff,
7584
7585	0x0,  0x0,  0x0,  0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
7586	0x88, 0x0,  0x15, 0xff, 0xed, 0x1c, 0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0,  0xff,
7587	0xc8, 0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0xff,
7588	0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc, 0xff, 0x0,  0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff,
7589
7590	0x0,  0x0,  0x0,  0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
7591	0x88, 0x0,  0x15, 0xff, 0xed, 0x1c, 0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0,  0xff,
7592	0xc8, 0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0xff,
7593	0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc, 0xff, 0x0,  0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff,
7594
7595	0x0,  0x0,  0x0,  0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
7596	0x88, 0x0,  0x15, 0xff, 0xed, 0x1c, 0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0,  0xff,
7597	0xc8, 0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0xff,
7598	0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc, 0xff, 0x0,  0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff
7599};
7600
7601/** Reference data parameters. */
7602const glw::GLuint GetLevelParameterTest::s_texture_width  = 4;
7603const glw::GLuint GetLevelParameterTest::s_texture_height = 4;
7604const glw::GLuint GetLevelParameterTest::s_texture_depth  = 4;
7605
7606/** @brief Get Level Parameter Test cases.
7607 *
7608 *  @return Iteration result.
7609 */
7610tcu::TestNode::IterateResult GetLevelParameterTest::iterate()
7611{
7612	/* Shortcut for GL functionality. */
7613	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7614
7615	/* Get context setup. */
7616	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
7617	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
7618
7619	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
7620	{
7621		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
7622
7623		return STOP;
7624	}
7625
7626	/* Running tests. */
7627	bool is_ok	= true;
7628	bool is_error = false;
7629
7630	/* Objects. */
7631	glw::GLuint texture = 0;
7632
7633	try
7634	{
7635		/* Texture initiation. */
7636		gl.genTextures(1, &texture);
7637		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
7638
7639		gl.bindTexture(GL_TEXTURE_3D, texture);
7640		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
7641
7642		gl.texImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, s_texture_width, s_texture_height, s_texture_depth, 0, GL_RGBA,
7643					  GL_UNSIGNED_BYTE, s_texture_data);
7644		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");
7645
7646		gl.texImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, s_texture_width / 2, s_texture_height / 2, s_texture_depth / 2, 0,
7647					  GL_RGBA, GL_UNSIGNED_BYTE, s_texture_data);
7648		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");
7649
7650		static const glw::GLenum pnames[] = {
7651			GL_TEXTURE_WIDTH,	  GL_TEXTURE_HEIGHT,	 GL_TEXTURE_DEPTH,		 GL_TEXTURE_INTERNAL_FORMAT,
7652			GL_TEXTURE_RED_TYPE,   GL_TEXTURE_GREEN_TYPE, GL_TEXTURE_BLUE_TYPE,  GL_TEXTURE_ALPHA_TYPE,
7653			GL_TEXTURE_DEPTH_TYPE, GL_TEXTURE_RED_SIZE,   GL_TEXTURE_GREEN_SIZE, GL_TEXTURE_BLUE_SIZE,
7654			GL_TEXTURE_ALPHA_SIZE, GL_TEXTURE_DEPTH_SIZE, GL_TEXTURE_COMPRESSED
7655		};
7656		static const glw::GLuint pnames_count = sizeof(pnames) / sizeof(pnames[0]);
7657
7658		/* Test GetTextureLevelParameteriv. */
7659		for (glw::GLuint i = 0; i < 2 /* levels */; ++i)
7660		{
7661			for (glw::GLuint j = 0; j < pnames_count; ++j)
7662			{
7663				glw::GLint result_legacy = 0;
7664				glw::GLint result_dsa	= 0;
7665
7666				/* Quering reference value. */
7667				gl.getTexLevelParameteriv(GL_TEXTURE_3D, i, pnames[j], &result_legacy);
7668				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
7669
7670				/* Quering using DSA function. */
7671				gl.getTextureLevelParameteriv(texture, i, pnames[j], &result_dsa);
7672
7673				/* Check for errors. */
7674				glw::GLenum error = GL_NO_ERROR;
7675
7676				if (GL_NO_ERROR != (error = gl.getError()))
7677				{
7678					m_context.getTestContext().getLog()
7679						<< tcu::TestLog::Message << "GetTextureLevelParameteriv unexpectedly generated error "
7680						<< glu::getErrorStr(error) << ". Test fails." << tcu::TestLog::EndMessage;
7681
7682					is_ok = false;
7683				}
7684				else
7685				{
7686					/* Compare values. */
7687					if (result_legacy != result_dsa)
7688					{
7689						m_context.getTestContext().getLog()
7690							<< tcu::TestLog::Message << "For parameter name "
7691							<< glu::getTextureLevelParameterStr(pnames[j]) << " GetTextureLevelParameteriv returned "
7692							<< result_dsa << ", but reference value (queried using GetTexLevelParameteriv) was "
7693							<< result_legacy << ". Test fails." << tcu::TestLog::EndMessage;
7694
7695						is_ok = false;
7696					}
7697				}
7698			}
7699		}
7700
7701		/* Test GetTextureLevelParameterfv. */
7702		for (glw::GLuint i = 0; i < 2 /* levels */; ++i)
7703		{
7704			for (glw::GLuint j = 0; j < pnames_count; ++j)
7705			{
7706				glw::GLfloat result_legacy = 0.f;
7707				glw::GLfloat result_dsa	= 0.f;
7708
7709				/* Quering reference value. */
7710				gl.getTexLevelParameterfv(GL_TEXTURE_3D, i, pnames[j], &result_legacy);
7711				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameterfv has failed");
7712
7713				/* Quering using DSA function. */
7714				gl.getTextureLevelParameterfv(texture, i, pnames[j], &result_dsa);
7715
7716				/* Check for errors. */
7717				glw::GLenum error = GL_NO_ERROR;
7718
7719				if (GL_NO_ERROR != (error = gl.getError()))
7720				{
7721					m_context.getTestContext().getLog()
7722						<< tcu::TestLog::Message << "GetTextureLevelParameterfv unexpectedly generated error "
7723						<< glu::getErrorStr(error) << ". Test fails." << tcu::TestLog::EndMessage;
7724
7725					is_ok = false;
7726				}
7727				else
7728				{
7729					/* Compare values. */
7730					if (de::abs(result_legacy - result_dsa) > 0.125 /* Precision. */)
7731					{
7732						m_context.getTestContext().getLog()
7733							<< tcu::TestLog::Message << "For parameter name "
7734							<< glu::getTextureLevelParameterStr(pnames[j]) << " GetTextureLevelParameterfv returned "
7735							<< result_dsa << ", but reference value (queried using GetTexLevelParameterfv) was "
7736							<< result_legacy << ". Test fails." << tcu::TestLog::EndMessage;
7737
7738						is_ok = false;
7739					}
7740				}
7741			}
7742		}
7743	}
7744	catch (...)
7745	{
7746		is_ok	= false;
7747		is_error = true;
7748	}
7749
7750	/* Cleanup. */
7751	if (texture)
7752	{
7753		gl.deleteTextures(1, &texture);
7754	}
7755
7756	while (GL_NO_ERROR != gl.getError())
7757		;
7758
7759	/* Result's setup. */
7760	if (is_ok)
7761	{
7762		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
7763	}
7764	else
7765	{
7766		if (is_error)
7767		{
7768			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
7769		}
7770		else
7771		{
7772			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
7773		}
7774	}
7775
7776	return STOP;
7777}
7778
7779/*********************************** Errors Utility Class *****************************************************/
7780
7781/** @brief Check for errors and log.
7782 *
7783 *  @param [in] context             Test's context.
7784 *  @param [in] expected_error      Expected error value.
7785 *  @param [in] function_name       Name of the function (to be logged).
7786 *  @param [in] log                 Log message.
7787 *
7788 *  @return True if error is equal to expected, false otherwise.
7789 */
7790bool ErrorsUtilities::CheckErrorAndLog(deqp::Context& context, glw::GLuint expected_error,
7791									   const glw::GLchar* function_name, const glw::GLchar* log)
7792{
7793	/* Shortcut for GL functionality. */
7794	const glw::Functions& gl = context.getRenderContext().getFunctions();
7795
7796	/* Check error. */
7797	glw::GLenum error = GL_NO_ERROR;
7798
7799	if (expected_error != (error = gl.getError()))
7800	{
7801		context.getTestContext().getLog() << tcu::TestLog::Message << function_name << " generated error "
7802										  << glu::getErrorStr(error) << " but, " << glu::getErrorStr(expected_error)
7803										  << " was expected if " << log << tcu::TestLog::EndMessage;
7804
7805		return false;
7806	}
7807
7808	return true;
7809}
7810
7811/******************************** Creation Errors Test Implementation   ********************************/
7812
7813/** @brief Creation Errors Test constructor.
7814 *
7815 *  @param [in] context     OpenGL context.
7816 */
7817CreationErrorsTest::CreationErrorsTest(deqp::Context& context)
7818	: deqp::TestCase(context, "textures_creation_errors", "Texture Objects Creation Errors Test")
7819{
7820	/* Intentionally left blank. */
7821}
7822
7823/** @brief Iterate Creation Errors Test cases.
7824 *
7825 *  @return Iteration result.
7826 */
7827tcu::TestNode::IterateResult CreationErrorsTest::iterate()
7828{
7829	/* Shortcut for GL functionality. */
7830	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7831
7832	/* Get context setup. */
7833	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
7834	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
7835
7836	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
7837	{
7838		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
7839
7840		return STOP;
7841	}
7842
7843	/* Running tests. */
7844	bool is_ok	= true;
7845	bool is_error = false;
7846
7847	/* Textures' objects */
7848	glw::GLuint texture = 0;
7849
7850	try
7851	{
7852		/* Not a target test. */
7853		gl.createTextures(NotATarget(), 1, &texture);
7854		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glCreateTextures",
7855								  "target is not one of the allowable values.");
7856
7857		if (texture)
7858		{
7859			gl.deleteTextures(1, &texture);
7860
7861			texture = 0;
7862		}
7863
7864		/* Negative number of textures. */
7865		gl.createTextures(GL_TEXTURE_2D, -1, &texture);
7866		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCreateTextures", "n is negative.");
7867	}
7868	catch (...)
7869	{
7870		is_ok	= false;
7871		is_error = true;
7872	}
7873
7874	/* Cleanup. */
7875	if (texture)
7876	{
7877		gl.deleteTextures(1, &texture);
7878	}
7879
7880	/* Errors clean up. */
7881	while (gl.getError())
7882		;
7883
7884	/* Result's setup. */
7885	if (is_ok)
7886	{
7887		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
7888	}
7889	else
7890	{
7891		if (is_error)
7892		{
7893			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
7894		}
7895		else
7896		{
7897			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
7898		}
7899	}
7900
7901	return STOP;
7902}
7903
7904/** @brief Function retruns enum which is not a texture target.
7905 */
7906glw::GLenum CreationErrorsTest::NotATarget()
7907{
7908	static const glw::GLenum texture_targets[] = { GL_TEXTURE_1D,
7909												   GL_TEXTURE_2D,
7910												   GL_TEXTURE_3D,
7911												   GL_TEXTURE_1D_ARRAY,
7912												   GL_TEXTURE_2D_ARRAY,
7913												   GL_TEXTURE_RECTANGLE,
7914												   GL_TEXTURE_CUBE_MAP,
7915												   GL_TEXTURE_CUBE_MAP_ARRAY,
7916												   GL_TEXTURE_BUFFER,
7917												   GL_TEXTURE_2D_MULTISAMPLE,
7918												   GL_TEXTURE_2D_MULTISAMPLE_ARRAY };
7919
7920	glw::GLenum not_a_target = 0;
7921	bool		is_target	= true;
7922
7923	while (is_target)
7924	{
7925		not_a_target++;
7926
7927		is_target = false;
7928
7929		for (glw::GLuint i = 0; i < sizeof(texture_targets) / sizeof(texture_targets[0]); ++i)
7930		{
7931			if (texture_targets[i] == not_a_target)
7932			{
7933				is_target = true;
7934				break;
7935			}
7936		}
7937	}
7938
7939	return not_a_target;
7940}
7941
7942/******************************** Texture Buffer Errors Test Implementation   ********************************/
7943
7944/** @brief Texture Buffer Errors Test constructor.
7945 *
7946 *  @param [in] context     OpenGL context.
7947 */
7948BufferErrorsTest::BufferErrorsTest(deqp::Context& context)
7949	: deqp::TestCase(context, "textures_buffer_errors", "Texture Buffer Errors Test")
7950{
7951	/* Intentionally left blank. */
7952}
7953
7954/** @brief Iterate Texture Buffer Errors Test cases.
7955 *
7956 *  @return Iteration result.
7957 */
7958tcu::TestNode::IterateResult BufferErrorsTest::iterate()
7959{
7960	/* Shortcut for GL functionality. */
7961	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7962
7963	/* Get context setup. */
7964	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
7965	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
7966
7967	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
7968	{
7969		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
7970
7971		return STOP;
7972	}
7973
7974	/* Running tests. */
7975	bool is_ok	= true;
7976	bool is_error = false;
7977
7978	/* Textures' objects */
7979	glw::GLuint texture_buffer = 0;
7980	glw::GLuint texture_1D	 = 0;
7981	glw::GLuint buffer		   = 0;
7982
7983	static const glw::GLubyte data[4]   = { 1, 2, 3, 4 };
7984	static const glw::GLuint  data_size = sizeof(data);
7985
7986	try
7987	{
7988		/* Auxiliary objects setup. */
7989		gl.createTextures(GL_TEXTURE_BUFFER, 1, &texture_buffer);
7990		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
7991
7992		gl.createTextures(GL_TEXTURE_1D, 1, &texture_1D);
7993		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
7994
7995		gl.createBuffers(1, &buffer);
7996		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers has failed");
7997
7998		gl.namedBufferData(buffer, data_size, data, GL_STATIC_COPY);
7999		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData has failed");
8000
8001		/*  Check that INVALID_OPERATION is generated by glTextureBuffer if texture
8002		 is not the name of an existing texture object. */
8003		{
8004			glw::GLuint not_a_texture = 0;
8005
8006			while (gl.isTexture(++not_a_texture))
8007				;
8008			GLU_EXPECT_NO_ERROR(gl.getError(), "glIsTexture has failed");
8009
8010			gl.textureBuffer(not_a_texture, GL_RGBA8, buffer);
8011
8012			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureBuffer",
8013									  "texture is not the name of an existing texture object.");
8014		}
8015
8016		/*  Check that INVALID_ENUM is generated by glTextureBuffer if the effective
8017		 target of texture is not TEXTURE_BUFFER. */
8018		{
8019			gl.textureBuffer(texture_1D, GL_RGBA8, buffer);
8020
8021			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureBuffer",
8022									  "the effective target of texture is not TEXTURE_BUFFER.");
8023		}
8024
8025		/*  Check that INVALID_ENUM is generated if internalformat is not one of the
8026		 sized internal formats described above. */
8027		{
8028			gl.textureBuffer(texture_buffer, GL_COMPRESSED_SIGNED_RED_RGTC1, buffer);
8029
8030			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureBuffer",
8031									  "internalformat is not one of the sized internal formats described above..");
8032		}
8033
8034		/*  Check that INVALID_OPERATION is generated if buffer is not zero and is
8035		 not the name of an existing buffer object. */
8036		{
8037			glw::GLuint not_a_buffer = 0;
8038
8039			while (gl.isBuffer(++not_a_buffer))
8040				;
8041			GLU_EXPECT_NO_ERROR(gl.getError(), "glIsBuffer has failed");
8042
8043			gl.textureBuffer(texture_buffer, GL_RGBA8, not_a_buffer);
8044
8045			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureBuffer",
8046									  "buffer is not zero and is not the name of an existing buffer object.");
8047		}
8048	}
8049	catch (...)
8050	{
8051		is_ok	= false;
8052		is_error = true;
8053	}
8054
8055	/* Cleanup. */
8056	if (texture_1D)
8057	{
8058		gl.deleteTextures(1, &texture_1D);
8059	}
8060
8061	if (texture_buffer)
8062	{
8063		gl.deleteTextures(1, &texture_buffer);
8064	}
8065
8066	if (buffer)
8067	{
8068		gl.deleteBuffers(1, &buffer);
8069	}
8070
8071	/* Errors clean up. */
8072	while (gl.getError())
8073		;
8074
8075	/* Result's setup. */
8076	if (is_ok)
8077	{
8078		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
8079	}
8080	else
8081	{
8082		if (is_error)
8083		{
8084			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
8085		}
8086		else
8087		{
8088			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
8089		}
8090	}
8091
8092	return STOP;
8093}
8094
8095/******************************** Texture Buffer Range Errors Test Implementation   ********************************/
8096
8097/** @brief Texture Buffer Range Errors Test constructor.
8098 *
8099 *  @param [in] context     OpenGL context.
8100 */
8101BufferRangeErrorsTest::BufferRangeErrorsTest(deqp::Context& context)
8102	: deqp::TestCase(context, "textures_buffer_range_errors", "Texture Buffer Range Errors Test")
8103{
8104	/* Intentionally left blank. */
8105}
8106
8107/** @brief Iterate Texture Buffer Range Errors Test cases.
8108 *
8109 *  @return Iteration result.
8110 */
8111tcu::TestNode::IterateResult BufferRangeErrorsTest::iterate()
8112{
8113	/* Shortcut for GL functionality. */
8114	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8115
8116	/* Get context setup. */
8117	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
8118	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
8119
8120	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
8121	{
8122		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
8123
8124		return STOP;
8125	}
8126
8127	/* Running tests. */
8128	bool is_ok	= true;
8129	bool is_error = false;
8130
8131	/* Textures' objects */
8132	glw::GLuint texture_buffer = 0;
8133	glw::GLuint texture_1D	 = 0;
8134	glw::GLuint buffer		   = 0;
8135
8136	static const glw::GLubyte data[4]   = { 1, 2, 3, 4 };
8137	static const glw::GLuint  data_size = sizeof(data);
8138
8139	try
8140	{
8141		/* Auxiliary objects setup. */
8142		gl.createTextures(GL_TEXTURE_BUFFER, 1, &texture_buffer);
8143		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
8144
8145		gl.createTextures(GL_TEXTURE_1D, 1, &texture_1D);
8146		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
8147
8148		gl.createBuffers(1, &buffer);
8149		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers has failed");
8150
8151		gl.namedBufferData(buffer, data_size, data, GL_STATIC_COPY);
8152		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData has failed");
8153
8154		/*  Check that INVALID_OPERATION is generated by TextureBufferRange if
8155		 texture is not the name of an existing texture object.*/
8156		{
8157			glw::GLuint not_a_texture = 0;
8158
8159			while (gl.isTexture(++not_a_texture))
8160				;
8161			GLU_EXPECT_NO_ERROR(gl.getError(), "glIsTexture has failed");
8162
8163			gl.textureBufferRange(not_a_texture, GL_RGBA8, buffer, 0, data_size);
8164
8165			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureBufferRange",
8166									  "texture is not the name of an existing texture object.");
8167		}
8168
8169		/*  Check that INVALID_ENUM is generated by TextureBufferRange if the
8170		 effective target of texture is not TEXTURE_BUFFER. */
8171		{
8172			gl.textureBufferRange(texture_1D, GL_RGBA8, buffer, 0, data_size);
8173
8174			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureBufferRange",
8175									  "the effective target of texture is not TEXTURE_BUFFER.");
8176		}
8177
8178		/*  Check that INVALID_ENUM is generated by TextureBufferRange if
8179		 internalformat is not one of the sized internal formats described above. */
8180		{
8181			gl.textureBufferRange(texture_buffer, GL_COMPRESSED_SIGNED_RED_RGTC1, buffer, 0, data_size);
8182
8183			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureBufferRange",
8184									  "internalformat is not one of the supported sized internal formats.");
8185		}
8186
8187		/*  Check that INVALID_OPERATION is generated by TextureBufferRange if
8188		 buffer is not zero and is not the name of an existing buffer object. */
8189		{
8190			glw::GLuint not_a_buffer = 0;
8191
8192			while (gl.isBuffer(++not_a_buffer))
8193				;
8194			GLU_EXPECT_NO_ERROR(gl.getError(), "glIsBuffer has failed");
8195
8196			gl.textureBufferRange(texture_buffer, GL_RGBA8, not_a_buffer, 0, data_size);
8197
8198			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureBufferRange",
8199									  "buffer is not zero and is not the name of an existing buffer object.");
8200		}
8201
8202		/* Check that INVALID_VALUE is generated by TextureBufferRange if offset
8203		 is negative, if size is less than or equal to zero, or if offset + size
8204		 is greater than the value of BUFFER_SIZE for buffer. */
8205		{
8206			gl.textureBufferRange(texture_buffer, GL_RGBA8, buffer, -1, data_size);
8207
8208			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureBufferRange", "offset is negative.");
8209
8210			gl.textureBufferRange(texture_buffer, GL_RGBA8, buffer, 0, 0);
8211
8212			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureBufferRange", "size is zero.");
8213
8214			gl.textureBufferRange(texture_buffer, GL_RGBA8, buffer, 0, -1);
8215
8216			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureBufferRange", "size is negative.");
8217
8218			gl.textureBufferRange(texture_buffer, GL_RGBA8, buffer, 0, data_size * 16);
8219
8220			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureBufferRange",
8221									  "size is greater than the value of BUFFER_SIZE for buffer.");
8222		}
8223
8224		/* Check that INVALID_VALUE is generated by TextureBufferRange if offset is
8225		 not an integer multiple of the value of TEXTURE_BUFFER_OFFSET_ALIGNMENT. */
8226		{
8227			glw::GLint gl_texture_buffer_offset_alignment = 0;
8228
8229			gl.getIntegerv(GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT, &gl_texture_buffer_offset_alignment);
8230
8231			/* If alignmet is 1 we cannot do anything. Error situtation is impossible then. */
8232			if (gl_texture_buffer_offset_alignment > 1)
8233			{
8234				gl.textureBufferRange(texture_buffer, GL_RGBA8, buffer, 1, data_size - 1);
8235
8236				is_ok &= CheckErrorAndLog(
8237					m_context, GL_INVALID_VALUE, "glTextureBufferRange",
8238					"offset is not an integer multiple of the value of TEXTURE_BUFFER_OFFSET_ALIGNMENT.");
8239			}
8240		}
8241	}
8242	catch (...)
8243	{
8244		is_ok	= false;
8245		is_error = true;
8246	}
8247
8248	/* Cleanup. */
8249	if (texture_1D)
8250	{
8251		gl.deleteTextures(1, &texture_1D);
8252	}
8253
8254	if (texture_buffer)
8255	{
8256		gl.deleteTextures(1, &texture_buffer);
8257	}
8258
8259	if (buffer)
8260	{
8261		gl.deleteBuffers(1, &buffer);
8262	}
8263
8264	/* Errors clean up. */
8265	while (gl.getError())
8266		;
8267
8268	/* Result's setup. */
8269	if (is_ok)
8270	{
8271		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
8272	}
8273	else
8274	{
8275		if (is_error)
8276		{
8277			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
8278		}
8279		else
8280		{
8281			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
8282		}
8283	}
8284
8285	return STOP;
8286}
8287
8288/******************************** Texture Storage Errors Test Implementation   ********************************/
8289
8290/** @brief Texture Storage Errors Test constructor.
8291 *
8292 *  @param [in] context     OpenGL context.
8293 */
8294StorageErrorsTest::StorageErrorsTest(deqp::Context& context)
8295	: deqp::TestCase(context, "textures_storage_errors", "Texture Storage Errors Test")
8296	, m_to_1D(0)
8297	, m_to_1D_array(0)
8298	, m_to_2D(0)
8299	, m_to_2D_array(0)
8300	, m_to_3D(0)
8301	, m_to_2D_ms(0)
8302	, m_to_2D_ms_immutable(0)
8303	, m_to_3D_ms(0)
8304	, m_to_3D_ms_immutable(0)
8305	, m_to_invalid(0)
8306	, m_internalformat_invalid(0)
8307	, m_max_texture_size(1)
8308	, m_max_samples(1)
8309	, m_max_array_texture_layers(1)
8310{
8311	/* Intentionally left blank. */
8312}
8313
8314/** @brief Iterate Texture Storage Errors Test cases.
8315 *
8316 *  @return Iteration result.
8317 */
8318tcu::TestNode::IterateResult StorageErrorsTest::iterate()
8319{
8320	/* Get context setup. */
8321	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
8322	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
8323
8324	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
8325	{
8326		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
8327
8328		return STOP;
8329	}
8330
8331	/* Running tests. */
8332	bool is_ok	= true;
8333	bool is_error = false;
8334
8335	try
8336	{
8337		Prepare();
8338
8339		is_ok &= Test1D();
8340		is_ok &= Test2D();
8341		is_ok &= Test3D();
8342		is_ok &= Test2DMultisample();
8343		is_ok &= Test3DMultisample();
8344	}
8345	catch (...)
8346	{
8347		is_ok	= false;
8348		is_error = true;
8349	}
8350
8351	/* Cleanup. */
8352	Clean();
8353
8354	/* Result's setup. */
8355	if (is_ok)
8356	{
8357		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
8358	}
8359	else
8360	{
8361		if (is_error)
8362		{
8363			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
8364		}
8365		else
8366		{
8367			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
8368		}
8369	}
8370
8371	return STOP;
8372}
8373
8374/** @brief Prepare test objects.
8375 */
8376void StorageErrorsTest::Prepare()
8377{
8378	/* Shortcut for GL functionality. */
8379	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8380
8381	/* Auxiliary objects setup. */
8382
8383	/* 1D */
8384	gl.createTextures(GL_TEXTURE_1D, 1, &m_to_1D);
8385	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
8386
8387	/* 1D ARRAY */
8388	gl.createTextures(GL_TEXTURE_1D_ARRAY, 1, &m_to_1D_array);
8389	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
8390
8391	/* 2D */
8392	gl.createTextures(GL_TEXTURE_2D, 1, &m_to_2D);
8393	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
8394
8395	/* 2D ARRAY */
8396	gl.createTextures(GL_TEXTURE_2D_ARRAY, 1, &m_to_2D_array);
8397	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
8398
8399	/* 3D */
8400	gl.createTextures(GL_TEXTURE_3D, 1, &m_to_3D);
8401	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
8402
8403	/* 2D Multisample */
8404	gl.createTextures(GL_TEXTURE_2D_MULTISAMPLE, 1, &m_to_2D_ms);
8405	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
8406
8407	/* 2D Multisample with storage */
8408	gl.createTextures(GL_TEXTURE_2D_MULTISAMPLE, 1, &m_to_2D_ms_immutable);
8409	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
8410
8411	gl.textureStorage2DMultisample(m_to_2D_ms_immutable, 1, GL_R8, 16, 16, false);
8412	GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2DMultisample has failed");
8413
8414	/* 3D Multisample */
8415	gl.createTextures(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 1, &m_to_3D_ms);
8416	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
8417
8418	/* 3D Multisample with storage */
8419	gl.createTextures(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 1, &m_to_3D_ms_immutable);
8420	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
8421
8422	gl.textureStorage3DMultisample(m_to_3D_ms_immutable, 1, GL_R8, 16, 16, 16, false);
8423	GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2DMultisample has failed");
8424
8425	/* Invalid values */
8426
8427	/* invalid texture object */
8428	while (gl.isTexture(++m_to_invalid))
8429		;
8430	GLU_EXPECT_NO_ERROR(gl.getError(), "glIsTexture has failed");
8431
8432	/* invalid internal format */
8433	static const glw::GLenum all_internal_formats[] = { GL_R8,
8434														GL_R8_SNORM,
8435														GL_R16,
8436														GL_R16_SNORM,
8437														GL_RG8,
8438														GL_RG8_SNORM,
8439														GL_RG16,
8440														GL_RG16_SNORM,
8441														GL_R3_G3_B2,
8442														GL_RGB4,
8443														GL_RGB5,
8444														GL_RGB565,
8445														GL_RGB8,
8446														GL_RGB8_SNORM,
8447														GL_RGB10,
8448														GL_RGB12,
8449														GL_RGB16,
8450														GL_RGB16_SNORM,
8451														GL_RGBA2,
8452														GL_RGBA4,
8453														GL_RGB5_A1,
8454														GL_RGBA8,
8455														GL_RGBA8_SNORM,
8456														GL_RGB10_A2,
8457														GL_RGB10_A2UI,
8458														GL_RGBA12,
8459														GL_RGBA16,
8460														GL_RGBA16_SNORM,
8461														GL_SRGB8,
8462														GL_SRGB8_ALPHA8,
8463														GL_R16F,
8464														GL_RG16F,
8465														GL_RGB16F,
8466														GL_RGBA16F,
8467														GL_R32F,
8468														GL_RG32F,
8469														GL_RGB32F,
8470														GL_RGBA32F,
8471														GL_R11F_G11F_B10F,
8472														GL_RGB9_E5,
8473														GL_R8I,
8474														GL_R8UI,
8475														GL_R16I,
8476														GL_R16UI,
8477														GL_R32I,
8478														GL_R32UI,
8479														GL_RG8I,
8480														GL_RG8UI,
8481														GL_RG16I,
8482														GL_RG16UI,
8483														GL_RG32I,
8484														GL_RG32UI,
8485														GL_RGB8I,
8486														GL_RGB8UI,
8487														GL_RGB16I,
8488														GL_RGB16UI,
8489														GL_RGB32I,
8490														GL_RGB32UI,
8491														GL_RGBA8I,
8492														GL_RGBA8UI,
8493														GL_RGBA16I,
8494														GL_RGBA16UI,
8495														GL_RGBA32I,
8496														GL_RGBA32UI,
8497														GL_COMPRESSED_RED,
8498														GL_COMPRESSED_RG,
8499														GL_COMPRESSED_RGB,
8500														GL_COMPRESSED_RGBA,
8501														GL_COMPRESSED_SRGB,
8502														GL_COMPRESSED_SRGB_ALPHA,
8503														GL_COMPRESSED_RED_RGTC1,
8504														GL_COMPRESSED_SIGNED_RED_RGTC1,
8505														GL_COMPRESSED_RG_RGTC2,
8506														GL_COMPRESSED_SIGNED_RG_RGTC2,
8507														GL_COMPRESSED_RGBA_BPTC_UNORM,
8508														GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM,
8509														GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT,
8510														GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT,
8511														GL_COMPRESSED_RGB8_ETC2,
8512														GL_COMPRESSED_SRGB8_ETC2,
8513														GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
8514														GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
8515														GL_COMPRESSED_RGBA8_ETC2_EAC,
8516														GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,
8517														GL_COMPRESSED_R11_EAC,
8518														GL_COMPRESSED_SIGNED_R11_EAC,
8519														GL_COMPRESSED_RG11_EAC,
8520														GL_COMPRESSED_SIGNED_RG11_EAC,
8521														GL_DEPTH_COMPONENT16,
8522														GL_DEPTH_COMPONENT24,
8523														GL_DEPTH_COMPONENT32,
8524														GL_DEPTH_COMPONENT32F,
8525														GL_DEPTH24_STENCIL8,
8526														GL_DEPTH32F_STENCIL8,
8527														GL_STENCIL_INDEX1,
8528														GL_STENCIL_INDEX4,
8529														GL_STENCIL_INDEX8,
8530														GL_STENCIL_INDEX16 };
8531
8532	static const glw::GLuint all_internal_formats_count =
8533		sizeof(all_internal_formats) / sizeof(all_internal_formats[0]);
8534
8535	bool is_valid			 = true;
8536	m_internalformat_invalid = 0;
8537
8538	while (is_valid)
8539	{
8540		is_valid = false;
8541		m_internalformat_invalid++;
8542		for (glw::GLuint i = 0; i < all_internal_formats_count; ++i)
8543		{
8544			if (all_internal_formats[i] == m_internalformat_invalid)
8545			{
8546				is_valid = true;
8547				break;
8548			}
8549		}
8550	}
8551
8552	/* Maximum texture size.*/
8553	gl.getIntegerv(GL_MAX_TEXTURE_SIZE, &m_max_texture_size);
8554	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");
8555
8556	/* Maximum number of samples. */
8557	gl.getIntegerv(GL_MAX_SAMPLES, &m_max_samples);
8558	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");
8559
8560	/* Maximum number of array texture layers. */
8561	gl.getIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &m_max_array_texture_layers);
8562	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");
8563}
8564
8565/** @brief Test TextureStorage1D
8566 *
8567 *  @return Test result.
8568 */
8569bool StorageErrorsTest::Test1D()
8570{
8571	/* Shortcut for GL functionality. */
8572	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8573
8574	/* Result. */
8575	bool is_ok = true;
8576
8577	/*  Check that INVALID_OPERATION is generated by TextureStorage1D if texture
8578	 is not the name of an existing texture object. */
8579	{
8580		gl.textureStorage1D(m_to_invalid, 1, GL_R8, 8);
8581		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage1D",
8582								  "texture is not the name of an existing texture object.");
8583	}
8584
8585	/*  Check that INVALID_ENUM is generated by TextureStorage1D if
8586	 internalformat is not a valid sized internal format. */
8587	{
8588		gl.textureStorage1D(m_to_1D, 1, m_internalformat_invalid, 8);
8589		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureStorage1D",
8590								  "internalformat is not a valid sized internal format.");
8591	}
8592
8593	/*  Check that INVALID_ENUM is generated by TextureStorage1D if target or
8594	 the effective target of texture is not one of the accepted targets
8595	 described above. */
8596	{
8597		gl.textureStorage1D(m_to_2D, 1, GL_R8, 8);
8598		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage1D",
8599								  "the effective target of texture is not one of the accepted targets.");
8600	}
8601
8602	/*  Check that INVALID_VALUE is generated by TextureStorage1D if width or
8603	 levels are less than 1. */
8604	{
8605		gl.textureStorage1D(m_to_1D, 0, GL_R8, 8);
8606		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage1D", "levels is less than 1.");
8607
8608		gl.textureStorage1D(m_to_1D, 1, GL_R8, 0);
8609		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage1D", "width is less than 1.");
8610	}
8611
8612	/*  Check that INVALID_OPERATION is generated by TextureStorage1D if levels
8613	 is greater than log2(width)+1. */
8614	{
8615		gl.textureStorage1D(m_to_1D, 8, GL_R8, 8);
8616		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage1D",
8617								  "levels is greater than log2(width)+1.");
8618	}
8619
8620	return is_ok;
8621}
8622
8623/** @brief Test TextureStorage2D
8624 *
8625 *  @return Test result.
8626 */
8627bool StorageErrorsTest::Test2D()
8628{
8629	/* Shortcut for GL functionality. */
8630	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8631
8632	/* Result. */
8633	bool is_ok = true;
8634
8635	/*  Check that INVALID_OPERATION is generated by TextureStorage2D if
8636	 texture is not the name of an existing texture object. */
8637	{
8638		gl.textureStorage2D(m_to_invalid, 1, GL_R8, 8, 8);
8639		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage2D",
8640								  "texture is not the name of an existing texture object.");
8641	}
8642
8643	/*  Check that INVALID_ENUM is generated by TextureStorage2D if
8644	 internalformat is not a valid sized internal format. */
8645	{
8646		gl.textureStorage2D(m_to_2D, 1, m_internalformat_invalid, 8, 8);
8647		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureStorage2D",
8648								  "internalformat is not a valid sized internal format.");
8649	}
8650
8651	/*  Check that INVALID_ENUM is generated by TextureStorage2D if target or
8652	 the effective target of texture is not one of the accepted targets
8653	 described above. */
8654	{
8655		gl.textureStorage2D(m_to_1D, 1, GL_R8, 8, 8);
8656		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage2D",
8657								  "the effective target of texture is not one of the accepted targets.");
8658	}
8659
8660	/*  Check that INVALID_VALUE is generated by TextureStorage2D if width,
8661	 height or levels are less than 1. */
8662	{
8663		gl.textureStorage2D(m_to_2D, 0, GL_R8, 8, 8);
8664		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage2D", "levels is less than 1.");
8665
8666		gl.textureStorage2D(m_to_2D, 1, GL_R8, 0, 8);
8667		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage2D", "width is less than 1.");
8668
8669		gl.textureStorage2D(m_to_2D, 1, GL_R8, 8, 0);
8670		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage2D", "height is less than 1.");
8671	}
8672
8673	/* Check that INVALID_OPERATION is generated by TextureStorage2D if target
8674	 is TEXTURE_1D_ARRAY or PROXY_TEXTURE_1D_ARRAY and levels is greater than
8675	 log2(width)+1. */
8676	{
8677		gl.textureStorage2D(m_to_1D_array, 8, GL_R8, 8, 8);
8678		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage2D",
8679								  "target is TEXTURE_1D_ARRAY and levels is greater than log2(width)+1.");
8680	}
8681
8682	/*  Check that INVALID_OPERATION is generated by TextureStorage2D if target
8683	 is not TEXTURE_1D_ARRAY or PROXY_TEXTURE_1D_ARRAY and levels is greater
8684	 than log2(max(width, height))+1.  */
8685	{
8686		gl.textureStorage2D(m_to_2D, 8, GL_R8, 8, 8);
8687		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage2D",
8688								  "target is TEXTURE_2D and levels is greater than log2(max(width, height))+1.");
8689	}
8690
8691	return is_ok;
8692}
8693
8694/** @brief Test TextureStorage3D
8695 *
8696 *  @return Test result.
8697 */
8698bool StorageErrorsTest::Test3D()
8699{
8700	/* Shortcut for GL functionality. */
8701	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8702
8703	/* Result. */
8704	bool is_ok = true;
8705
8706	/*  Check that INVALID_OPERATION is generated by TextureStorage3D if texture
8707	 is not the name of an existing texture object. */
8708	{
8709		gl.textureStorage3D(m_to_invalid, 1, GL_R8, 8, 8, 8);
8710		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage3D",
8711								  "texture is not the name of an existing texture object.");
8712	}
8713
8714	/*  Check that INVALID_ENUM is generated by TextureStorage3D if
8715	 internalformat is not a valid sized internal format. */
8716	{
8717		gl.textureStorage3D(m_to_3D, 1, m_internalformat_invalid, 8, 8, 8);
8718		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureStorage3D",
8719								  "internalformat is not a valid sized internal format.");
8720	}
8721
8722	/*  Check that INVALID_ENUM is generated by TextureStorage3D if target or
8723	 the effective target of texture is not one of the accepted targets
8724	 described above. */
8725	{
8726		gl.textureStorage3D(m_to_1D, 1, GL_R8, 8, 8, 8);
8727		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage3D",
8728								  "the effective target of texture is not one of the accepted targets.");
8729	}
8730
8731	/*  Check that INVALID_VALUE is generated by TextureStorage3D if width,
8732	 height, depth or levels are less than 1. */
8733	{
8734		gl.textureStorage3D(m_to_3D, 0, GL_R8, 8, 8, 8);
8735		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3D", "levels is less than 1.");
8736
8737		gl.textureStorage3D(m_to_3D, 1, GL_R8, 0, 8, 8);
8738		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3D", "width is less than 1.");
8739
8740		gl.textureStorage3D(m_to_3D, 1, GL_R8, 8, 0, 8);
8741		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3D", "height is less than 1.");
8742
8743		gl.textureStorage3D(m_to_3D, 1, GL_R8, 8, 8, 0);
8744		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3D", "depth is less than 1.");
8745	}
8746
8747	/* Check that INVALID_OPERATION is generated by TextureStorage3D if target
8748	 is TEXTURE_3D or PROXY_TEXTURE_3D and levels is greater than
8749	 log2(max(width, height, depth))+1. */
8750	{
8751		gl.textureStorage3D(m_to_3D, 8, GL_R8, 8, 8, 8);
8752		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage3D",
8753								  "target is TEXTURE_3D and levels is greater than log2(max(width, height, depth))+1.");
8754	}
8755
8756	/*  Check that INVALID_OPERATION is generated by TextureStorage3D if target
8757	 is TEXTURE_2D_ARRAY, PROXY_TEXTURE_2D_ARRAY, TEXURE_CUBE_ARRAY,
8758	 or PROXY_TEXTURE_CUBE_MAP_ARRAY and levels is greater than
8759	 log2(max(width, height))+1.  */
8760	{
8761		gl.textureStorage3D(m_to_2D_array, 6, GL_R8, 8, 8, 256);
8762		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage3D",
8763								  "target is TEXTURE_2D_ARRAY and levels is greater than log2(max(width, height))+1.");
8764	}
8765
8766	return is_ok;
8767}
8768
8769/** @brief Test TextureStorage2DMultisample
8770 *
8771 *  @return Test result.
8772 */
8773bool StorageErrorsTest::Test2DMultisample()
8774{
8775	/* Shortcut for GL functionality. */
8776	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8777
8778	/* Result. */
8779	bool is_ok = true;
8780
8781	/*  Check that INVALID_OPERATION is generated by TextureStorage2DMultisample
8782	 if texture is not the name of an existing texture object. */
8783	{
8784		gl.textureStorage2DMultisample(m_to_invalid, 1, GL_R8, 8, 8, false);
8785		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage2DMultisample",
8786								  "texture is not the name of an existing texture object.");
8787	}
8788
8789	/*  Check that INVALID_ENUM is generated by TextureStorage2DMultisample if
8790	 internalformat is not a valid color-renderable, depth-renderable or
8791	 stencil-renderable format. */
8792	{
8793		gl.textureStorage2DMultisample(m_to_2D_ms, 1, m_internalformat_invalid, 8, 8, false);
8794		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureStorage2DMultisample",
8795								  "internalformat is not a valid sized internal format.");
8796	}
8797
8798	/*  Check that INVALID_OPERATION is generated by TextureStorage2DMultisample if
8799	 target or the effective target of texture is not one of the accepted
8800	 targets described above. */
8801	{
8802		gl.textureStorage2DMultisample(m_to_1D, 1, GL_R8, 8, 8, false);
8803		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage2DMultisample",
8804								  "the effective target of texture is not one of the accepted targets.");
8805	}
8806
8807	/* Check that INVALID_VALUE is generated by TextureStorage2DMultisample if
8808	 width or height are less than 1 or greater than the value of
8809	 MAX_TEXTURE_SIZE. */
8810	{
8811		gl.textureStorage2DMultisample(m_to_2D_ms, 1, GL_R8, 0, 8, false);
8812		is_ok &=
8813			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage2DMultisample", "width is less than 1.");
8814
8815		gl.textureStorage2DMultisample(m_to_2D_ms, 1, GL_R8, 8, 0, false);
8816		is_ok &=
8817			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage2DMultisample", "height is less than 1.");
8818
8819		gl.textureStorage2DMultisample(m_to_2D_ms, 1, GL_R8, m_max_texture_size * 2, 8, false);
8820		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage2DMultisample",
8821								  "width is greater than the value of MAX_TEXTURE_SIZE.");
8822
8823		gl.textureStorage2DMultisample(m_to_2D_ms, 1, GL_R8, 8, m_max_texture_size * 2, false);
8824		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage2DMultisample",
8825								  "height is greater than the value of MAX_TEXTURE_SIZE.");
8826	}
8827
8828	/* Check that INVALID_OPERATION is generated by TextureStorage2DMultisample if
8829	 samples is greater than the value of MAX_SAMPLES. */
8830	{
8831		gl.textureStorage2DMultisample(m_to_2D_ms, m_max_samples * 2, GL_R8, 8, 8, false);
8832		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage2DMultisample",
8833								  "samples is greater than the value of MAX_SAMPLES.");
8834	}
8835
8836	/* Check that INVALID_OPERATION is generated by TextureStorage2DMultisample
8837	 if the value of TEXTURE_IMMUTABLE_FORMAT for the texture bound to target
8838	 is not FALSE. */
8839	{
8840		gl.textureStorage2DMultisample(m_to_2D_ms_immutable, 1, GL_R8, 8, 8, false);
8841		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage2DMultisample",
8842								  "samples is greater than the value of MAX_SAMPLES.");
8843	}
8844
8845	return is_ok;
8846}
8847
8848/** @brief Test TextureStorage3DMultisample
8849 *
8850 *  @return Test result.
8851 */
8852bool StorageErrorsTest::Test3DMultisample()
8853{
8854	/* Shortcut for GL functionality. */
8855	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8856
8857	/* Result. */
8858	bool is_ok = true;
8859
8860	/*  Check that INVALID_OPERATION is generated by TextureStorage3DMultisample
8861	 if texture is not the name of an existing texture object. */
8862	{
8863		gl.textureStorage3DMultisample(m_to_invalid, 1, GL_R8, 8, 8, 8, false);
8864		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage3DMultisample",
8865								  "texture is not the name of an existing texture object.");
8866	}
8867
8868	/*  Check that INVALID_ENUM is generated by TextureStorage3DMultisample if
8869	 internalformat is not a valid color-renderable, depth-renderable or
8870	 stencil-renderable format. */
8871	{
8872		gl.textureStorage3DMultisample(m_to_3D_ms, 1, m_internalformat_invalid, 8, 8, 8, false);
8873		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureStorage3DMultisample",
8874								  "internalformat is not a valid sized internal format.");
8875	}
8876
8877	/*  Check that INVALID_OPERATION is generated by TextureStorage3DMultisample if
8878	 target or the effective target of texture is not one of the accepted
8879	 targets described above. */
8880	{
8881		gl.textureStorage3DMultisample(m_to_1D, 1, GL_R8, 8, 8, 8, false);
8882		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage3DMultisample",
8883								  "the effective target of texture is not one of the accepted targets.");
8884	}
8885
8886	/* Check that INVALID_VALUE is generated by TextureStorage3DMultisample if
8887	 width or height are less than 1 or greater than the value of
8888	 MAX_TEXTURE_SIZE. */
8889	{
8890		gl.textureStorage3DMultisample(m_to_3D_ms, 1, GL_R8, 0, 8, 8, false);
8891		is_ok &=
8892			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3DMultisample", "width is less than 1.");
8893
8894		gl.textureStorage3DMultisample(m_to_3D_ms, 1, GL_R8, 8, 0, 8, false);
8895		is_ok &=
8896			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3DMultisample", "height is less than 1.");
8897
8898		gl.textureStorage3DMultisample(m_to_3D_ms, 1, GL_R8, m_max_texture_size * 2, 8, 8, false);
8899		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3DMultisample",
8900								  "width is greater than the value of MAX_TEXTURE_SIZE.");
8901
8902		gl.textureStorage3DMultisample(m_to_3D_ms, 1, GL_R8, 8, m_max_texture_size * 2, 8, false);
8903		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3DMultisample",
8904								  "height is greater than the value of MAX_TEXTURE_SIZE.");
8905	}
8906
8907	/* Check that INVALID_VALUE is generated by TextureStorage3DMultisample if
8908	 depth is less than 1 or greater than the value of
8909	 MAX_ARRAY_TEXTURE_LAYERS. */
8910	{
8911		gl.textureStorage3DMultisample(m_to_3D_ms, 1, GL_R8, 8, 8, 0, false);
8912		is_ok &=
8913			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3DMultisample", "depth is less than 1.");
8914
8915		gl.textureStorage3DMultisample(m_to_3D_ms, 1, GL_R8, 8, 8, m_max_array_texture_layers * 2, false);
8916		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3DMultisample",
8917								  "depth is greater than the value of MAX_ARRAY_TEXTURE_LAYERS.");
8918	}
8919
8920	/* Check that INVALID_VALUE is generated by TextureStorage3DMultisample if
8921	 samples is greater than the value of MAX_SAMPLES. */
8922	{
8923		gl.textureStorage3DMultisample(m_to_3D_ms, m_max_samples * 2, GL_R8, 8, 8, 8, false);
8924		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage3DMultisample",
8925								  "samples is greater than the value of MAX_SAMPLES.");
8926	}
8927
8928	/* Check that INVALID_OPERATION is generated by TextureStorage3DMultisample
8929	 if the value of TEXTURE_IMMUTABLE_FORMAT for the texture bound to target
8930	 is not FALSE. */
8931	{
8932		gl.textureStorage3DMultisample(m_to_3D_ms_immutable, 1, GL_R8, 8, 8, 8, false);
8933		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage3DMultisample",
8934								  "samples is greater than the value of MAX_SAMPLES.");
8935	}
8936
8937	return is_ok;
8938}
8939
8940/** @brief Clean GL objects, test variables and GL errors.
8941 */
8942void StorageErrorsTest::Clean()
8943{
8944	/* Shortcut for GL functionality. */
8945	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8946
8947	/* Cleanup. */
8948	if (m_to_1D)
8949	{
8950		gl.deleteTextures(1, &m_to_1D);
8951
8952		m_to_1D = 0;
8953	}
8954
8955	if (m_to_1D_array)
8956	{
8957		gl.deleteTextures(1, &m_to_1D_array);
8958
8959		m_to_1D_array = 0;
8960	}
8961
8962	if (m_to_2D)
8963	{
8964		gl.deleteTextures(1, &m_to_2D);
8965
8966		m_to_2D = 0;
8967	}
8968
8969	if (m_to_2D_array)
8970	{
8971		gl.deleteTextures(1, &m_to_2D_array);
8972
8973		m_to_2D_array = 0;
8974	}
8975
8976	if (m_to_3D)
8977	{
8978		gl.deleteTextures(1, &m_to_3D);
8979
8980		m_to_3D = 0;
8981	}
8982
8983	if (m_to_2D_ms)
8984	{
8985		gl.deleteTextures(1, &m_to_2D_ms);
8986
8987		m_to_2D_ms = 0;
8988	}
8989
8990	if (m_to_2D_ms_immutable)
8991	{
8992		gl.deleteTextures(1, &m_to_2D_ms_immutable);
8993
8994		m_to_2D_ms_immutable = 0;
8995	}
8996
8997	if (m_to_3D_ms)
8998	{
8999		gl.deleteTextures(1, &m_to_3D_ms);
9000
9001		m_to_3D_ms = 0;
9002	}
9003
9004	if (m_to_3D_ms_immutable)
9005	{
9006		gl.deleteTextures(1, &m_to_3D_ms_immutable);
9007
9008		m_to_3D_ms_immutable = 0;
9009	}
9010
9011	m_to_invalid			   = 0;
9012	m_internalformat_invalid   = 0;
9013	m_max_texture_size		   = 1;
9014	m_max_samples			   = 1;
9015	m_max_array_texture_layers = 1;
9016
9017	while (GL_NO_ERROR != gl.getError())
9018		;
9019}
9020
9021/******************************** Texture SubImage Errors Test Implementation   ********************************/
9022
9023/** @brief Texture SubImage Errors Test constructor.
9024 *
9025 *  @param [in] context     OpenGL context.
9026 */
9027SubImageErrorsTest::SubImageErrorsTest(deqp::Context& context)
9028	: deqp::TestCase(context, "textures_subimage_errors", "Texture SubImage Errors Test")
9029	, m_to_1D_empty(0)
9030	, m_to_2D_empty(0)
9031	, m_to_3D_empty(0)
9032	, m_to_1D(0)
9033	, m_to_2D(0)
9034	, m_to_3D(0)
9035	, m_to_1D_compressed(0)
9036	, m_to_2D_compressed(0)
9037	, m_to_3D_compressed(0)
9038	, m_to_rectangle_compressed(0)
9039	, m_to_invalid(0)
9040	, m_bo(0)
9041	, m_format_invalid(0)
9042	, m_type_invalid(0)
9043	, m_max_texture_size(1)
9044	, m_reference_compressed_1D(DE_NULL)
9045	, m_reference_compressed_2D(DE_NULL)
9046	, m_reference_compressed_3D(DE_NULL)
9047	, m_reference_compressed_rectangle(DE_NULL)
9048	, m_reference_compressed_1D_size(0)
9049	, m_reference_compressed_2D_size(0)
9050	, m_reference_compressed_3D_size(0)
9051	, m_reference_compressed_rectangle_size(0)
9052	, m_reference_compressed_1D_format(0)
9053	, m_reference_compressed_2D_format(0)
9054	, m_reference_compressed_3D_format(0)
9055	, m_reference_compressed_rectangle_format(0)
9056	, m_not_matching_compressed_1D_format(0)
9057	, m_not_matching_compressed_1D_size(0)
9058	, m_not_matching_compressed_2D_format(0)
9059	, m_not_matching_compressed_2D_size(0)
9060	, m_not_matching_compressed_3D_format(0)
9061	, m_not_matching_compressed_3D_size(0)
9062{
9063	/* Intentionally left blank. */
9064}
9065
9066/** @brief Iterate Texture SubImage Errors Test cases.
9067 *
9068 *  @return Iteration result.
9069 */
9070tcu::TestNode::IterateResult SubImageErrorsTest::iterate()
9071{
9072	/* Get context setup. */
9073	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
9074	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
9075
9076	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
9077	{
9078		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
9079
9080		return STOP;
9081	}
9082
9083	/* Running tests. */
9084	bool is_ok	= true;
9085	bool is_error = false;
9086
9087	try
9088	{
9089		Prepare();
9090
9091		is_ok &= Test1D();
9092		is_ok &= Test2D();
9093		is_ok &= Test3D();
9094		is_ok &= Test1DCompressed();
9095		is_ok &= Test2DCompressed();
9096		is_ok &= Test3DCompressed();
9097	}
9098	catch (...)
9099	{
9100		is_ok	= false;
9101		is_error = true;
9102	}
9103
9104	/* Cleanup. */
9105	Clean();
9106
9107	/* Result's setup. */
9108	if (is_ok)
9109	{
9110		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
9111	}
9112	else
9113	{
9114		if (is_error)
9115		{
9116			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
9117		}
9118		else
9119		{
9120			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
9121		}
9122	}
9123
9124	return STOP;
9125}
9126
9127/** @brief Prepare test's objects.
9128 */
9129void SubImageErrorsTest::Prepare()
9130{
9131	/* Shortcut for GL functionality. */
9132	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9133
9134	/* Auxiliary objects setup. */
9135
9136	/* 1D */
9137	gl.createTextures(GL_TEXTURE_1D, 1, &m_to_1D_empty);
9138	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
9139
9140	/* 2D */
9141	gl.createTextures(GL_TEXTURE_2D, 1, &m_to_2D_empty);
9142	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
9143
9144	/* 3D */
9145	gl.createTextures(GL_TEXTURE_3D, 1, &m_to_3D_empty);
9146	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
9147
9148	/* 1D */
9149	gl.createTextures(GL_TEXTURE_1D, 1, &m_to_1D);
9150	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
9151
9152	gl.bindTexture(GL_TEXTURE_1D, m_to_1D);
9153	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
9154
9155	gl.texImage1D(GL_TEXTURE_1D, 0, s_reference_internalformat, s_reference_width, 0, s_reference_format,
9156				  GL_UNSIGNED_BYTE, s_reference);
9157	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");
9158
9159	/* 2D */
9160	gl.createTextures(GL_TEXTURE_2D, 1, &m_to_2D);
9161	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
9162
9163	gl.bindTexture(GL_TEXTURE_2D, m_to_2D);
9164	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
9165
9166	gl.texImage2D(GL_TEXTURE_2D, 0, s_reference_internalformat, s_reference_width, s_reference_height, 0,
9167				  s_reference_format, GL_UNSIGNED_BYTE, s_reference);
9168	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");
9169
9170	/* 3D */
9171	gl.createTextures(GL_TEXTURE_3D, 1, &m_to_3D);
9172	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
9173
9174	gl.bindTexture(GL_TEXTURE_3D, m_to_3D);
9175	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
9176
9177	gl.texImage3D(GL_TEXTURE_3D, 0, s_reference_internalformat, s_reference_width, s_reference_height,
9178				  s_reference_depth, 0, s_reference_format, GL_UNSIGNED_BYTE, s_reference);
9179	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");
9180
9181	/* 1D Compressed */
9182	gl.createTextures(GL_TEXTURE_1D, 1, &m_to_1D_compressed);
9183	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
9184
9185	gl.bindTexture(GL_TEXTURE_1D, m_to_1D_compressed);
9186	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
9187
9188	gl.texImage1D(GL_TEXTURE_1D, 0, s_reference_internalformat_compressed, s_reference_width, 0, s_reference_format,
9189				  GL_UNSIGNED_BYTE, s_reference);
9190	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");
9191
9192	glw::GLint is_compressed = 0;
9193
9194	gl.getTexLevelParameteriv(GL_TEXTURE_1D, 0, GL_TEXTURE_COMPRESSED, &is_compressed);
9195	GLU_EXPECT_NO_ERROR(gl.getError(), "glTetTexLevelParameteriv has failed");
9196
9197	if (is_compressed)
9198	{
9199		gl.getTexLevelParameteriv(GL_TEXTURE_1D, 0, GL_TEXTURE_INTERNAL_FORMAT, &m_reference_compressed_1D_format);
9200		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
9201
9202		m_reference_compressed_1D_size = 0;
9203
9204		gl.getTexLevelParameteriv(GL_TEXTURE_1D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &m_reference_compressed_1D_size);
9205		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
9206
9207		if (m_reference_compressed_1D_size)
9208		{
9209			m_reference_compressed_1D = new glw::GLubyte[m_reference_compressed_1D_size];
9210
9211			gl.getCompressedTexImage(GL_TEXTURE_1D, 0, m_reference_compressed_1D);
9212			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");
9213		}
9214	}
9215
9216	/* 2D Compressed */
9217	gl.createTextures(GL_TEXTURE_2D, 1, &m_to_2D_compressed);
9218	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
9219
9220	gl.bindTexture(GL_TEXTURE_2D, m_to_2D_compressed);
9221	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
9222
9223	gl.texImage2D(GL_TEXTURE_2D, 0, s_reference_internalformat_compressed, s_reference_width, s_reference_height, 0,
9224				  s_reference_format, GL_UNSIGNED_BYTE, s_reference);
9225	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");
9226
9227	is_compressed = 0;
9228
9229	gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED, &is_compressed);
9230	GLU_EXPECT_NO_ERROR(gl.getError(), "glTetTexLevelParameteriv has failed");
9231
9232	if (is_compressed)
9233	{
9234		gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &m_reference_compressed_2D_format);
9235		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
9236
9237		m_reference_compressed_2D_size = 0;
9238
9239		gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &m_reference_compressed_2D_size);
9240		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
9241
9242		if (m_reference_compressed_2D_size)
9243		{
9244			m_reference_compressed_2D = new glw::GLubyte[m_reference_compressed_2D_size];
9245
9246			gl.getCompressedTexImage(GL_TEXTURE_2D, 0, m_reference_compressed_2D);
9247			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");
9248		}
9249	}
9250
9251	/* 3D Compressed */
9252	gl.createTextures(GL_TEXTURE_2D_ARRAY, 1, &m_to_3D_compressed);
9253	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
9254
9255	gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_to_3D_compressed);
9256	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
9257
9258	gl.texImage3D(GL_TEXTURE_2D_ARRAY, 0, s_reference_internalformat_compressed, s_reference_width, s_reference_height,
9259				  s_reference_depth, 0, s_reference_format, GL_UNSIGNED_BYTE, s_reference);
9260	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage3D has failed");
9261
9262	is_compressed = 0;
9263
9264	gl.getTexLevelParameteriv(GL_TEXTURE_2D_ARRAY, 0, GL_TEXTURE_COMPRESSED, &is_compressed);
9265	GLU_EXPECT_NO_ERROR(gl.getError(), "glTetTexLevelParameteriv has failed");
9266
9267	if (is_compressed)
9268	{
9269		gl.getTexLevelParameteriv(GL_TEXTURE_2D_ARRAY, 0, GL_TEXTURE_INTERNAL_FORMAT,
9270								  &m_reference_compressed_3D_format);
9271		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
9272
9273		m_reference_compressed_3D_size = 0;
9274
9275		gl.getTexLevelParameteriv(GL_TEXTURE_2D_ARRAY, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE,
9276								  &m_reference_compressed_3D_size);
9277		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
9278
9279		if (m_reference_compressed_3D_size)
9280		{
9281			m_reference_compressed_3D = new glw::GLubyte[m_reference_compressed_3D_size];
9282
9283			gl.getCompressedTexImage(GL_TEXTURE_2D_ARRAY, 0, m_reference_compressed_3D);
9284			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");
9285		}
9286	}
9287
9288	/* RECTANGLE Compressed */
9289	gl.createTextures(GL_TEXTURE_RECTANGLE, 1, &m_to_rectangle_compressed);
9290	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
9291
9292	gl.bindTexture(GL_TEXTURE_RECTANGLE, m_to_rectangle_compressed);
9293	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
9294
9295	gl.texImage2D(GL_TEXTURE_RECTANGLE, 0, s_reference_internalformat_compressed, s_reference_width, s_reference_height,
9296				  0, s_reference_format, GL_UNSIGNED_BYTE, s_reference);
9297	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");
9298
9299	is_compressed = 0;
9300
9301	gl.getTexLevelParameteriv(GL_TEXTURE_RECTANGLE, 0, GL_TEXTURE_COMPRESSED, &is_compressed);
9302	GLU_EXPECT_NO_ERROR(gl.getError(), "glTetTexLevelParameteriv has failed");
9303
9304	if (is_compressed)
9305	{
9306		gl.getTexLevelParameteriv(GL_TEXTURE_RECTANGLE, 0, GL_TEXTURE_INTERNAL_FORMAT,
9307								  &m_reference_compressed_rectangle_format);
9308		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
9309
9310		m_reference_compressed_rectangle_size = 0;
9311
9312		gl.getTexLevelParameteriv(GL_TEXTURE_RECTANGLE, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE,
9313								  &m_reference_compressed_rectangle_size);
9314		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
9315
9316		if (m_reference_compressed_rectangle_size)
9317		{
9318			m_reference_compressed_rectangle = new glw::GLubyte[m_reference_compressed_rectangle_size];
9319
9320			gl.getCompressedTexImage(GL_TEXTURE_RECTANGLE, 0, m_reference_compressed_rectangle);
9321			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");
9322		}
9323	}
9324
9325	/* Buffer object */
9326	gl.createBuffers(1, &m_bo);
9327	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers has failed");
9328
9329	gl.namedBufferData(m_bo, s_reference_size, s_reference, GL_STATIC_COPY);
9330	GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData has failed");
9331
9332	/* Invalid values */
9333
9334	/* invalid texture object */
9335	while (gl.isTexture(++m_to_invalid))
9336		;
9337	GLU_EXPECT_NO_ERROR(gl.getError(), "glIsTexture has failed");
9338
9339	/* invalid internal format */
9340	static const glw::GLenum all_formats[] = { GL_STENCIL_INDEX,
9341											   GL_DEPTH_COMPONENT,
9342											   GL_DEPTH_STENCIL,
9343											   GL_RED,
9344											   GL_GREEN,
9345											   GL_BLUE,
9346											   GL_RG,
9347											   GL_RGB,
9348											   GL_RGBA,
9349											   GL_BGR,
9350											   GL_BGRA,
9351											   GL_RED_INTEGER,
9352											   GL_GREEN_INTEGER,
9353											   GL_BLUE_INTEGER,
9354											   GL_RG_INTEGER,
9355											   GL_RGB_INTEGER,
9356											   GL_RGBA_INTEGER,
9357											   GL_BGR_INTEGER,
9358											   GL_BGRA_INTEGER };
9359
9360	static const glw::GLuint all_internal_formats_count = sizeof(all_formats) / sizeof(all_formats[0]);
9361
9362	bool is_valid	= true;
9363	m_format_invalid = 0;
9364
9365	while (is_valid)
9366	{
9367		is_valid = false;
9368		m_format_invalid++;
9369		for (glw::GLuint i = 0; i < all_internal_formats_count; ++i)
9370		{
9371			if (all_formats[i] == m_format_invalid)
9372			{
9373				is_valid = true;
9374				break;
9375			}
9376		}
9377	}
9378
9379	/* Invalid type. */
9380	static const glw::GLenum all_types[] = { GL_UNSIGNED_BYTE,
9381											 GL_BYTE,
9382											 GL_UNSIGNED_SHORT,
9383											 GL_SHORT,
9384											 GL_UNSIGNED_INT,
9385											 GL_INT,
9386											 GL_HALF_FLOAT,
9387											 GL_FLOAT,
9388											 GL_UNSIGNED_BYTE_3_3_2,
9389											 GL_UNSIGNED_BYTE_2_3_3_REV,
9390											 GL_UNSIGNED_SHORT_5_6_5,
9391											 GL_UNSIGNED_SHORT_5_6_5_REV,
9392											 GL_UNSIGNED_SHORT_4_4_4_4,
9393											 GL_UNSIGNED_SHORT_4_4_4_4_REV,
9394											 GL_UNSIGNED_SHORT_5_5_5_1,
9395											 GL_UNSIGNED_SHORT_1_5_5_5_REV,
9396											 GL_UNSIGNED_INT_8_8_8_8,
9397											 GL_UNSIGNED_INT_8_8_8_8_REV,
9398											 GL_UNSIGNED_INT_10_10_10_2,
9399											 GL_UNSIGNED_INT_2_10_10_10_REV,
9400											 GL_UNSIGNED_INT_24_8,
9401											 GL_UNSIGNED_INT_10F_11F_11F_REV,
9402											 GL_UNSIGNED_INT_5_9_9_9_REV,
9403											 GL_FLOAT_32_UNSIGNED_INT_24_8_REV };
9404
9405	static const glw::GLuint all_types_count = sizeof(all_types) / sizeof(all_types[0]);
9406
9407	is_valid	   = true;
9408	m_type_invalid = 0;
9409
9410	while (is_valid)
9411	{
9412		is_valid = false;
9413		m_type_invalid++;
9414		for (glw::GLuint i = 0; i < all_types_count; ++i)
9415		{
9416			if (all_types[i] == m_type_invalid)
9417			{
9418				is_valid = true;
9419				break;
9420			}
9421		}
9422	}
9423
9424	/* Maximum texture size.*/
9425	gl.getIntegerv(GL_MAX_TEXTURE_SIZE, &m_max_texture_size);
9426	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");
9427
9428	glw::GLenum not_matching_format					   = GL_RED;
9429	glw::GLenum not_matching_internalformat_compressed = GL_COMPRESSED_RED;
9430
9431	/* 1D Compressed with a non matching format. We need to do all the allocation to get the correct image size */
9432	glw::GLuint to_1D_compressed_not_matching;
9433
9434	gl.createTextures(GL_TEXTURE_1D, 1, &to_1D_compressed_not_matching);
9435	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
9436
9437	gl.bindTexture(GL_TEXTURE_1D, to_1D_compressed_not_matching);
9438	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
9439
9440	gl.texImage1D(GL_TEXTURE_1D, 0, not_matching_internalformat_compressed, s_reference_width, 0, s_reference_format,
9441				  GL_UNSIGNED_BYTE, s_reference);
9442	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");
9443
9444	is_compressed = 0;
9445
9446	gl.getTexLevelParameteriv(GL_TEXTURE_1D, 0, GL_TEXTURE_COMPRESSED, &is_compressed);
9447	GLU_EXPECT_NO_ERROR(gl.getError(), "glTetTexLevelParameteriv has failed");
9448
9449	if (is_compressed)
9450	{
9451		gl.getTexLevelParameteriv(GL_TEXTURE_1D, 0, GL_TEXTURE_INTERNAL_FORMAT, &m_not_matching_compressed_1D_format);
9452		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
9453
9454		m_not_matching_compressed_1D_size = 0;
9455
9456		gl.getTexLevelParameteriv(GL_TEXTURE_1D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE,
9457								  &m_not_matching_compressed_1D_size);
9458		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
9459	}
9460
9461	gl.deleteTextures(1, &to_1D_compressed_not_matching);
9462	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
9463
9464	/* 2D Compressed with a non matching format. We need to do all the allocation to get the correct image size */
9465	glw::GLuint to_2D_compressed_not_matching;
9466
9467	gl.createTextures(GL_TEXTURE_2D, 1, &to_2D_compressed_not_matching);
9468	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
9469
9470	gl.bindTexture(GL_TEXTURE_2D, to_2D_compressed_not_matching);
9471	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
9472
9473	gl.texImage2D(GL_TEXTURE_2D, 0, not_matching_internalformat_compressed, s_reference_width, s_reference_height, 0,
9474				  not_matching_format, GL_UNSIGNED_BYTE, s_reference);
9475	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");
9476
9477	is_compressed = 0;
9478
9479	gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED, &is_compressed);
9480	GLU_EXPECT_NO_ERROR(gl.getError(), "glTetTexLevelParameteriv has failed");
9481
9482	if (is_compressed)
9483	{
9484		gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &m_not_matching_compressed_2D_format);
9485		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
9486
9487		m_not_matching_compressed_2D_size = 0;
9488
9489		gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE,
9490								  &m_not_matching_compressed_2D_size);
9491		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
9492	}
9493
9494	gl.deleteTextures(1, &to_2D_compressed_not_matching);
9495	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
9496
9497	/* 3D Compressed with a non matching format. We need to do all the allocation to get the correct image size */
9498	glw::GLuint to_3D_compressed_not_matching;
9499
9500	gl.createTextures(GL_TEXTURE_3D, 1, &to_3D_compressed_not_matching);
9501	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
9502
9503	gl.bindTexture(GL_TEXTURE_3D, to_3D_compressed_not_matching);
9504	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
9505
9506	gl.texImage3D(GL_TEXTURE_3D, 0, not_matching_internalformat_compressed, s_reference_width, s_reference_height,
9507				  s_reference_depth, 0, not_matching_format, GL_UNSIGNED_BYTE, s_reference);
9508	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage3D has failed");
9509
9510	is_compressed = 0;
9511
9512	gl.getTexLevelParameteriv(GL_TEXTURE_3D, 0, GL_TEXTURE_COMPRESSED, &is_compressed);
9513	GLU_EXPECT_NO_ERROR(gl.getError(), "glTetTexLevelParameteriv has failed");
9514
9515	if (is_compressed)
9516	{
9517		gl.getTexLevelParameteriv(GL_TEXTURE_3D, 0, GL_TEXTURE_INTERNAL_FORMAT, &m_not_matching_compressed_3D_format);
9518		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
9519
9520		m_not_matching_compressed_3D_size = 0;
9521
9522		gl.getTexLevelParameteriv(GL_TEXTURE_3D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE,
9523								  &m_not_matching_compressed_3D_size);
9524		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
9525	}
9526
9527	gl.deleteTextures(1, &to_3D_compressed_not_matching);
9528	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
9529}
9530
9531/** @brief Test (negative) of TextureSubImage1D
9532 *
9533 *  @return Test result.
9534 */
9535bool SubImageErrorsTest::Test1D()
9536{
9537	/* Shortcut for GL functionality. */
9538	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9539
9540	/* Result. */
9541	bool is_ok = true;
9542
9543	/* Check that INVALID_OPERATION is generated by TextureSubImage1D if
9544	 texture is not the name of an existing texture object. */
9545	{
9546		gl.textureSubImage1D(m_to_invalid, 0, 0, s_reference_width, s_reference_format, s_reference_type, s_reference);
9547		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
9548								  "texture is not the name of an existing texture object.");
9549	}
9550
9551	/* Check that INVALID_ENUM is generated by TextureSubImage1D if format is
9552	 not an accepted format constant. */
9553	{
9554		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, m_format_invalid, s_reference_type, s_reference);
9555		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureSubImage1D",
9556								  "format is not an accepted format constant.");
9557	}
9558
9559	/* Check that INVALID_ENUM is generated by TextureSubImage1D if type is not
9560	 an accepted type constant. */
9561	{
9562		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, m_type_invalid, s_reference);
9563		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureSubImage1D",
9564								  "type is not an accepted type constant.");
9565	}
9566
9567	/* Check that INVALID_VALUE is generated by TextureSubImage1D if level is
9568	 less than 0. */
9569	{
9570		gl.textureSubImage1D(m_to_1D, -1, 0, s_reference_width, s_reference_format, s_reference_type, s_reference);
9571		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage1D", "level is less than 0.");
9572	}
9573
9574	/* Check that INVALID_VALUE may be generated by TextureSubImage1D if level
9575	 is greater than log2 max, where max is the returned value of
9576	 MAX_TEXTURE_SIZE. */
9577	{
9578		gl.textureSubImage1D(m_to_1D, m_max_texture_size, 0, s_reference_width, s_reference_format, s_reference_type,
9579							 s_reference);
9580		is_ok &=
9581			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage1D",
9582							 "level is greater than log2 max, where max is the returned value of MAX_TEXTURE_SIZE.");
9583	}
9584
9585	/* Check that INVALID_VALUE is generated by TextureSubImage1D if
9586	 xoffset<-b, or if (xoffset+width)>(w-b), where w is the TEXTURE_WIDTH,
9587	 and b is the width of the TEXTURE_BORDER of the texture image being
9588	 modified. Note that w includes twice the border width. */
9589	{
9590		gl.textureSubImage1D(m_to_1D, 0, -1, s_reference_width, s_reference_format, s_reference_type, s_reference);
9591		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage1D",
9592								  "xoffset<-b, where b is the width of the TEXTURE_BORDER.");
9593
9594		gl.textureSubImage1D(m_to_1D, 0, 1, s_reference_width + 1, s_reference_format, s_reference_type, s_reference);
9595		is_ok &= CheckErrorAndLog(
9596			m_context, GL_INVALID_VALUE, "glTextureSubImage1D",
9597			"(xoffset+width)>(w-b), where w is the TEXTURE_WIDTH, b is the width of the TEXTURE_BORDER.");
9598	}
9599
9600	/*Check that INVALID_VALUE is generated by TextureSubImage1D if width is less than 0. */
9601	{
9602#ifndef TURN_OFF_SUB_IMAGE_ERRORS_TEST_OF_NEGATIVE_WIDTH_HEIGHT_OR_DEPTH
9603		gl.textureSubImage1D(m_to_1D, 0, 0, -1, s_reference_format, s_reference_type, s_reference);
9604		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage1D", "width is less than 0.");
9605#endif
9606	}
9607
9608	/* Check that INVALID_OPERATION is generated by TextureSubImage1D if type
9609	 is one of UNSIGNED_BYTE_3_3_2, UNSIGNED_BYTE_2_3_3_REV,
9610	 UNSIGNED_SHORT_5_6_5, or UNSIGNED_SHORT_5_6_5_REV and format is not RGB. */
9611	{
9612		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_BYTE_3_3_2, s_reference);
9613		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
9614								  "type is UNSIGNED_BYTE_3_3_2 and format is not RGB.");
9615
9616		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_BYTE_2_3_3_REV,
9617							 s_reference);
9618		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
9619								  "type is UNSIGNED_BYTE_2_3_3_REV and format is not RGB.");
9620
9621		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_SHORT_5_6_5,
9622							 s_reference);
9623		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
9624								  "type is UNSIGNED_SHORT_5_6_5 and format is not RGB.");
9625
9626		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_SHORT_5_6_5_REV,
9627							 s_reference);
9628		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
9629								  "type is UNSIGNED_SHORT_5_6_5_REV and format is not RGB.");
9630	}
9631
9632	/* Check that INVALID_OPERATION is generated by TextureSubImage1D if type
9633	 is one of UNSIGNED_SHORT_4_4_4_4, UNSIGNED_SHORT_4_4_4_4_REV,
9634	 UNSIGNED_SHORT_5_5_5_1, UNSIGNED_SHORT_1_5_5_5_REV,
9635	 UNSIGNED_INT_8_8_8_8, UNSIGNED_INT_8_8_8_8_REV, UNSIGNED_INT_10_10_10_2,
9636	 or UNSIGNED_INT_2_10_10_10_REV and format is neither RGBA nor BGRA. */
9637	{
9638		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_SHORT_4_4_4_4,
9639							 s_reference);
9640		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
9641								  "type is UNSIGNED_SHORT_4_4_4_4 and format is neither RGBA nor BGRA.");
9642
9643		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_SHORT_4_4_4_4_REV,
9644							 s_reference);
9645		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
9646								  "type is UNSIGNED_SHORT_4_4_4_4_REV and format is neither RGBA nor BGRA.");
9647
9648		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_SHORT_5_5_5_1,
9649							 s_reference);
9650		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
9651								  "type is UNSIGNED_SHORT_5_5_5_1 and format is neither RGBA nor BGRA.");
9652
9653		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_SHORT_1_5_5_5_REV,
9654							 s_reference);
9655		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
9656								  "type is UNSIGNED_SHORT_1_5_5_5_REV and format is neither RGBA nor BGRA.");
9657
9658		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_INT_8_8_8_8,
9659							 s_reference);
9660		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
9661								  "type is UNSIGNED_INT_8_8_8_8 and format is neither RGBA nor BGRA.");
9662
9663		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_INT_8_8_8_8_REV,
9664							 s_reference);
9665		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
9666								  "type is UNSIGNED_INT_8_8_8_8_REV and format is neither RGBA nor BGRA.");
9667
9668		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_INT_10_10_10_2,
9669							 s_reference);
9670		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
9671								  "type is UNSIGNED_INT_10_10_10_2 and format is neither RGBA nor BGRA.");
9672
9673		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_INT_2_10_10_10_REV,
9674							 s_reference);
9675		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
9676								  "type is UNSIGNED_INT_2_10_10_10_REV and format is neither RGBA nor BGRA.");
9677	}
9678
9679	/* Check that INVALID_OPERATION is generated by TextureSubImage1D if a
9680	 non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target
9681	 and the buffer object's data store is currently mapped. */
9682	{
9683		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
9684		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
9685
9686		gl.mapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE);
9687
9688		if (GL_NO_ERROR == gl.getError())
9689		{
9690			gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, s_reference_type, NULL);
9691			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
9692									  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and "
9693									  "the buffer object's data store is currently mapped.");
9694
9695			gl.unmapBuffer(GL_PIXEL_UNPACK_BUFFER);
9696			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
9697
9698			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
9699			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
9700		}
9701	}
9702
9703	/* Check that INVALID_OPERATION is generated by TextureSubImage1D if a
9704	 non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target
9705	 and the data would be unpacked from the buffer object such that the
9706	 memory reads required would exceed the data store size. */
9707	{
9708		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
9709		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
9710
9711		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, s_reference_type,
9712							 (glw::GLubyte*)NULL + s_reference_size * 2);
9713		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
9714								  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and the "
9715								  "data would be unpacked from the buffer object such that the memory reads required "
9716								  "would exceed the data store size.");
9717
9718		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
9719		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
9720	}
9721
9722	/* Check that INVALID_OPERATION is generated by TextureSubImage1D if a
9723	 non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target
9724	 and pixels is not evenly divisible into the number of bytes needed to
9725	 store in memory a datum indicated by type. */
9726	{
9727		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
9728		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
9729
9730		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, s_reference_type,
9731							 (glw::GLubyte*)NULL + 1);
9732		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
9733								  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and pixels "
9734								  "is not evenly divisible into the number of bytes needed to store in memory a datum "
9735								  "indicated by type.");
9736
9737		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
9738		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
9739	}
9740
9741	return is_ok;
9742}
9743
9744/** @brief Test (negative) of TextureSubImage2D
9745 *
9746 *  @return Test result.
9747 */
9748bool SubImageErrorsTest::Test2D()
9749{
9750	/* Shortcut for GL functionality. */
9751	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9752
9753	/* Result. */
9754	bool is_ok = true;
9755
9756	/* Check that INVALID_OPERATION is generated by TextureSubImage2D if
9757	 texture is not the name of an existing texture object. */
9758	{
9759		gl.textureSubImage2D(m_to_invalid, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
9760							 s_reference_type, s_reference);
9761		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
9762								  "texture is not the name of an existing texture object.");
9763	}
9764
9765	/* Check that INVALID_ENUM is generated by TextureSubImage2D if format is
9766	 not an accepted format constant. */
9767	{
9768		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, m_format_invalid,
9769							 s_reference_type, s_reference);
9770		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureSubImage2D",
9771								  "format is not an accepted format constant.");
9772	}
9773
9774	/* Check that INVALID_ENUM is generated by TextureSubImage2D if type is not
9775	 an accepted type constant. */
9776	{
9777		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
9778							 m_type_invalid, s_reference);
9779		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureSubImage2D",
9780								  "type is not an accepted type constant.");
9781	}
9782
9783	/* Check that INVALID_VALUE is generated by TextureSubImage2D if level is
9784	 less than 0. */
9785	{
9786		gl.textureSubImage2D(m_to_2D, -1, 0, 0, s_reference_width, s_reference_height, s_reference_format,
9787							 s_reference_type, s_reference);
9788		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage2D", "level is less than 0.");
9789	}
9790
9791	/* Check that INVALID_VALUE may be generated by TextureSubImage2D if level
9792	 is greater than log2 max, where max is the returned value of
9793	 MAX_TEXTURE_SIZE. */
9794	{
9795		gl.textureSubImage2D(m_to_2D, m_max_texture_size, 0, 0, s_reference_width, s_reference_height,
9796							 s_reference_format, s_reference_type, s_reference);
9797		is_ok &=
9798			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage2D",
9799							 "level is greater than log2 max, where max is the returned value of MAX_TEXTURE_SIZE.");
9800	}
9801
9802	/* Check that INVALID_VALUE may be generated by TextureSubImage2D if level
9803	 is greater than log2 max, where max is the returned value of
9804	 MAX_TEXTURE_SIZE.
9805	 Check that INVALID_VALUE is generated by TextureSubImage2D if
9806	 xoffset<-b, (xoffset+width)>(w-b), yoffset<-b, or
9807	 (yoffset+height)>(h-b), where w is the TEXTURE_WIDTH, h is the
9808	 TEXTURE_HEIGHT, and b is the border width of the texture image being
9809	 modified. Note that w and h include twice the border width. */
9810	{
9811		gl.textureSubImage2D(m_to_2D, 0, -1, 0, s_reference_width, s_reference_height, s_reference_format,
9812							 s_reference_type, s_reference);
9813		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage2D",
9814								  "xoffset<-b, where b is the width of the TEXTURE_BORDER.");
9815
9816		gl.textureSubImage2D(m_to_2D, 0, 1, 0, s_reference_width + 1, s_reference_height, s_reference_format,
9817							 s_reference_type, s_reference);
9818		is_ok &= CheckErrorAndLog(
9819			m_context, GL_INVALID_VALUE, "glTextureSubImage2D",
9820			"(xoffset+width)>(w-b), where w is the TEXTURE_WIDTH, b is the width of the TEXTURE_BORDER.");
9821
9822		gl.textureSubImage2D(m_to_2D, 0, 0, -1, s_reference_width, s_reference_height, s_reference_format,
9823							 s_reference_type, s_reference);
9824		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage2D",
9825								  "yoffset<-b, where b is the height of the TEXTURE_BORDER.");
9826
9827		gl.textureSubImage2D(m_to_2D, 0, 0, 1, s_reference_width + 1, s_reference_height, s_reference_format,
9828							 s_reference_type, s_reference);
9829		is_ok &= CheckErrorAndLog(
9830			m_context, GL_INVALID_VALUE, "glTextureSubImage2D",
9831			"(yoffset+height)>(h-b), where h is the TEXTURE_HEIGHT, b is the width of the TEXTURE_BORDER.");
9832	}
9833
9834	/*Check that INVALID_VALUE is generated by TextureSubImage2D if width or height is less than 0. */
9835	{
9836#ifndef TURN_OFF_SUB_IMAGE_ERRORS_TEST_OF_NEGATIVE_WIDTH_HEIGHT_OR_DEPTH
9837		gl.textureSubImage2D(m_to_2D, 0, 0, 0, -1, s_reference_height, s_reference_format, s_reference_type,
9838							 s_reference);
9839		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage2D", "width is less than 0.");
9840
9841		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, -1, s_reference_format, s_reference_type,
9842							 s_reference);
9843		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage2D", "height is less than 0.");
9844#endif
9845	}
9846
9847	/* Check that INVALID_OPERATION is generated by TextureSubImage2D if type
9848	 is one of UNSIGNED_BYTE_3_3_2, UNSIGNED_BYTE_2_3_3_REV,
9849	 UNSIGNED_SHORT_5_6_5, or UNSIGNED_SHORT_5_6_5_REV and format is not RGB. */
9850	{
9851		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
9852							 GL_UNSIGNED_BYTE_3_3_2, s_reference);
9853		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
9854								  "type is UNSIGNED_BYTE_3_3_2 and format is not RGB.");
9855
9856		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
9857							 GL_UNSIGNED_BYTE_2_3_3_REV, s_reference);
9858		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
9859								  "type is UNSIGNED_BYTE_2_3_3_REV and format is not RGB.");
9860
9861		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
9862							 GL_UNSIGNED_SHORT_5_6_5, s_reference);
9863		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
9864								  "type is UNSIGNED_SHORT_5_6_5 and format is not RGB.");
9865
9866		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
9867							 GL_UNSIGNED_SHORT_5_6_5_REV, s_reference);
9868		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
9869								  "type is UNSIGNED_SHORT_5_6_5_REV and format is not RGB.");
9870	}
9871
9872	/* Check that INVALID_OPERATION is generated by TextureSubImage2D if type
9873	 is one of UNSIGNED_SHORT_4_4_4_4, UNSIGNED_SHORT_4_4_4_4_REV,
9874	 UNSIGNED_SHORT_5_5_5_1, UNSIGNED_SHORT_1_5_5_5_REV,
9875	 UNSIGNED_INT_8_8_8_8, UNSIGNED_INT_8_8_8_8_REV, UNSIGNED_INT_10_10_10_2,
9876	 or UNSIGNED_INT_2_10_10_10_REV and format is neither RGBA nor BGRA. */
9877	{
9878		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
9879							 GL_UNSIGNED_SHORT_4_4_4_4, s_reference);
9880		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
9881								  "type is UNSIGNED_SHORT_4_4_4_4 and format is neither RGBA nor BGRA.");
9882
9883		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
9884							 GL_UNSIGNED_SHORT_4_4_4_4_REV, s_reference);
9885		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
9886								  "type is UNSIGNED_SHORT_4_4_4_4_REV and format is neither RGBA nor BGRA.");
9887
9888		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
9889							 GL_UNSIGNED_SHORT_5_5_5_1, s_reference);
9890		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
9891								  "type is UNSIGNED_SHORT_5_5_5_1 and format is neither RGBA nor BGRA.");
9892
9893		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
9894							 GL_UNSIGNED_SHORT_1_5_5_5_REV, s_reference);
9895		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
9896								  "type is UNSIGNED_SHORT_1_5_5_5_REV and format is neither RGBA nor BGRA.");
9897
9898		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
9899							 GL_UNSIGNED_INT_8_8_8_8, s_reference);
9900		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
9901								  "type is UNSIGNED_INT_8_8_8_8 and format is neither RGBA nor BGRA.");
9902
9903		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
9904							 GL_UNSIGNED_INT_8_8_8_8_REV, s_reference);
9905		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
9906								  "type is UNSIGNED_INT_8_8_8_8_REV and format is neither RGBA nor BGRA.");
9907
9908		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
9909							 GL_UNSIGNED_INT_10_10_10_2, s_reference);
9910		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
9911								  "type is UNSIGNED_INT_10_10_10_2 and format is neither RGBA nor BGRA.");
9912
9913		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
9914							 GL_UNSIGNED_INT_2_10_10_10_REV, s_reference);
9915		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
9916								  "type is UNSIGNED_INT_2_10_10_10_REV and format is neither RGBA nor BGRA.");
9917	}
9918
9919	/* Check that INVALID_OPERATION is generated by TextureSubImage2D if a
9920	 non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target
9921	 and the buffer object's data store is currently mapped. */
9922	{
9923		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
9924		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
9925
9926		gl.mapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE);
9927
9928		if (GL_NO_ERROR == gl.getError())
9929		{
9930			gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
9931								 s_reference_type, NULL);
9932			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
9933									  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and "
9934									  "the buffer object's data store is currently mapped.");
9935
9936			gl.unmapBuffer(GL_PIXEL_UNPACK_BUFFER);
9937			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
9938
9939			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
9940			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
9941		}
9942	}
9943
9944	/* Check that INVALID_OPERATION is generated by TextureSubImage2D if a
9945	 non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target
9946	 and the data would be unpacked from the buffer object such that the
9947	 memory reads required would exceed the data store size. */
9948	{
9949		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
9950		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
9951
9952		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
9953							 s_reference_type, (glw::GLubyte*)NULL + s_reference_size * 2);
9954		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
9955								  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and the "
9956								  "data would be unpacked from the buffer object such that the memory reads required "
9957								  "would exceed the data store size.");
9958
9959		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
9960		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
9961	}
9962
9963	/* Check that INVALID_OPERATION is generated by TextureSubImage2D if a
9964	 non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target
9965	 and pixels is not evenly divisible into the number of bytes needed to
9966	 store in memory a datum indicated by type. */
9967	{
9968		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
9969		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
9970
9971		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
9972							 s_reference_type, (glw::GLubyte*)NULL + 1);
9973		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
9974								  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and pixels "
9975								  "is not evenly divisible into the number of bytes needed to store in memory a datum "
9976								  "indicated by type.");
9977
9978		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
9979		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
9980	}
9981
9982	return is_ok;
9983}
9984
9985/** @brief Test (negative) of TextureSubImage3D
9986 *
9987 *  @return Test result.
9988 */
9989bool SubImageErrorsTest::Test3D()
9990{
9991	/* Shortcut for GL functionality. */
9992	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9993
9994	/* Result. */
9995	bool is_ok = true;
9996
9997	/* Check that INVALID_OPERATION is generated by TextureSubImage3D if
9998	 texture is not the name of an existing texture object. */
9999	{
10000		gl.textureSubImage3D(m_to_invalid, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10001							 s_reference_format, s_reference_type, s_reference);
10002		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
10003								  "texture is not the name of an existing texture object.");
10004	}
10005
10006	/* Check that INVALID_ENUM is generated by TextureSubImage3D if format is
10007	 not an accepted format constant. */
10008	{
10009		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10010							 m_format_invalid, s_reference_type, s_reference);
10011		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureSubImage3D",
10012								  "format is not an accepted format constant.");
10013	}
10014
10015	/* Check that INVALID_ENUM is generated by TextureSubImage3D if type is not
10016	 an accepted type constant. */
10017	{
10018		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10019							 s_reference_format, m_type_invalid, s_reference);
10020		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureSubImage3D",
10021								  "type is not an accepted type constant.");
10022	}
10023
10024	/* Check that INVALID_VALUE is generated by TextureSubImage3D if level is
10025	 less than 0. */
10026	{
10027		gl.textureSubImage3D(m_to_3D, -1, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10028							 s_reference_format, s_reference_type, s_reference);
10029		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage3D", "level is less than 0.");
10030	}
10031
10032	/* Check that INVALID_VALUE may be generated by TextureSubImage1D if level
10033	 is greater than log2 max, where max is the returned value of
10034	 MAX_TEXTURE_SIZE. */
10035	{
10036		gl.textureSubImage3D(m_to_3D, m_max_texture_size, 0, 0, 0, s_reference_width, s_reference_height,
10037							 s_reference_depth, s_reference_format, s_reference_type, s_reference);
10038		is_ok &=
10039			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage3D",
10040							 "level is greater than log2 max, where max is the returned value of MAX_TEXTURE_SIZE.");
10041	}
10042
10043	/* Check that INVALID_VALUE is generated by TextureSubImage3D if
10044	 xoffset<-b, (xoffset+width)>(w-b), yoffset<-b, or
10045	 (yoffset+height)>(h-b), or zoffset<-b, or (zoffset+depth)>(d-b), where w
10046	 is the TEXTURE_WIDTH, h is the TEXTURE_HEIGHT, d is the TEXTURE_DEPTH
10047	 and b is the border width of the texture image being modified. Note
10048	 that w, h, and d include twice the border width. */
10049	{
10050		gl.textureSubImage3D(m_to_3D, 0, -1, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10051							 s_reference_format, s_reference_type, s_reference);
10052		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage3D",
10053								  "xoffset<-b, where b is the width of the TEXTURE_BORDER.");
10054
10055		gl.textureSubImage3D(m_to_3D, 0, 1, 0, 0, s_reference_width + 1, s_reference_height, s_reference_depth,
10056							 s_reference_format, s_reference_type, s_reference);
10057		is_ok &= CheckErrorAndLog(
10058			m_context, GL_INVALID_VALUE, "glTextureSubImage3D",
10059			"(xoffset+width)>(w-b), where w is the TEXTURE_WIDTH, b is the width of the TEXTURE_BORDER.");
10060
10061		gl.textureSubImage3D(m_to_3D, 0, 0, -1, 0, s_reference_width, s_reference_height, s_reference_depth,
10062							 s_reference_format, s_reference_type, s_reference);
10063		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage3D",
10064								  "yoffset<-b, where b is the width of the TEXTURE_BORDER.");
10065
10066		gl.textureSubImage3D(m_to_3D, 0, 0, 1, 0, s_reference_width + 1, s_reference_height, s_reference_depth,
10067							 s_reference_format, s_reference_type, s_reference);
10068		is_ok &= CheckErrorAndLog(
10069			m_context, GL_INVALID_VALUE, "glTextureSubImage3D",
10070			"(yoffset+height)>(h-b), where h is the TEXTURE_HEIGHT, b is the width of the TEXTURE_BORDER.");
10071
10072		gl.textureSubImage3D(m_to_3D, 0, 0, 0, -1, s_reference_width, s_reference_height, s_reference_depth,
10073							 s_reference_format, s_reference_type, s_reference);
10074		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage3D",
10075								  "zoffset<-b, where b is the depth of the TEXTURE_BORDER.");
10076
10077		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 1, s_reference_width + 1, s_reference_height, s_reference_depth,
10078							 s_reference_format, s_reference_type, s_reference);
10079		is_ok &= CheckErrorAndLog(
10080			m_context, GL_INVALID_VALUE, "glTextureSubImage3D",
10081			"(zoffset+width)>(d-b), where d is the TEXTURE_DEPTH, b is the width of the TEXTURE_BORDER.");
10082	}
10083
10084	/*Check that INVALID_VALUE is generated by TextureSubImage3D if width or height or depth is less than 0. */
10085	{
10086#ifndef TURN_OFF_SUB_IMAGE_ERRORS_TEST_OF_NEGATIVE_WIDTH_HEIGHT_OR_DEPTH
10087		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, -1, s_reference_height, s_reference_depth, s_reference_format,
10088							 s_reference_type, s_reference);
10089		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage1D", "width is less than 0.");
10090
10091		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, -1, s_reference_depth, s_reference_format,
10092							 s_reference_type, s_reference);
10093		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage1D", "height is less than 0.");
10094
10095		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, -1, s_reference_format,
10096							 s_reference_type, s_reference);
10097		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage1D", "depth is less than 0.");
10098#endif
10099	}
10100
10101	/* Check that INVALID_OPERATION is generated by TextureSubImage3D if type
10102	 is one of UNSIGNED_BYTE_3_3_2, UNSIGNED_BYTE_2_3_3_REV,
10103	 UNSIGNED_SHORT_5_6_5, or UNSIGNED_SHORT_5_6_5_REV and format is not RGB. */
10104	{
10105		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10106							 s_reference_format, GL_UNSIGNED_BYTE_3_3_2, s_reference);
10107		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
10108								  "type is UNSIGNED_BYTE_3_3_2 and format is not RGB.");
10109
10110		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10111							 s_reference_format, GL_UNSIGNED_BYTE_2_3_3_REV, s_reference);
10112		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
10113								  "type is UNSIGNED_BYTE_2_3_3_REV and format is not RGB.");
10114
10115		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10116							 s_reference_format, GL_UNSIGNED_SHORT_5_6_5, s_reference);
10117		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
10118								  "type is UNSIGNED_SHORT_5_6_5 and format is not RGB.");
10119
10120		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10121							 s_reference_format, GL_UNSIGNED_SHORT_5_6_5_REV, s_reference);
10122		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
10123								  "type is UNSIGNED_SHORT_5_6_5_REV and format is not RGB.");
10124	}
10125
10126	/* Check that INVALID_OPERATION is generated by TextureSubImage3D if type
10127	 is one of UNSIGNED_SHORT_4_4_4_4, UNSIGNED_SHORT_4_4_4_4_REV,
10128	 UNSIGNED_SHORT_5_5_5_1, UNSIGNED_SHORT_1_5_5_5_REV,
10129	 UNSIGNED_INT_8_8_8_8, UNSIGNED_INT_8_8_8_8_REV, UNSIGNED_INT_10_10_10_2,
10130	 or UNSIGNED_INT_2_10_10_10_REV and format is neither RGBA nor BGRA. */
10131	{
10132		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10133							 s_reference_format, GL_UNSIGNED_SHORT_4_4_4_4, s_reference);
10134		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
10135								  "type is UNSIGNED_SHORT_4_4_4_4 and format is neither RGBA nor BGRA.");
10136
10137		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10138							 s_reference_format, GL_UNSIGNED_SHORT_4_4_4_4_REV, s_reference);
10139		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
10140								  "type is UNSIGNED_SHORT_4_4_4_4_REV and format is neither RGBA nor BGRA.");
10141
10142		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10143							 s_reference_format, GL_UNSIGNED_SHORT_5_5_5_1, s_reference);
10144		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
10145								  "type is UNSIGNED_SHORT_5_5_5_1 and format is neither RGBA nor BGRA.");
10146
10147		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10148							 s_reference_format, GL_UNSIGNED_SHORT_1_5_5_5_REV, s_reference);
10149		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
10150								  "type is UNSIGNED_SHORT_1_5_5_5_REV and format is neither RGBA nor BGRA.");
10151
10152		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10153							 s_reference_format, GL_UNSIGNED_INT_8_8_8_8, s_reference);
10154		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
10155								  "type is UNSIGNED_INT_8_8_8_8 and format is neither RGBA nor BGRA.");
10156
10157		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10158							 s_reference_format, GL_UNSIGNED_INT_8_8_8_8_REV, s_reference);
10159		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
10160								  "type is UNSIGNED_INT_8_8_8_8_REV and format is neither RGBA nor BGRA.");
10161
10162		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10163							 s_reference_format, GL_UNSIGNED_INT_10_10_10_2, s_reference);
10164		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
10165								  "type is UNSIGNED_INT_10_10_10_2 and format is neither RGBA nor BGRA.");
10166
10167		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10168							 s_reference_format, GL_UNSIGNED_INT_2_10_10_10_REV, s_reference);
10169		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
10170								  "type is UNSIGNED_INT_2_10_10_10_REV and format is neither RGBA nor BGRA.");
10171	}
10172
10173	/* Check that INVALID_OPERATION is generated by TextureSubImage3D if a
10174	 non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target
10175	 and the buffer object's data store is currently mapped. */
10176	{
10177		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
10178		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10179
10180		gl.mapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE);
10181
10182		if (GL_NO_ERROR == gl.getError())
10183		{
10184			gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10185								 s_reference_format, s_reference_type, NULL);
10186			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
10187									  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and "
10188									  "the buffer object's data store is currently mapped.");
10189
10190			gl.unmapBuffer(GL_PIXEL_UNPACK_BUFFER);
10191			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10192
10193			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
10194			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10195		}
10196	}
10197
10198	/* Check that INVALID_OPERATION is generated by TextureSubImage3D if a
10199	 non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target
10200	 and the data would be unpacked from the buffer object such that the
10201	 memory reads required would exceed the data store size. */
10202	{
10203		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
10204		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10205
10206		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10207							 s_reference_format, s_reference_type, (glw::GLubyte*)NULL + s_reference_size * 2);
10208		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
10209								  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and the "
10210								  "data would be unpacked from the buffer object such that the memory reads required "
10211								  "would exceed the data store size.");
10212
10213		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
10214		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10215	}
10216
10217	/* Check that INVALID_OPERATION is generated by TextureSubImage3D if a
10218	 non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target
10219	 and pixels is not evenly divisible into the number of bytes needed to
10220	 store in memory a datum indicated by type. */
10221	{
10222		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
10223		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10224
10225		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10226							 s_reference_format, s_reference_type, (glw::GLubyte*)NULL + 1);
10227		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
10228								  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and pixels "
10229								  "is not evenly divisible into the number of bytes needed to store in memory a datum "
10230								  "indicated by type.");
10231
10232		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
10233		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10234	}
10235
10236	return is_ok;
10237}
10238
10239/** @brief Test (negative) of TextureSubImage1DCompressed
10240 *
10241 *  @return Test result.
10242 */
10243bool SubImageErrorsTest::Test1DCompressed()
10244{
10245	/* Shortcut for GL functionality. */
10246	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
10247
10248	/* Result. */
10249	bool is_ok = true;
10250
10251	/* Do tests only if compressed 1D textures are supported. */
10252	if (DE_NULL != m_reference_compressed_1D)
10253	{
10254		/* Check that INVALID_OPERATION is generated by CompressedTextureSubImage1D
10255		 if texture is not the name of an existing texture object. */
10256		{
10257			gl.compressedTextureSubImage1D(m_to_invalid, 0, 0, s_reference_width, m_reference_compressed_1D_format,
10258										   m_reference_compressed_1D_size, m_reference_compressed_1D);
10259			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage1D",
10260									  "texture is not the name of an existing texture object.");
10261		}
10262
10263		/* Check that INVALID_ENUM is generated by CompressedTextureSubImage1D if
10264		 internalformat is not one of the generic compressed internal formats:
10265		 COMPRESSED_RED, COMPRESSED_RG, COMPRESSED_RGB, COMPRESSED_RGBA.
10266		 COMPRESSED_SRGB, or COMPRESSED_SRGB_ALPHA. */
10267		{
10268			/* GL_COMPRESSED_RG_RGTC2 is not 1D as specification says. */
10269			gl.compressedTextureSubImage1D(m_to_1D_compressed, 0, 0, s_reference_width, GL_COMPRESSED_RG_RGTC2,
10270										   m_reference_compressed_1D_size, m_reference_compressed_1D);
10271			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glCompressedTextureSubImage1D",
10272									  "internalformat is of the generic compressed internal formats: COMPRESSED_RED, "
10273									  "COMPRESSED_RG, COMPRESSED_RGB, COMPRESSED_RGBA. COMPRESSED_SRGB, or "
10274									  "COMPRESSED_SRGB_ALPHA.");
10275		}
10276
10277		/* Check that INVALID_OPERATION is generated if format does not match the
10278		 internal format of the texture image being modified, since these
10279		 commands do not provide for image format conversion. */
10280		{
10281			gl.compressedTextureSubImage1D(m_to_1D_compressed, 0, 0, s_reference_width,
10282										   m_not_matching_compressed_1D_format, m_not_matching_compressed_1D_size,
10283										   m_reference_compressed_1D);
10284			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage1D",
10285									  "format does not match the internal format of the texture image being modified, "
10286									  "since these commands do not provide for image format conversion.");
10287		}
10288
10289		/* Check that INVALID_VALUE is generated by CompressedTextureSubImage1D if
10290		 imageSize is not consistent with the format, dimensions, and contents of
10291		 the specified compressed image data. */
10292		{
10293			gl.compressedTextureSubImage1D(m_to_1D_compressed, 0, 0, s_reference_width,
10294										   m_reference_compressed_1D_format, m_reference_compressed_1D_size - 1,
10295										   m_reference_compressed_1D);
10296			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCompressedTextureSubImage1D",
10297									  "imageSize is not consistent with the format, dimensions, and contents of the "
10298									  "specified compressed image data.");
10299		}
10300
10301		/* Check that INVALID_OPERATION is generated by CompressedTextureSubImage1D
10302		 if a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER
10303		 target and the buffer object's data store is currently mapped. */
10304		{
10305			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
10306			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10307
10308			gl.mapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE);
10309
10310			if (GL_NO_ERROR == gl.getError())
10311			{
10312				gl.compressedTextureSubImage1D(m_to_1D_compressed, 0, 0, s_reference_width,
10313											   m_reference_compressed_1D_format, m_reference_compressed_1D_size, NULL);
10314				is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage1D",
10315										  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target "
10316										  "and the buffer object's data store is currently mapped.");
10317
10318				gl.unmapBuffer(GL_PIXEL_UNPACK_BUFFER);
10319				GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10320
10321				gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
10322				GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10323			}
10324		}
10325
10326		/* Check that INVALID_OPERATION is generated by CompressedTextureSubImage1D
10327		 if a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER
10328		 target and the data would be unpacked from the buffer object such that
10329		 the memory reads required would exceed the data store size. */
10330		{
10331			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
10332			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10333
10334			gl.compressedTextureSubImage1D(m_to_1D_compressed, 0, 0, s_reference_width,
10335										   m_reference_compressed_1D_format, m_reference_compressed_1D_size,
10336										   (glw::GLubyte*)NULL + s_reference_size * 2);
10337			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage1D",
10338									  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and "
10339									  "the buffer object's data store is currently mapped.");
10340
10341			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
10342			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10343		}
10344	}
10345
10346	return is_ok;
10347}
10348
10349/** @brief Test (negative) of TextureSubImage2DCompressed
10350 *
10351 *  @return Test result.
10352 */
10353bool SubImageErrorsTest::Test2DCompressed()
10354{
10355	/* Shortcut for GL functionality. */
10356	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
10357
10358	/* Result. */
10359	bool is_ok = true;
10360
10361	/* Do tests only if compressed 2D textures are supported. */
10362	if (DE_NULL != m_reference_compressed_2D)
10363	{
10364		/* Check that INVALID_OPERATION is generated by CompressedTextureSubImage2D
10365		 if texture is not the name of an existing texture object. */
10366		{
10367			gl.compressedTextureSubImage2D(m_to_invalid, 0, 0, 0, s_reference_width, s_reference_height,
10368										   m_reference_compressed_2D_format, m_reference_compressed_2D_size,
10369										   m_reference_compressed_2D);
10370			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage2D",
10371									  "texture is not the name of an existing texture object.");
10372		}
10373
10374		/* Check that INVALID_ENUM is generated by CompressedTextureSubImage2D if
10375		 internalformat is of the generic compressed internal formats:
10376		 COMPRESSED_RED, COMPRESSED_RG, COMPRESSED_RGB, COMPRESSED_RGBA.
10377		 COMPRESSED_SRGB, or COMPRESSED_SRGB_ALPHA. */
10378		{
10379			gl.compressedTextureSubImage2D(m_to_2D_compressed, 0, 0, 0, s_reference_width, s_reference_height,
10380										   GL_COMPRESSED_RG, m_reference_compressed_2D_size, m_reference_compressed_2D);
10381			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glCompressedTextureSubImage2D",
10382									  "internalformat is of the generic compressed internal formats: COMPRESSED_RED, "
10383									  "COMPRESSED_RG, COMPRESSED_RGB, COMPRESSED_RGBA. COMPRESSED_SRGB, or "
10384									  "COMPRESSED_SRGB_ALPHA.");
10385		}
10386
10387		/* Check that INVALID_OPERATION is generated if format does not match the
10388		 internal format of the texture image being modified, since these
10389		 commands do not provide for image format conversion. */
10390		{
10391			gl.compressedTextureSubImage2D(m_to_2D_compressed, 0, 0, 0, s_reference_width, s_reference_height,
10392										   m_not_matching_compressed_2D_format, m_not_matching_compressed_2D_size,
10393										   m_reference_compressed_2D);
10394			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage2D",
10395									  "format does not match the internal format of the texture image being modified, "
10396									  "since these commands do not provide for image format conversion.");
10397		}
10398
10399		/* Check that INVALID_VALUE is generated by CompressedTextureSubImage2D if
10400		 imageSize is not consistent with the format, dimensions, and contents of
10401		 the specified compressed image data. */
10402		{
10403			gl.compressedTextureSubImage2D(m_to_2D_compressed, 0, 0, 0, s_reference_width, s_reference_height,
10404										   m_reference_compressed_2D_format, m_reference_compressed_2D_size - 1,
10405										   m_reference_compressed_2D);
10406			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCompressedTextureSubImage2D",
10407									  "imageSize is not consistent with the format, dimensions, and contents of the "
10408									  "specified compressed image data.");
10409		}
10410
10411		/* Check that INVALID_OPERATION is generated by CompressedTextureSubImage2D
10412		 if a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER
10413		 target and the buffer object's data store is currently mapped. */
10414		{
10415			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
10416			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10417
10418			gl.mapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE);
10419
10420			if (GL_NO_ERROR == gl.getError())
10421			{
10422				gl.compressedTextureSubImage2D(m_to_2D_compressed, 0, 0, 0, s_reference_width, s_reference_height,
10423											   m_reference_compressed_2D_format, m_reference_compressed_2D_size, NULL);
10424				is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage2D",
10425										  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target "
10426										  "and the buffer object's data store is currently mapped.");
10427
10428				gl.unmapBuffer(GL_PIXEL_UNPACK_BUFFER);
10429				GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10430
10431				gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
10432				GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10433			}
10434		}
10435
10436		/* Check that INVALID_OPERATION is generated by CompressedTextureSubImage2D
10437		 if a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER
10438		 target and the data would be unpacked from the buffer object such that
10439		 the memory reads required would exceed the data store size. */
10440		{
10441			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
10442			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10443
10444			gl.compressedTextureSubImage2D(m_to_2D_compressed, 0, 0, 0, s_reference_width, s_reference_height,
10445										   m_reference_compressed_2D_format, m_reference_compressed_2D_size,
10446										   (glw::GLubyte*)NULL + s_reference_size * 2);
10447			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage2D",
10448									  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and "
10449									  "the buffer object's data store is currently mapped.");
10450
10451			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
10452			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10453		}
10454
10455		/* Check that INVALID_OPERATION is generated by CompressedTextureSubImage2D
10456		 if the effective target is TEXTURE_RECTANGLE. */
10457		if (DE_NULL !=
10458			m_reference_compressed_rectangle) /* Do test only if rectangle compressed texture is supported by the implementation. */
10459		{
10460			gl.compressedTextureSubImage2D(m_to_rectangle_compressed, 0, 0, 0, s_reference_width, s_reference_height,
10461										   m_reference_compressed_rectangle_format,
10462										   m_reference_compressed_rectangle_size, m_reference_compressed_rectangle);
10463
10464			if (m_context.getContextInfo().isExtensionSupported("GL_NV_texture_rectangle_compressed"))
10465			{
10466				is_ok &= CheckErrorAndLog(m_context, GL_NO_ERROR, "glCompressedTextureSubImage2D",
10467										  "a rectangle texture object is used with this function.");
10468			}
10469			else
10470			{
10471				is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage2D",
10472										  "a rectangle texture object is used with this function.");
10473			}
10474		}
10475	}
10476
10477	return is_ok;
10478}
10479
10480/** @brief Test (negative) of TextureSubImage3DCompressed
10481 *
10482 *  @return Test result.
10483 */
10484bool SubImageErrorsTest::Test3DCompressed()
10485{
10486	/* Shortcut for GL functionality. */
10487	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
10488
10489	/* Result. */
10490	bool is_ok = true;
10491
10492	/* Do tests only if compressed 3D textures are supported. */
10493	if (DE_NULL != m_reference_compressed_3D)
10494	{
10495		/* Check that INVALID_OPERATION is generated by CompressedTextureSubImage3D
10496		 if texture is not the name of an existing texture object. */
10497		{
10498			gl.compressedTextureSubImage3D(m_to_invalid, 0, 0, 0, 0, s_reference_width, s_reference_height,
10499										   s_reference_depth, m_reference_compressed_3D_format,
10500										   m_reference_compressed_3D_size, m_reference_compressed_3D);
10501			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage3D",
10502									  "texture is not the name of an existing texture object.");
10503		}
10504
10505		/* Check that INVALID_ENUM is generated by CompressedTextureSubImage3D if
10506		 internalformat is of the generic compressed internal formats:
10507		 COMPRESSED_RED, COMPRESSED_RG, COMPRESSED_RGB, COMPRESSED_RGBA.
10508		 COMPRESSED_SRGB, or COMPRESSED_SRGB_ALPHA. */
10509		{
10510			gl.compressedTextureSubImage3D(m_to_3D_compressed, 0, 0, 0, 0, s_reference_width, s_reference_height,
10511										   s_reference_depth, GL_COMPRESSED_RG, m_reference_compressed_3D_size,
10512										   m_reference_compressed_3D);
10513			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glCompressedTextureSubImage3D",
10514									  "internalformat is of the generic compressed internal formats: COMPRESSED_RED, "
10515									  "COMPRESSED_RG, COMPRESSED_RGB, COMPRESSED_RGBA. COMPRESSED_SRGB, or "
10516									  "COMPRESSED_SRGB_ALPHA.");
10517		}
10518
10519		/* Check that INVALID_OPERATION is generated if format does not match the
10520		 internal format of the texture image being modified, since these
10521		 commands do not provide for image format conversion. */
10522		{
10523			gl.compressedTextureSubImage3D(m_to_3D_compressed, 0, 0, 0, 0, s_reference_width, s_reference_height,
10524										   s_reference_depth, m_not_matching_compressed_3D_format,
10525										   m_not_matching_compressed_3D_size, m_reference_compressed_3D);
10526			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage3D",
10527									  "format does not match the internal format of the texture image being modified, "
10528									  "since these commands do not provide for image format conversion.");
10529		}
10530
10531		/* Check that INVALID_VALUE is generated by CompressedTextureSubImage3D if
10532		 imageSize is not consistent with the format, dimensions, and contents of
10533		 the specified compressed image data. */
10534		{
10535			gl.compressedTextureSubImage3D(m_to_3D_compressed, 0, 0, 0, 0, s_reference_width, s_reference_height,
10536										   s_reference_depth, m_reference_compressed_3D_format,
10537										   m_reference_compressed_3D_size - 1, m_reference_compressed_3D);
10538			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCompressedTextureSubImage3D",
10539									  "imageSize is not consistent with the format, dimensions, and contents of the "
10540									  "specified compressed image data.");
10541		}
10542
10543		/* Check that INVALID_OPERATION is generated by CompressedTextureSubImage3D
10544		 if a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER
10545		 target and the buffer object's data store is currently mapped. */
10546		{
10547			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
10548			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10549
10550			gl.mapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE);
10551
10552			if (GL_NO_ERROR == gl.getError())
10553			{
10554				gl.compressedTextureSubImage3D(m_to_3D_compressed, 0, 0, 0, 0, s_reference_width, s_reference_height,
10555											   s_reference_depth, m_reference_compressed_3D_format,
10556											   m_reference_compressed_3D_size, NULL);
10557				is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage3D",
10558										  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target "
10559										  "and the buffer object's data store is currently mapped.");
10560
10561				gl.unmapBuffer(GL_PIXEL_UNPACK_BUFFER);
10562				GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10563
10564				gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
10565				GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10566			}
10567		}
10568
10569		/* Check that INVALID_OPERATION is generated by CompressedTextureSubImage3D
10570		 if a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER
10571		 target and the data would be unpacked from the buffer object such that
10572		 the memory reads required would exceed the data store size. */
10573		{
10574			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
10575			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10576
10577			gl.compressedTextureSubImage3D(m_to_3D_compressed, 0, 0, 0, 0, s_reference_width, s_reference_height,
10578										   s_reference_depth, m_reference_compressed_3D_format,
10579										   m_reference_compressed_3D_size, (glw::GLubyte*)NULL + s_reference_size * 2);
10580			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage3D",
10581									  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and "
10582									  "the buffer object's data store is currently mapped.");
10583
10584			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
10585			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10586		}
10587	}
10588
10589	return is_ok;
10590}
10591
10592/** @brief Clean GL objects, test variables and GL errors.
10593 */
10594void SubImageErrorsTest::Clean()
10595{
10596	/* Shortcut for GL functionality. */
10597	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
10598
10599	/* Cleanup. */
10600	if (m_to_1D_empty)
10601	{
10602		gl.deleteTextures(1, &m_to_1D_empty);
10603
10604		m_to_1D_empty = 0;
10605	}
10606
10607	if (m_to_2D_empty)
10608	{
10609		gl.deleteTextures(1, &m_to_2D_empty);
10610
10611		m_to_2D_empty = 0;
10612	}
10613
10614	if (m_to_3D_empty)
10615	{
10616		gl.deleteTextures(1, &m_to_3D_empty);
10617
10618		m_to_3D_empty = 0;
10619	}
10620
10621	if (m_to_1D)
10622	{
10623		gl.deleteTextures(1, &m_to_1D);
10624
10625		m_to_1D = 0;
10626	}
10627
10628	if (m_to_2D)
10629	{
10630		gl.deleteTextures(1, &m_to_2D);
10631
10632		m_to_2D = 0;
10633	}
10634
10635	if (m_to_3D)
10636	{
10637		gl.deleteTextures(1, &m_to_3D);
10638
10639		m_to_3D = 0;
10640	}
10641
10642	if (m_to_1D_compressed)
10643	{
10644		gl.deleteTextures(1, &m_to_1D_compressed);
10645
10646		m_to_1D_compressed = 0;
10647	}
10648
10649	if (m_to_2D_compressed)
10650	{
10651		gl.deleteTextures(1, &m_to_2D_compressed);
10652
10653		m_to_2D_compressed = 0;
10654	}
10655
10656	if (m_to_3D_compressed)
10657	{
10658		gl.deleteTextures(1, &m_to_3D_compressed);
10659
10660		m_to_3D_compressed = 0;
10661	}
10662
10663	if (m_to_rectangle_compressed)
10664	{
10665		gl.deleteTextures(1, &m_to_rectangle_compressed);
10666
10667		m_to_rectangle_compressed = 0;
10668	}
10669
10670	if (m_bo)
10671	{
10672		gl.deleteBuffers(1, &m_bo);
10673
10674		m_bo = 0;
10675	}
10676
10677	m_to_invalid	   = 0;
10678	m_format_invalid   = 0;
10679	m_type_invalid	 = 0;
10680	m_max_texture_size = 1;
10681
10682	if (DE_NULL != m_reference_compressed_1D)
10683	{
10684		delete[] m_reference_compressed_1D;
10685
10686		m_reference_compressed_1D = NULL;
10687	}
10688
10689	if (DE_NULL != m_reference_compressed_2D)
10690	{
10691		delete[] m_reference_compressed_2D;
10692
10693		m_reference_compressed_2D = NULL;
10694	}
10695
10696	if (DE_NULL != m_reference_compressed_3D)
10697	{
10698		delete[] m_reference_compressed_3D;
10699
10700		m_reference_compressed_3D = NULL;
10701	}
10702
10703	if (DE_NULL != m_reference_compressed_rectangle)
10704	{
10705		delete[] m_reference_compressed_rectangle;
10706
10707		m_reference_compressed_rectangle = NULL;
10708	}
10709
10710	m_reference_compressed_1D_format		= 0;
10711	m_reference_compressed_2D_format		= 0;
10712	m_reference_compressed_3D_format		= 0;
10713	m_reference_compressed_rectangle_format = 0;
10714	m_reference_compressed_1D_size			= 0;
10715	m_reference_compressed_2D_size			= 0;
10716	m_reference_compressed_3D_size			= 0;
10717	m_reference_compressed_rectangle_size   = 0;
10718	m_not_matching_compressed_1D_format		= 0;
10719	m_not_matching_compressed_1D_size		= 0;
10720	m_not_matching_compressed_2D_format		= 0;
10721	m_not_matching_compressed_2D_size		= 0;
10722	m_not_matching_compressed_3D_format		= 0;
10723	m_not_matching_compressed_3D_size		= 0;
10724
10725	while (GL_NO_ERROR != gl.getError())
10726		;
10727}
10728
10729/** Reference data */
10730const glw::GLushort SubImageErrorsTest::s_reference[] = {
10731	0x0,  0x0,  0x0,  0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
10732	0x88, 0x0,  0x15, 0xff, 0xed, 0x1c, 0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0,  0xff,
10733	0xc8, 0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0xff,
10734	0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc, 0xff, 0x0,  0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff,
10735
10736	0x0,  0x0,  0x0,  0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
10737	0x88, 0x0,  0x15, 0xff, 0xed, 0x1c, 0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0,  0xff,
10738	0xc8, 0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0xff,
10739	0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc, 0xff, 0x0,  0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff,
10740
10741	0x0,  0x0,  0x0,  0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
10742	0x88, 0x0,  0x15, 0xff, 0xed, 0x1c, 0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0,  0xff,
10743	0xc8, 0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0xff,
10744	0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc, 0xff, 0x0,  0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff,
10745
10746	0x0,  0x0,  0x0,  0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
10747	0x88, 0x0,  0x15, 0xff, 0xed, 0x1c, 0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0,  0xff,
10748	0xc8, 0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0xff,
10749	0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc, 0xff, 0x0,  0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff
10750};
10751
10752/** Reference data parameters. */
10753const glw::GLuint SubImageErrorsTest::s_reference_size						= sizeof(s_reference);
10754const glw::GLuint SubImageErrorsTest::s_reference_width						= 4;
10755const glw::GLuint SubImageErrorsTest::s_reference_height					= 4;
10756const glw::GLuint SubImageErrorsTest::s_reference_depth						= 4;
10757const glw::GLenum SubImageErrorsTest::s_reference_internalformat			= GL_RG8;
10758const glw::GLenum SubImageErrorsTest::s_reference_internalformat_compressed = GL_COMPRESSED_RG;
10759const glw::GLenum SubImageErrorsTest::s_reference_format = GL_RG; /* !Must not be a RGB, RGBA, or BGRA */
10760const glw::GLenum SubImageErrorsTest::s_reference_type   = GL_UNSIGNED_SHORT;
10761
10762/******************************** Copy Errors Test Implementation   ********************************/
10763
10764/** @brief Copy Errors Test constructor.
10765 *
10766 *  @param [in] context     OpenGL context.
10767 */
10768CopyErrorsTest::CopyErrorsTest(deqp::Context& context)
10769	: deqp::TestCase(context, "textures_copy_errors", "Texture Copy Errors Test")
10770	, m_fbo(0)
10771	, m_fbo_ms(0)
10772	, m_fbo_incomplete(0)
10773	, m_to_src(0)
10774	, m_to_src_ms(0)
10775	, m_to_1D_dst(0)
10776	, m_to_2D_dst(0)
10777	, m_to_3D_dst(0)
10778	, m_to_invalid(0)
10779{
10780	/* Intentionally left blank. */
10781}
10782
10783/** @brief Iterate Copy Errors Test cases.
10784 *
10785 *  @return Iteration result.
10786 */
10787tcu::TestNode::IterateResult CopyErrorsTest::iterate()
10788{
10789	/* Get context setup. */
10790	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
10791	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
10792
10793	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
10794	{
10795		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
10796
10797		return STOP;
10798	}
10799
10800	/* Running tests. */
10801	bool is_ok	= true;
10802	bool is_error = false;
10803
10804	try
10805	{
10806		Prepare();
10807
10808		is_ok &= Test1D();
10809		is_ok &= Test2D();
10810		is_ok &= Test3D();
10811	}
10812	catch (...)
10813	{
10814		is_ok	= false;
10815		is_error = true;
10816	}
10817
10818	/* Cleanup. */
10819	Clean();
10820
10821	/* Result's setup. */
10822	if (is_ok)
10823	{
10824		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
10825	}
10826	else
10827	{
10828		if (is_error)
10829		{
10830			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
10831		}
10832		else
10833		{
10834			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
10835		}
10836	}
10837
10838	return STOP;
10839}
10840
10841/** @brief Prepare test's objects and values.
10842 */
10843void CopyErrorsTest::Prepare()
10844{
10845	/* Shortcut for GL functionality. */
10846	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
10847
10848	/* Auxiliary objects setup. */
10849
10850	/* Framebuffer. */
10851	gl.genFramebuffers(1, &m_fbo);
10852	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
10853
10854	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
10855	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
10856
10857	gl.createTextures(GL_TEXTURE_2D, 1, &m_to_src);
10858	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
10859
10860	gl.textureStorage2D(m_to_src, 1, s_internalformat, s_width, s_height);
10861	GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2D has failed");
10862
10863	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_to_src, 0);
10864	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture1D call failed.");
10865
10866	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
10867	{
10868		throw 0;
10869	}
10870
10871	gl.viewport(0, 0, s_width, s_height);
10872	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
10873
10874	gl.clear(GL_COLOR_BUFFER_BIT);
10875	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed.");
10876
10877	/* Framebuffer Multisample. */
10878	gl.genFramebuffers(1, &m_fbo_ms);
10879	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
10880
10881	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_ms);
10882	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
10883
10884	gl.createTextures(GL_TEXTURE_2D_MULTISAMPLE, 1, &m_to_src_ms);
10885	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
10886
10887	gl.textureStorage2DMultisample(m_to_src_ms, 1, s_internalformat, s_width, s_height, false);
10888	GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2DMultisample has failed");
10889
10890	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, m_to_src_ms, 0);
10891	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture1D call failed.");
10892
10893	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
10894	{
10895		throw 0;
10896	}
10897
10898	gl.viewport(0, 0, s_width, s_height);
10899	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
10900
10901	gl.clear(GL_COLOR_BUFFER_BIT);
10902	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed.");
10903
10904	/* Framebuffer Incomplete. */
10905	gl.createFramebuffers(1, &m_fbo_incomplete);
10906	GLU_EXPECT_NO_ERROR(gl.getError(), "glcreateFramebuffers call failed.");
10907
10908	/* 1D */
10909	gl.createTextures(GL_TEXTURE_1D, 1, &m_to_1D_dst);
10910	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
10911
10912	gl.textureStorage1D(m_to_1D_dst, 1, s_internalformat, s_width);
10913	GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2D has failed");
10914
10915	/* 2D */
10916	gl.createTextures(GL_TEXTURE_2D, 1, &m_to_2D_dst);
10917	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
10918
10919	gl.textureStorage2D(m_to_2D_dst, 1, s_internalformat, s_width, s_height);
10920	GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2D has failed");
10921
10922	/* 3D */
10923	gl.createTextures(GL_TEXTURE_3D, 1, &m_to_3D_dst);
10924	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
10925
10926	gl.textureStorage3D(m_to_3D_dst, 1, s_internalformat, s_width, s_height, s_depth);
10927	GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2D has failed");
10928
10929	/* invalid texture object */
10930	while (gl.isTexture(++m_to_invalid))
10931		;
10932	GLU_EXPECT_NO_ERROR(gl.getError(), "glIsTexture has failed");
10933}
10934
10935/** @brief Test (negative) of CopyTextureSubImage1D
10936 *
10937 *  @return Test result.
10938 */
10939bool CopyErrorsTest::Test1D()
10940{
10941	/* Shortcut for GL functionality. */
10942	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
10943
10944	/* Result. */
10945	bool is_ok = true;
10946
10947	/* Bind framebuffer. */
10948	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_incomplete);
10949	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
10950
10951	/* Check that INVALID_FRAMEBUFFER_OPERATION is generated by
10952	 CopyTextureSubImage1D if the object bound to READ_FRAMEBUFFER_BINDING is
10953	 not framebuffer complete. */
10954	{
10955		gl.copyTextureSubImage1D(m_to_1D_dst, 0, 0, 0, 0, s_width);
10956		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_FRAMEBUFFER_OPERATION, "glCopyTextureSubImage1D",
10957								  "the object bound to READ_FRAMEBUFFER_BINDING is not framebuffer complete.");
10958	}
10959
10960	/* Bind framebuffer. */
10961	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
10962	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
10963
10964	gl.readBuffer(GL_COLOR_ATTACHMENT0);
10965	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
10966
10967	/* Check that INVALID_OPERATION is generated by CopyTextureSubImage1D if
10968	 texture is not the name of an existing texture object, or if the
10969	 effective target of texture is not TEXTURE_1D. */
10970	{
10971		gl.copyTextureSubImage1D(m_to_invalid, 0, 0, 0, 0, s_width);
10972		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage1D",
10973								  "texture is not the name of an existing texture object.");
10974
10975		gl.copyTextureSubImage1D(m_to_2D_dst, 0, 0, 0, 0, s_width);
10976		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage1D",
10977								  "the effective target of texture is not TEXTURE_1D.");
10978	}
10979
10980	/* Check that INVALID_VALUE is generated by CopyTextureSubImage1D if level is less than 0. */
10981	{
10982		gl.copyTextureSubImage1D(m_to_1D_dst, -1, 0, 0, 0, s_width);
10983		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage1D", "level is less than 0.");
10984	}
10985
10986	/* Check that INVALID_VALUE is generated by CopyTextureSubImage1D if
10987	 xoffset<0, or (xoffset+width)>w, where w is the TEXTURE_WIDTH of the
10988	 texture image being modified. */
10989	{
10990		gl.copyTextureSubImage1D(m_to_1D_dst, 0, -1, 0, 0, s_width);
10991		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage1D", "xoffset<0.");
10992
10993		gl.copyTextureSubImage1D(m_to_1D_dst, 0, 1, 0, 0, s_width);
10994		is_ok &=
10995			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage1D",
10996							 "(xoffset+width)>w, where w is the TEXTURE_WIDTH of the texture image being modified.");
10997	}
10998
10999	/* Check that INVALID_OPERATION is generated by CopyTextureSubImage1D if
11000	 the read buffer is NONE. */
11001	gl.readBuffer(GL_NONE);
11002	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11003
11004	{
11005		gl.copyTextureSubImage1D(m_to_1D_dst, 0, 0, 0, 0, s_width);
11006		is_ok &=
11007			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage1D", "the read buffer is NONE.");
11008	}
11009
11010	/* Bind multisample framebuffer. */
11011	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_ms);
11012	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11013
11014	gl.readBuffer(GL_COLOR_ATTACHMENT0);
11015	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11016
11017	/* Check that INVALID_OPERATION is generated by CopyTextureSubImage1D if
11018	 the effective value of SAMPLE_BUFFERS for the read
11019	 framebuffer is one. */
11020	{
11021		gl.copyTextureSubImage1D(m_to_1D_dst, 0, 0, 0, 0, s_width);
11022		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage1D",
11023								  "the effective value of SAMPLE_BUFFERS for the read framebuffer is one.");
11024	}
11025
11026	return is_ok;
11027}
11028
11029/** @brief Test (negative) of CopyTextureSubImage2D
11030 *
11031 *  @return Test result.
11032 */
11033bool CopyErrorsTest::Test2D()
11034{
11035	/* Shortcut for GL functionality. */
11036	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
11037
11038	/* Result. */
11039	bool is_ok = true;
11040
11041	/* Bind framebuffer. */
11042	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_incomplete);
11043	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11044
11045	/* Check that INVALID_FRAMEBUFFER_OPERATION is generated by
11046	 CopyTextureSubImage2D if the object bound to READ_FRAMEBUFFER_BINDING is
11047	 not framebuffer complete. */
11048	{
11049		gl.copyTextureSubImage2D(m_to_2D_dst, 0, 0, 0, 0, 0, s_width, s_height);
11050		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_FRAMEBUFFER_OPERATION, "glCopyTextureSubImage2D",
11051								  "the object bound to READ_FRAMEBUFFER_BINDING is not framebuffer complete.");
11052	}
11053
11054	/* Bind framebuffer. */
11055	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
11056	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11057
11058	gl.readBuffer(GL_COLOR_ATTACHMENT0);
11059	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11060
11061	/* Check that INVALID_OPERATION is generated by CopyTextureSubImage2D if
11062	 texture is not the name of an existing texture object, or if the
11063	 effective target of texture is not TEXTURE_2D. */
11064	{
11065		gl.copyTextureSubImage2D(m_to_invalid, 0, 0, 0, 0, 0, s_width, s_height);
11066		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage2D",
11067								  "texture is not the name of an existing texture object.");
11068
11069		gl.copyTextureSubImage2D(m_to_1D_dst, 0, 0, 0, 0, 0, s_width, s_height);
11070		is_ok &= CheckErrorAndLog(
11071			m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage2D",
11072			"the effective target of does not correspond to one of the texture targets supported by the function..");
11073	}
11074
11075	/* Check that INVALID_VALUE is generated by CopyTextureSubImage2D if level is less than 0. */
11076	{
11077		gl.copyTextureSubImage2D(m_to_2D_dst, -1, 0, 0, 0, 0, s_width, s_height);
11078		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage2D", "level is less than 0.");
11079	}
11080
11081	/* Check that INVALID_VALUE is generated by CopyTextureSubImage2D if
11082	 xoffset<0, (xoffset+width)>w, yoffset<0, or (yoffset+height)>0, where w
11083	 is the TEXTURE_WIDTH, h is the TEXTURE_HEIGHT and of the texture image
11084	 being modified. */
11085	{
11086		gl.copyTextureSubImage2D(m_to_2D_dst, 0, -1, 0, 0, 0, s_width, s_height);
11087		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage2D", "xoffset<0.");
11088
11089		gl.copyTextureSubImage2D(m_to_2D_dst, 0, 1, 0, 0, 0, s_width, s_height);
11090		is_ok &=
11091			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage2D",
11092							 "(xoffset+width)>w, where w is the TEXTURE_WIDTH of the texture image being modified.");
11093
11094		gl.copyTextureSubImage2D(m_to_2D_dst, 0, 0, -1, 0, 0, s_width, s_height);
11095		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage2D", "yoffset<0.");
11096
11097		gl.copyTextureSubImage2D(m_to_2D_dst, 0, 0, 1, 0, 0, s_width, s_height);
11098		is_ok &=
11099			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage2D",
11100							 "(yoffset+height)>h, where h is the TEXTURE_HEIGHT of the texture image being modified.");
11101	}
11102
11103	/* Check that INVALID_OPERATION is generated by CopyTextureSubImage2D if
11104	 the read buffer is NONE. */
11105	gl.readBuffer(GL_NONE);
11106	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11107
11108	{
11109		gl.copyTextureSubImage2D(m_to_2D_dst, 0, 0, 0, 0, 0, s_width, s_height);
11110		is_ok &=
11111			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage2D", "the read buffer is NONE.");
11112	}
11113
11114	/* Bind multisample framebuffer. */
11115	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_ms);
11116	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11117
11118	gl.readBuffer(GL_COLOR_ATTACHMENT0);
11119	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11120
11121	/* Check that INVALID_OPERATION is generated by CopyTextureSubImage2D if
11122	 the effective value of SAMPLE_BUFFERS for the read
11123	 framebuffer is one. */
11124	{
11125		gl.copyTextureSubImage2D(m_to_2D_dst, 0, 0, 0, 0, 0, s_width, s_height);
11126		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage2D",
11127								  "the effective value of SAMPLE_BUFFERS for the read framebuffer is one.");
11128	}
11129
11130	return is_ok;
11131}
11132
11133/** @brief Test (negative) of CopyTextureSubImage3D
11134 *
11135 *  @return Test result.
11136 */
11137bool CopyErrorsTest::Test3D()
11138{
11139	/* Shortcut for GL functionality. */
11140	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
11141
11142	/* Result. */
11143	bool is_ok = true;
11144
11145	/* Bind framebuffer. */
11146	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_incomplete);
11147	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11148
11149	/* Check that INVALID_FRAMEBUFFER_OPERATION is generated by
11150	 CopyTextureSubImage3D if the object bound to READ_FRAMEBUFFER_BINDING is
11151	 not framebuffer complete. */
11152	{
11153		gl.copyTextureSubImage3D(m_to_3D_dst, 0, 0, 0, 0, 0, 0, s_width, s_height);
11154		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_FRAMEBUFFER_OPERATION, "glCopyTextureSubImage3D",
11155								  "the object bound to READ_FRAMEBUFFER_BINDING is not framebuffer complete.");
11156	}
11157
11158	/* Bind framebuffer. */
11159	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
11160	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11161
11162	gl.readBuffer(GL_COLOR_ATTACHMENT0);
11163	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11164
11165	/* Check that INVALID_OPERATION is generated by CopyTextureSubImage3D if
11166	 texture is not the name of an existing texture object, or if the
11167	 effective target of texture is not supported by the function. */
11168	{
11169		gl.copyTextureSubImage3D(m_to_invalid, 0, 0, 0, 0, 0, 0, s_width, s_height);
11170		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage3D",
11171								  "texture is not the name of an existing texture object.");
11172
11173		gl.copyTextureSubImage3D(m_to_1D_dst, 0, 0, 0, 0, 0, 0, s_width, s_height);
11174		is_ok &= CheckErrorAndLog(
11175			m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage3D",
11176			"the effective target of does not correspond to one of the texture targets supported by the function..");
11177	}
11178
11179	/* Check that INVALID_VALUE is generated by CopyTextureSubImage3D if level is less than 0. */
11180	{
11181		gl.copyTextureSubImage3D(m_to_3D_dst, -1, 0, 0, 0, 0, 0, s_width, s_height);
11182		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage3D", "level is less than 0.");
11183	}
11184
11185	/* Check that INVALID_VALUE is generated by CopyTextureSubImage3D if
11186	 xoffset<0, (xoffset+width)>w, yoffset<0, (yoffset+height)>h, zoffset<0,
11187	 or (zoffset+1)>d, where w is the TEXTURE_WIDTH, h is the TEXTURE_HEIGHT,
11188	 d is the TEXTURE_DEPTH and of the texture image being modified. Note
11189	 that w, h, and d include twice the border width.  */
11190	{
11191		gl.copyTextureSubImage3D(m_to_3D_dst, 0, -1, 0, 0, 0, 0, s_width, s_height);
11192		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage3D", "xoffset<0.");
11193
11194		gl.copyTextureSubImage3D(m_to_3D_dst, 0, 1, 0, 0, 0, 0, s_width, s_height);
11195		is_ok &=
11196			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage3D",
11197							 "(xoffset+width)>w, where w is the TEXTURE_WIDTH of the texture image being modified.");
11198
11199		gl.copyTextureSubImage3D(m_to_3D_dst, 0, 0, -1, 0, 0, 0, s_width, s_height);
11200		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage3D", "yoffset<0.");
11201
11202		gl.copyTextureSubImage3D(m_to_3D_dst, 0, 0, 1, 0, 0, 0, s_width, s_height);
11203		is_ok &=
11204			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage3D",
11205							 "(yoffset+height)>h, where h is the TEXTURE_HEIGHT of the texture image being modified.");
11206
11207		gl.copyTextureSubImage3D(m_to_3D_dst, 0, 0, 0, -1, 0, 0, s_width, s_height);
11208		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage3D", "zoffset<0.");
11209
11210		gl.copyTextureSubImage3D(m_to_3D_dst, 0, 0, 0, s_depth + 1, 0, 0, s_width, s_height);
11211		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage3D",
11212								  "(zoffset+1)>d, where d is the TEXTURE_DEPTH of the texture image being modified.");
11213	}
11214
11215	/* Check that INVALID_OPERATION is generated by CopyTextureSubImage3D if
11216	 the read buffer is NONE. */
11217	gl.readBuffer(GL_NONE);
11218	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11219
11220	{
11221		gl.copyTextureSubImage3D(m_to_3D_dst, 0, 0, 0, 0, 0, 0, s_width, s_height);
11222		is_ok &=
11223			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage3D", "the read buffer is NONE.");
11224	}
11225
11226	/* Bind multisample framebuffer. */
11227	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_ms);
11228	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11229
11230	gl.readBuffer(GL_COLOR_ATTACHMENT0);
11231	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11232
11233	/* Check that INVALID_OPERATION is generated by CopyTextureSubImage3D if
11234	 the effective value of SAMPLE_BUFFERS for the read
11235	 framebuffer is one. */
11236	{
11237		gl.copyTextureSubImage3D(m_to_3D_dst, 0, 0, 0, 0, 0, 0, s_width, s_height);
11238		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage3D",
11239								  "the effective value of SAMPLE_BUFFERS for the read framebuffer is one.");
11240	}
11241
11242	return is_ok;
11243}
11244
11245/** @brief Clean GL objects, test variables and GL errors.
11246 */
11247void CopyErrorsTest::Clean()
11248{
11249	/* Shortcut for GL functionality. */
11250	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
11251
11252	/* Cleanup. */
11253	if (m_fbo)
11254	{
11255		gl.deleteFramebuffers(1, &m_fbo);
11256
11257		m_fbo = 0;
11258	}
11259
11260	if (m_fbo_ms)
11261	{
11262		gl.deleteFramebuffers(1, &m_fbo_ms);
11263
11264		m_fbo_ms = 0;
11265	}
11266
11267	if (m_fbo_incomplete)
11268	{
11269		gl.deleteFramebuffers(1, &m_fbo_incomplete);
11270
11271		m_fbo_incomplete = 0;
11272	}
11273
11274	if (m_to_src)
11275	{
11276		gl.deleteTextures(1, &m_to_src);
11277
11278		m_to_src = 0;
11279	}
11280
11281	if (m_to_src_ms)
11282	{
11283		gl.deleteTextures(1, &m_to_src_ms);
11284
11285		m_to_src_ms = 0;
11286	}
11287
11288	if (m_to_1D_dst)
11289	{
11290		gl.deleteTextures(1, &m_to_1D_dst);
11291
11292		m_to_1D_dst = 0;
11293	}
11294
11295	if (m_to_2D_dst)
11296	{
11297		gl.deleteTextures(1, &m_to_2D_dst);
11298
11299		m_to_2D_dst = 0;
11300	}
11301
11302	if (m_to_3D_dst)
11303	{
11304		gl.deleteTextures(1, &m_to_3D_dst);
11305
11306		m_to_3D_dst = 0;
11307	}
11308
11309	m_to_invalid = 0;
11310
11311	while (GL_NO_ERROR != gl.getError())
11312		;
11313}
11314
11315/* Test's parameters. */
11316const glw::GLuint CopyErrorsTest::s_width		   = 4;
11317const glw::GLuint CopyErrorsTest::s_height		   = 4;
11318const glw::GLuint CopyErrorsTest::s_depth		   = 4;
11319const glw::GLuint CopyErrorsTest::s_internalformat = GL_RGBA8;
11320
11321/******************************** Parameter Setup Errors Test Implementation   ********************************/
11322
11323/** @brief Parameter Setup Errors Test constructor.
11324 *
11325 *  @param [in] context     OpenGL context.
11326 */
11327ParameterSetupErrorsTest::ParameterSetupErrorsTest(deqp::Context& context)
11328	: deqp::TestCase(context, "textures_parameter_setup_errors", "Texture Parameter Setup Errors Test")
11329	, m_to_2D(0)
11330	, m_to_2D_ms(0)
11331	, m_to_rectangle(0)
11332	, m_to_invalid(0)
11333	, m_pname_invalid(0)
11334	, m_depth_stencil_mode_invalid(0)
11335{
11336	/* Intentionally left blank. */
11337}
11338
11339/** @brief Iterate Parameter Setup Errors Test cases.
11340 *
11341 *  @return Iteration result.
11342 */
11343tcu::TestNode::IterateResult ParameterSetupErrorsTest::iterate()
11344{
11345	/* Get context setup. */
11346	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
11347	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
11348
11349	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
11350	{
11351		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
11352
11353		return STOP;
11354	}
11355
11356	/* Running tests. */
11357	bool is_ok	= true;
11358	bool is_error = false;
11359
11360	try
11361	{
11362		Prepare();
11363
11364		is_ok &= Testf();
11365		is_ok &= Testi();
11366		is_ok &= Testfv();
11367		is_ok &= Testiv();
11368		is_ok &= TestIiv();
11369		is_ok &= TestIuiv();
11370	}
11371	catch (...)
11372	{
11373		is_ok	= false;
11374		is_error = true;
11375	}
11376
11377	/* Cleanup. */
11378	Clean();
11379
11380	/* Result's setup. */
11381	if (is_ok)
11382	{
11383		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
11384	}
11385	else
11386	{
11387		if (is_error)
11388		{
11389			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
11390		}
11391		else
11392		{
11393			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
11394		}
11395	}
11396
11397	return STOP;
11398}
11399
11400/** @brief Test's preparations.
11401 */
11402void ParameterSetupErrorsTest::Prepare()
11403{
11404	/* Shortcut for GL functionality. */
11405	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
11406
11407	/* Auxiliary objects setup. */
11408
11409	/* 2D */
11410	gl.createTextures(GL_TEXTURE_2D, 1, &m_to_2D);
11411	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
11412
11413	/* 3D */
11414	gl.createTextures(GL_TEXTURE_2D_MULTISAMPLE, 1, &m_to_2D_ms);
11415	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
11416
11417	/* RECTANGLE */
11418	gl.createTextures(GL_TEXTURE_RECTANGLE, 1, &m_to_rectangle);
11419	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
11420
11421	/* Invalid texture object. */
11422	while (gl.isTexture(++m_to_invalid))
11423		;
11424	GLU_EXPECT_NO_ERROR(gl.getError(), "glIsTexture has failed");
11425
11426	/* Invalid parameter name. */
11427	glw::GLenum all_pnames[] = { GL_DEPTH_STENCIL_TEXTURE_MODE,
11428								 GL_TEXTURE_BASE_LEVEL,
11429								 GL_TEXTURE_COMPARE_FUNC,
11430								 GL_TEXTURE_COMPARE_MODE,
11431								 GL_TEXTURE_LOD_BIAS,
11432								 GL_TEXTURE_MIN_FILTER,
11433								 GL_TEXTURE_MAG_FILTER,
11434								 GL_TEXTURE_MIN_LOD,
11435								 GL_TEXTURE_MAX_LOD,
11436								 GL_TEXTURE_MAX_LEVEL,
11437								 GL_TEXTURE_SWIZZLE_R,
11438								 GL_TEXTURE_SWIZZLE_G,
11439								 GL_TEXTURE_SWIZZLE_B,
11440								 GL_TEXTURE_SWIZZLE_A,
11441								 GL_TEXTURE_WRAP_S,
11442								 GL_TEXTURE_WRAP_T,
11443								 GL_TEXTURE_WRAP_R,
11444								 GL_TEXTURE_BORDER_COLOR,
11445								 GL_TEXTURE_SWIZZLE_RGBA };
11446	glw::GLuint all_pnames_count = sizeof(all_pnames) / sizeof(all_pnames[0]);
11447
11448	bool is_valid = true;
11449
11450	while (is_valid)
11451	{
11452		is_valid = false;
11453		++m_pname_invalid;
11454
11455		for (glw::GLuint i = 0; i < all_pnames_count; ++i)
11456		{
11457			if (all_pnames[i] == m_pname_invalid)
11458			{
11459				is_valid = true;
11460
11461				break;
11462			}
11463		}
11464	}
11465
11466	/* Invalid depth stencil mode name. */
11467	glw::GLenum all_depth_stencil_modes[]	 = { GL_DEPTH_COMPONENT, GL_STENCIL_INDEX };
11468	glw::GLuint all_depth_stencil_modes_count = sizeof(all_depth_stencil_modes) / sizeof(all_depth_stencil_modes[0]);
11469
11470	is_valid = true;
11471
11472	while (is_valid)
11473	{
11474		is_valid = false;
11475		++m_depth_stencil_mode_invalid;
11476
11477		for (glw::GLuint i = 0; i < all_depth_stencil_modes_count; ++i)
11478		{
11479			if (all_depth_stencil_modes[i] == m_depth_stencil_mode_invalid)
11480			{
11481				is_valid = true;
11482
11483				break;
11484			}
11485		}
11486	}
11487}
11488
11489/** @brief Test (negative) of TextureParameterf
11490 *
11491 *  @return Test result.
11492 */
11493bool ParameterSetupErrorsTest::Testf()
11494{
11495	/* Shortcut for GL functionality. */
11496	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
11497
11498	/* Result. */
11499	bool is_ok = true;
11500
11501	/* Check that INVALID_ENUM is generated by TextureParameter* if pname is
11502	 not one of the accepted defined values. */
11503	{
11504		gl.textureParameterf(m_to_2D, m_pname_invalid, 1.f);
11505
11506		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterf",
11507								  "pname is not one of the accepted defined values.");
11508	}
11509
11510	/* Check that INVALID_ENUM is generated by TextureParameter* if params
11511	 should have a defined constant value (based on the value of pname) and
11512	 does not. */
11513	{
11514		gl.textureParameterf(m_to_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, (glw::GLfloat)m_depth_stencil_mode_invalid);
11515
11516		is_ok &=
11517			CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterf",
11518							 "params should have a defined constant value (based on the value of pname) and does not.");
11519	}
11520	/* Check that INVALID_ENUM is generated if TextureParameter{if} is called
11521	 for a non-scalar parameter (pname TEXTURE_BORDER_COLOR or
11522	 TEXTURE_SWIZZLE_RGBA). */
11523	{
11524		gl.textureParameterf(m_to_2D, GL_TEXTURE_BORDER_COLOR, 1.f);
11525
11526		is_ok &=
11527			CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterf",
11528							 "called for a non-scalar parameter (pname TEXTURE_BORDER_COLOR or TEXTURE_SWIZZLE_RGBA).");
11529	}
11530
11531	/* Check that INVALID_ENUM is generated by TextureParameter* if the
11532	 effective target is either TEXTURE_2D_MULTISAMPLE or
11533	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states. */
11534	{
11535		gl.textureParameterf(m_to_2D_ms, GL_TEXTURE_LOD_BIAS, 1.f);
11536
11537		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterf",
11538								  "the  effective target is either TEXTURE_2D_MULTISAMPLE or  "
11539								  "TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states.");
11540	}
11541
11542	/* Check that INVALID_ENUM is generated by TextureParameter* if the
11543	 effective target is TEXTURE_RECTANGLE and either of pnames
11544	 TEXTURE_WRAP_S or TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE,
11545	 MIRRORED_REPEAT or REPEAT. */
11546	{
11547		gl.textureParameterf(m_to_rectangle, GL_TEXTURE_WRAP_S, GL_MIRROR_CLAMP_TO_EDGE);
11548
11549		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterf",
11550								  "the effective target is TEXTURE_RECTANGLE and either of pnames TEXTURE_WRAP_S or "
11551								  "TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE, MIRRORED_REPEAT or REPEAT.");
11552	}
11553
11554	/* Check that INVALID_ENUM is generated by TextureParameter* if the
11555	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is
11556	 set to a value other than NEAREST or LINEAR (no mipmap filtering is
11557	 permitted). */
11558	{
11559		gl.textureParameterf(m_to_rectangle, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
11560
11561		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterf",
11562								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is set to a "
11563								  "value other than NEAREST or LINEAR (no mipmap filtering is permitted).");
11564	}
11565
11566	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
11567	 effective target is either TEXTURE_2D_MULTISAMPLE or
11568	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname TEXTURE_BASE_LEVEL is set to a
11569	 value other than zero. */
11570	{
11571		gl.textureParameterf(m_to_2D_ms, GL_TEXTURE_BASE_LEVEL, 1.f);
11572
11573		is_ok &=
11574			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterf",
11575							 "the effective target is either TEXTURE_2D_MULTISAMPLE or TEXTURE_2D_MULTISAMPLE_ARRAY, "
11576							 "and pname TEXTURE_BASE_LEVEL is set to a value other than zero.");
11577	}
11578
11579	/* Check that INVALID_OPERATION is generated by TextureParameter* if
11580	 texture is not the name of an existing texture object. */
11581	{
11582		gl.textureParameterf(m_to_invalid, GL_TEXTURE_LOD_BIAS, 1.f);
11583
11584		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterf",
11585								  "texture is not the name of an existing texture object.");
11586	}
11587
11588	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
11589	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is
11590	 set to any value other than zero. */
11591	{
11592		gl.textureParameterf(m_to_rectangle, GL_TEXTURE_BASE_LEVEL, 1.f);
11593
11594		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterf",
11595								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is set to "
11596								  "any value other than zero. ");
11597	}
11598
11599	/* Check that INVALID_VALUE is generated by TextureParameter* if pname is
11600	 TEXTURE_BASE_LEVEL or TEXTURE_MAX_LEVEL, and param or params is
11601	 negative. */
11602	{
11603		gl.textureParameterf(m_to_2D, GL_TEXTURE_BASE_LEVEL, -1.f);
11604
11605		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameterf",
11606								  "pname is TEXTURE_BASE_LEVEL and param is negative.");
11607
11608		gl.textureParameterf(m_to_2D, GL_TEXTURE_MAX_LEVEL, -1.f);
11609
11610		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameterf",
11611								  "pname is TEXTURE_MAX_LEVEL and param is negative.");
11612	}
11613
11614	return is_ok;
11615}
11616
11617/** @brief Test (negative) of TextureParameteri
11618 *
11619 *  @return Test result.
11620 */
11621bool ParameterSetupErrorsTest::Testi()
11622{
11623	/* Shortcut for GL functionality. */
11624	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
11625
11626	/* Result. */
11627	bool is_ok = true;
11628
11629	/* Check that INVALID_ENUM is generated by TextureParameter* if pname is
11630	 not one of the accepted defined values. */
11631	{
11632		gl.textureParameteri(m_to_2D, m_pname_invalid, 1);
11633
11634		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteri",
11635								  "pname is not one of the accepted defined values.");
11636	}
11637
11638	/* Check that INVALID_ENUM is generated by TextureParameter* if params
11639	 should have a defined constant value (based on the value of pname) and
11640	 does not. */
11641	{
11642		gl.textureParameteri(m_to_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, m_depth_stencil_mode_invalid);
11643
11644		is_ok &=
11645			CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteri",
11646							 "params should have a defined constant value (based on the value of pname) and does not.");
11647	}
11648	/* Check that INVALID_ENUM is generated if TextureParameter{if} is called
11649	 for a non-scalar parameter (pname TEXTURE_BORDER_COLOR or
11650	 TEXTURE_SWIZZLE_RGBA). */
11651	{
11652		gl.textureParameteri(m_to_2D, GL_TEXTURE_BORDER_COLOR, 1);
11653
11654		is_ok &=
11655			CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteri",
11656							 "called for a non-scalar parameter (pname TEXTURE_BORDER_COLOR or TEXTURE_SWIZZLE_RGBA).");
11657	}
11658
11659	/* Check that INVALID_ENUM is generated by TextureParameter* if the
11660	 effective target is either TEXTURE_2D_MULTISAMPLE or
11661	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states. */
11662	{
11663		gl.textureParameteri(m_to_2D_ms, GL_TEXTURE_LOD_BIAS, 1);
11664
11665		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteri",
11666								  "the  effective target is either TEXTURE_2D_MULTISAMPLE or  "
11667								  "TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states.");
11668	}
11669
11670	/* Check that INVALID_ENUM is generated by TextureParameter* if the
11671	 effective target is TEXTURE_RECTANGLE and either of pnames
11672	 TEXTURE_WRAP_S or TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE,
11673	 MIRRORED_REPEAT or REPEAT. */
11674	{
11675		gl.textureParameteri(m_to_rectangle, GL_TEXTURE_WRAP_S, GL_MIRROR_CLAMP_TO_EDGE);
11676
11677		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteri",
11678								  "the effective target is TEXTURE_RECTANGLE and either of pnames TEXTURE_WRAP_S or "
11679								  "TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE, MIRRORED_REPEAT or REPEAT.");
11680	}
11681
11682	/* Check that INVALID_ENUM is generated by TextureParameter* if the
11683	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is
11684	 set to a value other than NEAREST or LINEAR (no mipmap filtering is
11685	 permitted). */
11686	{
11687		gl.textureParameteri(m_to_rectangle, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
11688
11689		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteri",
11690								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is set to a "
11691								  "value other than NEAREST or LINEAR (no mipmap filtering is permitted).");
11692	}
11693
11694	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
11695	 effective target is either TEXTURE_2D_MULTISAMPLE or
11696	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname TEXTURE_BASE_LEVEL is set to a
11697	 value other than zero. */
11698	{
11699		gl.textureParameteri(m_to_2D_ms, GL_TEXTURE_BASE_LEVEL, 1);
11700
11701		is_ok &=
11702			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameteri",
11703							 "the effective target is either TEXTURE_2D_MULTISAMPLE or TEXTURE_2D_MULTISAMPLE_ARRAY, "
11704							 "and pname TEXTURE_BASE_LEVEL is set to a value other than zero.");
11705	}
11706
11707	/* Check that INVALID_OPERATION is generated by TextureParameter* if
11708	 texture is not the name of an existing texture object. */
11709	{
11710		gl.textureParameteri(m_to_invalid, GL_TEXTURE_LOD_BIAS, 1);
11711
11712		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameteri",
11713								  "texture is not the name of an existing texture object.");
11714	}
11715
11716	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
11717	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is
11718	 set to any value other than zero. */
11719	{
11720		gl.textureParameteri(m_to_rectangle, GL_TEXTURE_BASE_LEVEL, 1);
11721
11722		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameteri",
11723								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is set to "
11724								  "any value other than zero. ");
11725	}
11726
11727	/* Check that INVALID_VALUE is generated by TextureParameter* if pname is
11728	 TEXTURE_BASE_LEVEL or TEXTURE_MAX_LEVEL, and param or params is
11729	 negative. */
11730	{
11731		gl.textureParameteri(m_to_2D, GL_TEXTURE_BASE_LEVEL, -1);
11732
11733		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameteri",
11734								  "pname is TEXTURE_BASE_LEVEL and param is negative.");
11735
11736		gl.textureParameteri(m_to_2D, GL_TEXTURE_MAX_LEVEL, -1);
11737
11738		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameteri",
11739								  "pname is TEXTURE_MAX_LEVEL and param is negative.");
11740	}
11741
11742	return is_ok;
11743}
11744
11745/** @brief Test (negative) of TextureParameterfv
11746 *
11747 *  @return Test result.
11748 */
11749bool ParameterSetupErrorsTest::Testfv()
11750{
11751	/* Shortcut for GL functionality. */
11752	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
11753
11754	/* Result. */
11755	bool is_ok = true;
11756
11757	glw::GLfloat one						= 1.f;
11758	glw::GLfloat minus_one					= -1.f;
11759	glw::GLfloat depth_stencil_mode_invalid = (glw::GLfloat)m_depth_stencil_mode_invalid;
11760	glw::GLfloat wrap_invalid				= (glw::GLfloat)GL_MIRROR_CLAMP_TO_EDGE;
11761	glw::GLfloat min_filter_invalid			= (glw::GLfloat)GL_NEAREST_MIPMAP_NEAREST;
11762
11763	/* Check that INVALID_ENUM is generated by TextureParameter* if pname is
11764	 not one of the accepted defined values. */
11765	{
11766		gl.textureParameterfv(m_to_2D, m_pname_invalid, &one);
11767
11768		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterfv",
11769								  "pname is not one of the accepted defined values.");
11770	}
11771
11772	/* Check that INVALID_ENUM is generated by TextureParameter* if params
11773	 should have a defined constant value (based on the value of pname) and
11774	 does not. */
11775	{
11776		gl.textureParameterfv(m_to_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, &depth_stencil_mode_invalid);
11777
11778		is_ok &=
11779			CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterfv",
11780							 "params should have a defined constant value (based on the value of pname) and does not.");
11781	}
11782
11783	/* Check that INVALID_ENUM is generated by TextureParameter* if the
11784	 effective target is either TEXTURE_2D_MULTISAMPLE or
11785	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states. */
11786	{
11787		gl.textureParameterfv(m_to_2D_ms, GL_TEXTURE_LOD_BIAS, &one);
11788
11789		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterfv",
11790								  "the  effective target is either TEXTURE_2D_MULTISAMPLE or  "
11791								  "TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states.");
11792	}
11793
11794	/* Check that INVALID_ENUM is generated by TextureParameter* if the
11795	 effective target is TEXTURE_RECTANGLE and either of pnames
11796	 TEXTURE_WRAP_S or TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE,
11797	 MIRRORED_REPEAT or REPEAT. */
11798	{
11799		gl.textureParameterfv(m_to_rectangle, GL_TEXTURE_WRAP_S, &wrap_invalid);
11800
11801		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterfv",
11802								  "the effective target is TEXTURE_RECTANGLE and either of pnames TEXTURE_WRAP_S or "
11803								  "TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE, MIRRORED_REPEAT or REPEAT.");
11804	}
11805
11806	/* Check that INVALID_ENUM is generated by TextureParameter* if the
11807	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is
11808	 set to a value other than NEAREST or LINEAR (no mipmap filtering is
11809	 permitted). */
11810	{
11811		gl.textureParameterfv(m_to_rectangle, GL_TEXTURE_MIN_FILTER, &min_filter_invalid);
11812
11813		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterfv",
11814								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is set to a "
11815								  "value other than NEAREST or LINEAR (no mipmap filtering is permitted).");
11816	}
11817
11818	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
11819	 effective target is either TEXTURE_2D_MULTISAMPLE or
11820	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname TEXTURE_BASE_LEVEL is set to a
11821	 value other than zero. */
11822	{
11823		gl.textureParameterfv(m_to_2D_ms, GL_TEXTURE_BASE_LEVEL, &one);
11824
11825		is_ok &=
11826			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterfv",
11827							 "the effective target is either TEXTURE_2D_MULTISAMPLE or TEXTURE_2D_MULTISAMPLE_ARRAY, "
11828							 "and pname TEXTURE_BASE_LEVEL is set to a value other than zero.");
11829	}
11830
11831	/* Check that INVALID_OPERATION is generated by TextureParameter* if
11832	 texture is not the name of an existing texture object. */
11833	{
11834		gl.textureParameterfv(m_to_invalid, GL_TEXTURE_LOD_BIAS, &one);
11835
11836		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterfv",
11837								  "texture is not the name of an existing texture object.");
11838	}
11839
11840	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
11841	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is
11842	 set to any value other than zero. */
11843	{
11844		gl.textureParameterfv(m_to_rectangle, GL_TEXTURE_BASE_LEVEL, &one);
11845
11846		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterfv",
11847								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is set to "
11848								  "any value other than zero. ");
11849	}
11850
11851	/* Check that INVALID_VALUE is generated by TextureParameter* if pname is
11852	 TEXTURE_BASE_LEVEL or TEXTURE_MAX_LEVEL, and param or params is
11853	 negative. */
11854	{
11855		gl.textureParameterfv(m_to_2D, GL_TEXTURE_BASE_LEVEL, &minus_one);
11856
11857		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameterfv",
11858								  "pname is TEXTURE_BASE_LEVEL and param is negative.");
11859
11860		gl.textureParameterfv(m_to_2D, GL_TEXTURE_MAX_LEVEL, &minus_one);
11861
11862		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameterfv",
11863								  "pname is TEXTURE_MAX_LEVEL and param is negative.");
11864	}
11865
11866	return is_ok;
11867}
11868
11869/** @brief Test (negative) of TextureParameteriv
11870 *
11871 *  @return Test result.
11872 */
11873bool ParameterSetupErrorsTest::Testiv()
11874{
11875	/* Shortcut for GL functionality. */
11876	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
11877
11878	/* Result. */
11879	bool is_ok = true;
11880
11881	glw::GLint one						  = 1;
11882	glw::GLint minus_one				  = -1;
11883	glw::GLint depth_stencil_mode_invalid = (glw::GLint)m_depth_stencil_mode_invalid;
11884	glw::GLint wrap_invalid				  = (glw::GLint)GL_MIRROR_CLAMP_TO_EDGE;
11885	glw::GLint min_filter_invalid		  = (glw::GLint)GL_NEAREST_MIPMAP_NEAREST;
11886
11887	/* Check that INVALID_ENUM is generated by TextureParameter* if pname is
11888	 not one of the accepted defined values. */
11889	{
11890		gl.textureParameteriv(m_to_2D, m_pname_invalid, &one);
11891
11892		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteriv",
11893								  "pname is not one of the accepted defined values.");
11894	}
11895
11896	/* Check that INVALID_ENUM is generated by TextureParameter* if params
11897	 should have a defined constant value (based on the value of pname) and
11898	 does not. */
11899	{
11900		gl.textureParameteriv(m_to_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, &depth_stencil_mode_invalid);
11901
11902		is_ok &=
11903			CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteriv",
11904							 "params should have a defined constant value (based on the value of pname) and does not.");
11905	}
11906
11907	/* Check that INVALID_ENUM is generated by TextureParameter* if the
11908	 effective target is either TEXTURE_2D_MULTISAMPLE or
11909	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states. */
11910	{
11911		gl.textureParameteriv(m_to_2D_ms, GL_TEXTURE_LOD_BIAS, &one);
11912
11913		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteriv",
11914								  "the  effective target is either TEXTURE_2D_MULTISAMPLE or  "
11915								  "TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states.");
11916	}
11917
11918	/* Check that INVALID_ENUM is generated by TextureParameter* if the
11919	 effective target is TEXTURE_RECTANGLE and either of pnames
11920	 TEXTURE_WRAP_S or TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE,
11921	 MIRRORED_REPEAT or REPEAT. */
11922	{
11923		gl.textureParameteriv(m_to_rectangle, GL_TEXTURE_WRAP_S, &wrap_invalid);
11924
11925		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteriv",
11926								  "the effective target is TEXTURE_RECTANGLE and either of pnames TEXTURE_WRAP_S or "
11927								  "TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE, MIRRORED_REPEAT or REPEAT.");
11928	}
11929
11930	/* Check that INVALID_ENUM is generated by TextureParameter* if the
11931	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is
11932	 set to a value other than NEAREST or LINEAR (no mipmap filtering is
11933	 permitted). */
11934	{
11935		gl.textureParameteriv(m_to_rectangle, GL_TEXTURE_MIN_FILTER, &min_filter_invalid);
11936
11937		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteriv",
11938								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is set to a "
11939								  "value other than NEAREST or LINEAR (no mipmap filtering is permitted).");
11940	}
11941
11942	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
11943	 effective target is either TEXTURE_2D_MULTISAMPLE or
11944	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname TEXTURE_BASE_LEVEL is set to a
11945	 value other than zero. */
11946	{
11947		gl.textureParameteriv(m_to_2D_ms, GL_TEXTURE_BASE_LEVEL, &one);
11948
11949		is_ok &=
11950			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameteriv",
11951							 "the effective target is either TEXTURE_2D_MULTISAMPLE or TEXTURE_2D_MULTISAMPLE_ARRAY, "
11952							 "and pname TEXTURE_BASE_LEVEL is set to a value other than zero.");
11953	}
11954
11955	/* Check that INVALID_OPERATION is generated by TextureParameter* if
11956	 texture is not the name of an existing texture object. */
11957	{
11958		gl.textureParameteriv(m_to_invalid, GL_TEXTURE_LOD_BIAS, &one);
11959
11960		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameteriv",
11961								  "texture is not the name of an existing texture object.");
11962	}
11963
11964	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
11965	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is
11966	 set to any value other than zero. */
11967	{
11968		gl.textureParameteriv(m_to_rectangle, GL_TEXTURE_BASE_LEVEL, &one);
11969
11970		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameteriv",
11971								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is set to "
11972								  "any value other than zero. ");
11973	}
11974
11975	/* Check that INVALID_VALUE is generated by TextureParameter* if pname is
11976	 TEXTURE_BASE_LEVEL or TEXTURE_MAX_LEVEL, and param or params is
11977	 negative. */
11978	{
11979		gl.textureParameteriv(m_to_2D, GL_TEXTURE_BASE_LEVEL, &minus_one);
11980
11981		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameteriv",
11982								  "pname is TEXTURE_BASE_LEVEL and param is negative.");
11983
11984		gl.textureParameteriv(m_to_2D, GL_TEXTURE_MAX_LEVEL, &minus_one);
11985
11986		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameteriv",
11987								  "pname is TEXTURE_MAX_LEVEL and param is negative.");
11988	}
11989
11990	return is_ok;
11991}
11992
11993/** @brief Test (negative) of TextureParameterIiv
11994 *
11995 *  @return Test result.
11996 */
11997bool ParameterSetupErrorsTest::TestIiv()
11998{
11999	/* Shortcut for GL functionality. */
12000	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
12001
12002	/* Result. */
12003	bool is_ok = true;
12004
12005	glw::GLint one						  = 1;
12006	glw::GLint minus_one				  = -1;
12007	glw::GLint depth_stencil_mode_invalid = (glw::GLint)m_depth_stencil_mode_invalid;
12008	glw::GLint wrap_invalid				  = (glw::GLint)GL_MIRROR_CLAMP_TO_EDGE;
12009	glw::GLint min_filter_invalid		  = (glw::GLint)GL_NEAREST_MIPMAP_NEAREST;
12010
12011	/* Check that INVALID_ENUM is generated by TextureParameter* if pname is
12012	 not one of the accepted defined values. */
12013	{
12014		gl.textureParameterIiv(m_to_2D, m_pname_invalid, &one);
12015
12016		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIiv",
12017								  "pname is not one of the accepted defined values.");
12018	}
12019
12020	/* Check that INVALID_ENUM is generated by TextureParameter* if params
12021	 should have a defined constant value (based on the value of pname) and
12022	 does not. */
12023	{
12024		gl.textureParameterIiv(m_to_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, &depth_stencil_mode_invalid);
12025
12026		is_ok &=
12027			CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIiv",
12028							 "params should have a defined constant value (based on the value of pname) and does not.");
12029	}
12030
12031	/* Check that INVALID_ENUM is generated by TextureParameter* if the
12032	 effective target is either TEXTURE_2D_MULTISAMPLE or
12033	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states. */
12034	{
12035		gl.textureParameterIiv(m_to_2D_ms, GL_TEXTURE_LOD_BIAS, &one);
12036
12037		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIiv",
12038								  "the  effective target is either TEXTURE_2D_MULTISAMPLE or  "
12039								  "TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states.");
12040	}
12041
12042	/* Check that INVALID_ENUM is generated by TextureParameter* if the
12043	 effective target is TEXTURE_RECTANGLE and either of pnames
12044	 TEXTURE_WRAP_S or TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE,
12045	 MIRRORED_REPEAT or REPEAT. */
12046	{
12047		gl.textureParameterIiv(m_to_rectangle, GL_TEXTURE_WRAP_S, &wrap_invalid);
12048
12049		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIiv",
12050								  "the effective target is TEXTURE_RECTANGLE and either of pnames TEXTURE_WRAP_S or "
12051								  "TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE, MIRRORED_REPEAT or REPEAT.");
12052	}
12053
12054	/* Check that INVALID_ENUM is generated by TextureParameter* if the
12055	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is
12056	 set to a value other than NEAREST or LINEAR (no mipmap filtering is
12057	 permitted). */
12058	{
12059		gl.textureParameterIiv(m_to_rectangle, GL_TEXTURE_MIN_FILTER, &min_filter_invalid);
12060
12061		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIiv",
12062								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is set to a "
12063								  "value other than NEAREST or LINEAR (no mipmap filtering is permitted).");
12064	}
12065
12066	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
12067	 effective target is either TEXTURE_2D_MULTISAMPLE or
12068	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname TEXTURE_BASE_LEVEL is set to a
12069	 value other than zero. */
12070	{
12071		gl.textureParameterIiv(m_to_2D_ms, GL_TEXTURE_BASE_LEVEL, &one);
12072
12073		is_ok &=
12074			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterIiv",
12075							 "the effective target is either TEXTURE_2D_MULTISAMPLE or TEXTURE_2D_MULTISAMPLE_ARRAY, "
12076							 "and pname TEXTURE_BASE_LEVEL is set to a value other than zero.");
12077	}
12078
12079	/* Check that INVALID_OPERATION is generated by TextureParameter* if
12080	 texture is not the name of an existing texture object. */
12081	{
12082		gl.textureParameterIiv(m_to_invalid, GL_TEXTURE_LOD_BIAS, &one);
12083
12084		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterIiv",
12085								  "texture is not the name of an existing texture object.");
12086	}
12087
12088	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
12089	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is
12090	 set to any value other than zero. */
12091	{
12092		gl.textureParameterIiv(m_to_rectangle, GL_TEXTURE_BASE_LEVEL, &one);
12093
12094		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterIiv",
12095								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is set to "
12096								  "any value other than zero. ");
12097	}
12098
12099	/* Check that INVALID_VALUE is generated by TextureParameter* if pname is
12100	 TEXTURE_BASE_LEVEL or TEXTURE_MAX_LEVEL, and param or params is
12101	 negative. */
12102	{
12103		gl.textureParameterIiv(m_to_2D, GL_TEXTURE_BASE_LEVEL, &minus_one);
12104
12105		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameterIiv",
12106								  "pname is TEXTURE_BASE_LEVEL and param is negative.");
12107
12108		gl.textureParameterIiv(m_to_2D, GL_TEXTURE_MAX_LEVEL, &minus_one);
12109
12110		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameterIiv",
12111								  "pname is TEXTURE_MAX_LEVEL and param is negative.");
12112	}
12113
12114	return is_ok;
12115}
12116
12117/** @brief Test (negative) of TextureParameterIuiv
12118 *
12119 *  @return Test result.
12120 */
12121bool ParameterSetupErrorsTest::TestIuiv()
12122{
12123	/* Shortcut for GL functionality. */
12124	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
12125
12126	/* Result. */
12127	bool is_ok = true;
12128
12129	glw::GLuint one						   = 1;
12130	glw::GLuint depth_stencil_mode_invalid = (glw::GLint)m_depth_stencil_mode_invalid;
12131	glw::GLuint wrap_invalid			   = (glw::GLint)GL_MIRROR_CLAMP_TO_EDGE;
12132	glw::GLuint min_filter_invalid		   = (glw::GLint)GL_NEAREST_MIPMAP_NEAREST;
12133
12134	/* Check that INVALID_ENUM is generated by TextureParameter* if pname is
12135	 not one of the accepted defined values. */
12136	{
12137		gl.textureParameterIuiv(m_to_2D, m_pname_invalid, &one);
12138
12139		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIuiv",
12140								  "pname is not one of the accepted defined values.");
12141	}
12142
12143	/* Check that INVALID_ENUM is generated by TextureParameter* if params
12144	 should have a defined constant value (based on the value of pname) and
12145	 does not. */
12146	{
12147		gl.textureParameterIuiv(m_to_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, &depth_stencil_mode_invalid);
12148
12149		is_ok &=
12150			CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIuiv",
12151							 "params should have a defined constant value (based on the value of pname) and does not.");
12152	}
12153
12154	/* Check that INVALID_ENUM is generated by TextureParameter* if the
12155	 effective target is either TEXTURE_2D_MULTISAMPLE or
12156	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states. */
12157	{
12158		gl.textureParameterIuiv(m_to_2D_ms, GL_TEXTURE_LOD_BIAS, &one);
12159
12160		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIuiv",
12161								  "the  effective target is either TEXTURE_2D_MULTISAMPLE or  "
12162								  "TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states.");
12163	}
12164
12165	/* Check that INVALID_ENUM is generated by TextureParameter* if the
12166	 effective target is TEXTURE_RECTANGLE and either of pnames
12167	 TEXTURE_WRAP_S or TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE,
12168	 MIRRORED_REPEAT or REPEAT. */
12169	{
12170		gl.textureParameterIuiv(m_to_rectangle, GL_TEXTURE_WRAP_S, &wrap_invalid);
12171
12172		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIuiv",
12173								  "the effective target is TEXTURE_RECTANGLE and either of pnames TEXTURE_WRAP_S or "
12174								  "TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE, MIRRORED_REPEAT or REPEAT.");
12175	}
12176
12177	/* Check that INVALID_ENUM is generated by TextureParameter* if the
12178	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is
12179	 set to a value other than NEAREST or LINEAR (no mipmap filtering is
12180	 permitted). */
12181	{
12182		gl.textureParameterIuiv(m_to_rectangle, GL_TEXTURE_MIN_FILTER, &min_filter_invalid);
12183
12184		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIuiv",
12185								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is set to a "
12186								  "value other than NEAREST or LINEAR (no mipmap filtering is permitted).");
12187	}
12188
12189	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
12190	 effective target is either TEXTURE_2D_MULTISAMPLE or
12191	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname TEXTURE_BASE_LEVEL is set to a
12192	 value other than zero. */
12193	{
12194		gl.textureParameterIuiv(m_to_2D_ms, GL_TEXTURE_BASE_LEVEL, &one);
12195
12196		is_ok &=
12197			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterIuiv",
12198							 "the effective target is either TEXTURE_2D_MULTISAMPLE or TEXTURE_2D_MULTISAMPLE_ARRAY, "
12199							 "and pname TEXTURE_BASE_LEVEL is set to a value other than zero.");
12200	}
12201
12202	/* Check that INVALID_OPERATION is generated by TextureParameter* if
12203	 texture is not the name of an existing texture object. */
12204	{
12205		gl.textureParameterIuiv(m_to_invalid, GL_TEXTURE_LOD_BIAS, &one);
12206
12207		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterIuiv",
12208								  "texture is not the name of an existing texture object.");
12209	}
12210
12211	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
12212	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is
12213	 set to any value other than zero. */
12214	{
12215		gl.textureParameterIuiv(m_to_rectangle, GL_TEXTURE_BASE_LEVEL, &one);
12216
12217		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterIuiv",
12218								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is set to "
12219								  "any value other than zero. ");
12220	}
12221
12222	return is_ok;
12223}
12224
12225/** @brief Clean GL objects, test variables and GL errors.
12226 */
12227void ParameterSetupErrorsTest::Clean()
12228{
12229	/* Shortcut for GL functionality. */
12230	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
12231
12232	/* Cleanup. */
12233	if (m_to_2D)
12234	{
12235		gl.deleteTextures(1, &m_to_2D);
12236
12237		m_to_2D = 0;
12238	}
12239
12240	if (m_to_2D_ms)
12241	{
12242		gl.deleteTextures(1, &m_to_2D_ms);
12243
12244		m_to_2D_ms = 0;
12245	}
12246
12247	if (m_to_rectangle)
12248	{
12249		gl.deleteTextures(1, &m_to_rectangle);
12250
12251		m_to_rectangle = 0;
12252	}
12253
12254	if (m_to_invalid)
12255	{
12256		gl.deleteTextures(1, &m_to_invalid);
12257
12258		m_to_invalid = 0;
12259	}
12260
12261	m_to_invalid	= 0;
12262	m_pname_invalid = 0;
12263
12264	while (GL_NO_ERROR != gl.getError())
12265		;
12266}
12267
12268/******************************** Generate Mipmap Errors Test Implementation   ********************************/
12269
12270/** @brief Generate Mipmap Errors Test constructor.
12271 *
12272 *  @param [in] context     OpenGL context.
12273 */
12274GenerateMipmapErrorsTest::GenerateMipmapErrorsTest(deqp::Context& context)
12275	: deqp::TestCase(context, "textures_generate_mipmap_errors", "Texture Generate Mipmap Errors Test")
12276{
12277	/* Intentionally left blank. */
12278}
12279
12280/** @brief Iterate Generate Mipmap Errors Test cases.
12281 *
12282 *  @return Iteration result.
12283 */
12284tcu::TestNode::IterateResult GenerateMipmapErrorsTest::iterate()
12285{
12286	/* Shortcut for GL functionality. */
12287	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
12288
12289	/* Get context setup. */
12290	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
12291	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
12292
12293	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
12294	{
12295		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
12296
12297		return STOP;
12298	}
12299
12300	/* Running tests. */
12301	bool is_ok	= true;
12302	bool is_error = false;
12303
12304	/* Objects. */
12305	glw::GLuint texture_invalid = 0;
12306	glw::GLuint texture_cube	= 0;
12307
12308	try
12309	{
12310		/* Preparations. */
12311
12312		/* incomplete cube map */
12313		gl.genTextures(1, &texture_cube);
12314		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
12315
12316		gl.bindTexture(GL_TEXTURE_CUBE_MAP, texture_cube);
12317		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
12318
12319		gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, s_reference_internalformat, s_reference_width,
12320					  s_reference_height, 0, s_reference_format, s_reference_type, s_reference_data);
12321		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");
12322
12323		/* invalid texture */
12324		while (gl.isTexture(++texture_invalid))
12325			;
12326
12327		/* Check that INVALID_OPERATION is generated by GenerateTextureMipmap if
12328		 texture is not the name of an existing texture object. */
12329		gl.generateTextureMipmap(texture_invalid);
12330		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGenerateTextureMipmap",
12331								  "texture is not the name of an existing texture object.");
12332
12333		/* Check that INVALID_OPERATION is generated by GenerateTextureMipmap if
12334		 target is TEXTURE_CUBE_MAP or TEXTURE_CUBE_MAP_ARRAY, and the specified
12335		 texture object is not cube complete or cube array complete,
12336		 respectively. */
12337		gl.generateTextureMipmap(texture_cube);
12338		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGenerateTextureMipmap",
12339								  "target is TEXTURE_CUBE_MAP or TEXTURE_CUBE_MAP_ARRAY, and the specified texture "
12340								  "object is not cube complete or cube array complete, respectively.");
12341	}
12342	catch (...)
12343	{
12344		is_ok	= false;
12345		is_error = true;
12346	}
12347
12348	/* Cleanup. */
12349	if (texture_cube)
12350	{
12351		gl.deleteTextures(1, &texture_cube);
12352	}
12353
12354	while (GL_NO_ERROR != gl.getError())
12355		;
12356
12357	/* Result's setup. */
12358	if (is_ok)
12359	{
12360		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
12361	}
12362	else
12363	{
12364		if (is_error)
12365		{
12366			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
12367		}
12368		else
12369		{
12370			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
12371		}
12372	}
12373
12374	return STOP;
12375}
12376
12377/** Reference data. */
12378const glw::GLubyte GenerateMipmapErrorsTest::s_reference_data[] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
12379																	0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF };
12380
12381/** Reference data parameters. */
12382const glw::GLuint GenerateMipmapErrorsTest::s_reference_width		   = 4;
12383const glw::GLuint GenerateMipmapErrorsTest::s_reference_height		   = 4;
12384const glw::GLenum GenerateMipmapErrorsTest::s_reference_internalformat = GL_R8;
12385const glw::GLenum GenerateMipmapErrorsTest::s_reference_format		   = GL_RED;
12386const glw::GLenum GenerateMipmapErrorsTest::s_reference_type		   = GL_UNSIGNED_BYTE;
12387
12388/******************************** Bind Unit Errors Test Implementation   ********************************/
12389
12390/** @brief Bind Unit Errors Test constructor.
12391 *
12392 *  @param [in] context     OpenGL context.
12393 */
12394BindUnitErrorsTest::BindUnitErrorsTest(deqp::Context& context)
12395	: deqp::TestCase(context, "textures_bind_unit_errors", "Texture Bind Unit Errors Test")
12396{
12397	/* Intentionally left blank. */
12398}
12399
12400/** @brief IterateBind Unit Errors Test cases.
12401 *
12402 *  @return Iteration result.
12403 */
12404tcu::TestNode::IterateResult BindUnitErrorsTest::iterate()
12405{
12406	/* Shortcut for GL functionality. */
12407	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
12408
12409	/* Get context setup. */
12410	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
12411	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
12412
12413	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
12414	{
12415		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
12416
12417		return STOP;
12418	}
12419
12420	/* Running tests. */
12421	bool is_ok	= true;
12422	bool is_error = false;
12423
12424	/* Objects. */
12425	glw::GLuint texture_invalid = 0;
12426
12427	try
12428	{
12429		/* Prepare invalid texture */
12430		while (gl.isTexture(++texture_invalid))
12431			;
12432
12433		/* incomplete cube map */
12434
12435		/* Check that INVALID_OPERATION error is generated if texture is not zero
12436		 or the name of an existing texture object. */
12437		gl.bindTextureUnit(0, texture_invalid);
12438		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glBindTextureUnit",
12439								  "texture is not zero or the name of an existing texture object.");
12440	}
12441	catch (...)
12442	{
12443		is_ok	= false;
12444		is_error = true;
12445	}
12446
12447	/* Cleanup. */
12448	while (GL_NO_ERROR != gl.getError())
12449		;
12450
12451	/* Result's setup. */
12452	if (is_ok)
12453	{
12454		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
12455	}
12456	else
12457	{
12458		if (is_error)
12459		{
12460			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
12461		}
12462		else
12463		{
12464			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
12465		}
12466	}
12467
12468	return STOP;
12469}
12470
12471/******************************** Image Query Errors Test Implementation   ********************************/
12472
12473/** @brief Image Query Errors Test constructor.
12474 *
12475 *  @param [in] context     OpenGL context.
12476 */
12477ImageQueryErrorsTest::ImageQueryErrorsTest(deqp::Context& context)
12478	: deqp::TestCase(context, "textures_image_query_errors", "Texture Image Query Errors Test")
12479{
12480	/* Intentionally left blank. */
12481}
12482
12483/** Reference data. */
12484const glw::GLuint ImageQueryErrorsTest::s_reference_data[] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
12485															   0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF };
12486
12487/** Reference data parameters. */
12488const glw::GLuint ImageQueryErrorsTest::s_reference_width					  = 4;
12489const glw::GLuint ImageQueryErrorsTest::s_reference_height					  = 4;
12490const glw::GLuint ImageQueryErrorsTest::s_reference_size					  = sizeof(s_reference_data);
12491const glw::GLenum ImageQueryErrorsTest::s_reference_internalformat			  = GL_R8;
12492const glw::GLenum ImageQueryErrorsTest::s_reference_internalformat_int		  = GL_R8I;
12493const glw::GLenum ImageQueryErrorsTest::s_reference_internalformat_compressed = GL_COMPRESSED_RED_RGTC1;
12494const glw::GLenum ImageQueryErrorsTest::s_reference_format					  = GL_RED;
12495const glw::GLenum ImageQueryErrorsTest::s_reference_type					  = GL_UNSIGNED_INT;
12496
12497/** @brief Iterate Image Query Errors Test cases.
12498 *
12499 *  @return Iteration result.
12500 */
12501tcu::TestNode::IterateResult ImageQueryErrorsTest::iterate()
12502{
12503	/* Shortcut for GL functionality. */
12504	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
12505
12506	/* Get context setup. */
12507	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
12508	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
12509
12510	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
12511	{
12512		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
12513
12514		return STOP;
12515	}
12516
12517	/* Running tests. */
12518	bool is_ok	= true;
12519	bool is_error = false;
12520
12521	/* Objects. */
12522	glw::GLuint buffer										  = 0;
12523	glw::GLuint texture_invalid								  = 0;
12524	glw::GLuint texture_2D									  = 0;
12525	glw::GLuint texture_2D_int								  = 0;
12526	glw::GLuint texture_2D_ms								  = 0;
12527	glw::GLuint texture_2D_stencil							  = 0;
12528	glw::GLuint texture_2D_compressed						  = 0;
12529	glw::GLuint texture_cube								  = 0;
12530	glw::GLuint texture_rectangle							  = 0;
12531	glw::GLint  max_level									  = 0;
12532	char		store[s_reference_size * 6 /* for cubemap */] = {};
12533
12534	try
12535	{
12536		/* Preparations. */
12537
12538		/* Buffer. */
12539		gl.createBuffers(1, &buffer);
12540
12541		gl.namedBufferData(buffer, s_reference_size + 1, NULL, GL_STATIC_COPY);
12542		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData has failed");
12543
12544		/* 2D texture */
12545		gl.genTextures(1, &texture_2D);
12546		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
12547
12548		gl.bindTexture(GL_TEXTURE_2D, texture_2D);
12549		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
12550
12551		gl.texImage2D(GL_TEXTURE_2D, 0, s_reference_internalformat, s_reference_width, s_reference_height, 0,
12552					  s_reference_format, s_reference_type, s_reference_data);
12553		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");
12554
12555		/* 2D texture */
12556		gl.genTextures(1, &texture_2D);
12557		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
12558
12559		gl.bindTexture(GL_TEXTURE_2D, texture_2D);
12560		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
12561
12562		gl.texImage2D(GL_TEXTURE_2D, 0, s_reference_internalformat, s_reference_width, s_reference_height, 0,
12563					  s_reference_format, s_reference_type, s_reference_data);
12564		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");
12565
12566		/* incomplete cube map */
12567		gl.genTextures(1, &texture_cube);
12568		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
12569
12570		gl.bindTexture(GL_TEXTURE_CUBE_MAP, texture_cube);
12571		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
12572
12573		gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, s_reference_internalformat, s_reference_width,
12574					  s_reference_height, 0, s_reference_format, s_reference_type, s_reference_data);
12575		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");
12576
12577		/* 2D multisample */
12578		gl.createTextures(GL_TEXTURE_2D_MULTISAMPLE, 1, &texture_2D_ms);
12579		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
12580
12581		gl.textureStorage2DMultisample(texture_2D_ms, 1, s_reference_internalformat, s_reference_width,
12582									   s_reference_height, false);
12583		GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2DMultisample has failed");
12584
12585		/* 2D stencil */
12586		gl.createTextures(GL_TEXTURE_2D, 1, &texture_2D_stencil);
12587		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
12588
12589		gl.textureStorage2D(texture_2D_stencil, 1, GL_STENCIL_INDEX8, s_reference_width, s_reference_height);
12590		GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2DMultisample has failed");
12591
12592		/* 2D compressed texture  */
12593		gl.genTextures(1, &texture_2D_compressed);
12594		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
12595
12596		gl.bindTexture(GL_TEXTURE_2D, texture_2D_compressed);
12597		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
12598
12599		gl.texImage2D(GL_TEXTURE_2D, 0, s_reference_internalformat_compressed, s_reference_width, s_reference_height, 0,
12600					  s_reference_format, s_reference_type, s_reference_data);
12601		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");
12602
12603		gl.getIntegerv(GL_MAX_TEXTURE_SIZE, &max_level); /* assuming that x > log(x) */
12604		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");
12605
12606		/* Rectangle texture */
12607		gl.genTextures(1, &texture_rectangle);
12608		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
12609
12610		gl.bindTexture(GL_TEXTURE_RECTANGLE, texture_rectangle);
12611		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
12612
12613		gl.texImage2D(GL_TEXTURE_RECTANGLE, 0, s_reference_internalformat, s_reference_width, s_reference_height, 0,
12614					  s_reference_format, s_reference_type, s_reference_data);
12615		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");
12616
12617		/* invalid texture */
12618		while (gl.isTexture(++texture_invalid))
12619			;
12620
12621		/* Tests. */
12622
12623		/* Check that INVALID_OPERATION is generated by GetTextureImage functions if
12624		 resulting texture target is not an accepted value TEXTURE_1D,
12625		 TEXTURE_2D, TEXTURE_3D, TEXTURE_1D_ARRAY, TEXTURE_2D_ARRAY,
12626		 TEXTURE_CUBE_MAP_ARRAY, TEXTURE_RECTANGLE, and TEXTURE_CUBE_MAP. */
12627		gl.getTextureImage(texture_2D_ms, 0, s_reference_format, s_reference_type, s_reference_size, store);
12628		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage",
12629								  "resulting texture target is not an accepted value TEXTURE_1D, TEXTURE_2D, "
12630								  "TEXTURE_3D, TEXTURE_1D_ARRAY, TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP_ARRAY, "
12631								  "TEXTURE_RECTANGLE, and TEXTURE_CUBE_MAP.");
12632
12633		/* Check that INVALID_OPERATION is generated by GetTextureImage
12634		 if texture is not the name of an existing texture object. */
12635		gl.getTextureImage(texture_invalid, 0, s_reference_format, s_reference_type, s_reference_size, store);
12636		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage",
12637								  "texture is not the name of an existing texture object.");
12638
12639		/* Check that INVALID_OPERATION error is generated by GetTextureImage if
12640		 the effective target is TEXTURE_CUBE_MAP or TEXTURE_CUBE_MAP_ARRAY, and
12641		 the texture object is not cube complete or cube array complete,
12642		 respectively. */
12643		gl.getTextureImage(texture_cube, 0, s_reference_format, s_reference_type, s_reference_size * 6, store);
12644		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage",
12645								  "the effective target is TEXTURE_CUBE_MAP and the texture object is not cube "
12646								  "complete or cube array complete, respectively.");
12647
12648		/* Check that GL_INVALID_VALUE is generated if level is less than 0 or
12649		 larger than the maximum allowable level. */
12650		gl.getTextureImage(texture_2D, -1, s_reference_format, s_reference_type, s_reference_size, store);
12651		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetTextureImage", "level is less than 0.");
12652
12653		gl.getTextureImage(texture_2D, max_level, s_reference_format, s_reference_type, s_reference_size, store);
12654		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetTextureImage",
12655								  "level is larger than the maximum allowable level.");
12656
12657		/* Check that INVALID_VALUE error is generated if level is non-zero and the
12658		 effective target is TEXTURE_RECTANGLE. */
12659		gl.getTextureImage(texture_rectangle, 1, s_reference_format, s_reference_type, s_reference_size, store);
12660		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetTextureImage",
12661								  "level is non-zero and the effective target is TEXTURE_RECTANGLE.");
12662
12663		/* Check that INVALID_OPERATION error is generated if any of the following
12664		 mismatches between format and the internal format of the texture image
12665		 exist:
12666		 -  format is a color format (one of the formats in table 8.3 whose
12667		 target is the color buffer) and the base internal format of the
12668		 texture image is not a color format.
12669		 -  format is DEPTH_COMPONENT and the base internal format is  not
12670		 DEPTH_COMPONENT or DEPTH_STENCIL
12671		 -  format is DEPTH_STENCIL and the base internal format is not
12672		 DEPTH_STENCIL
12673		 -  format is STENCIL_INDEX and the base internal format is not
12674		 STENCIL_INDEX or DEPTH_STENCIL
12675		 -  format is one of the integer formats in table 8.3 and the internal
12676		 format of the texture image is not integer, or format is not one of
12677		 the integer formats in table 8.3 and the internal format is integer. */
12678		gl.getTextureImage(texture_2D_stencil, 0, s_reference_format /* red */, s_reference_type, s_reference_size,
12679						   store);
12680		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage",
12681								  "format is a color format (one of the formats in table 8.3 whose target is the color "
12682								  "buffer) and the base internal format of the texture image is not a color format.");
12683
12684		gl.getTextureImage(texture_2D, 0, GL_DEPTH_COMPONENT, s_reference_type, s_reference_size, store);
12685		is_ok &= CheckErrorAndLog(
12686			m_context, GL_INVALID_OPERATION, "glGetTextureImage",
12687			"format is DEPTH_COMPONENT and the base internal format is not DEPTH_COMPONENT or DEPTH_STENCIL.");
12688
12689		gl.getTextureImage(texture_2D, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, s_reference_size, store);
12690		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage",
12691								  "format is DEPTH_STENCIL and the base internal format is not DEPTH_STENCIL.");
12692
12693		gl.getTextureImage(texture_2D, 0, GL_STENCIL_INDEX, s_reference_type, s_reference_size, store);
12694		is_ok &= CheckErrorAndLog(
12695			m_context, GL_INVALID_OPERATION, "glGetTextureImage",
12696			"format is STENCIL_INDEX and the base internal format is not STENCIL_INDEX or DEPTH_STENCIL.");
12697
12698		gl.getTextureImage(texture_2D, 0, GL_RED_INTEGER, s_reference_type, s_reference_size, store);
12699		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage",
12700								  "format is one of the integer formats in table 8.3 and the internal format of the "
12701								  "texture image is not integer.");
12702
12703		gl.getTextureImage(texture_2D_int, 0, GL_RED, s_reference_type, s_reference_size, store);
12704		is_ok &= CheckErrorAndLog(
12705			m_context, GL_INVALID_OPERATION, "glGetTextureImage",
12706			"format is not one of the integer formats in table 8.3 and the internal format is integer.");
12707
12708		/* Check that INVALID_OPERATION error is generated if a pixel pack buffer
12709		 object is bound and packing the texture image into the buffer’s memory
12710		 would exceed the size of the buffer. */
12711		gl.bindBuffer(GL_PIXEL_PACK_BUFFER, buffer);
12712		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
12713
12714		gl.getTextureImage(texture_2D, 0, s_reference_format, s_reference_type, s_reference_size,
12715						   (glw::GLuint*)NULL + 1);
12716		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage",
12717								  "a pixel pack buffer object is bound and packing the texture image into the buffer’s "
12718								  "memory would exceed the size of the buffer.");
12719
12720		gl.bindBuffer(GL_PIXEL_PACK_BUFFER, 0);
12721		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
12722
12723		/* Check that INVALID_OPERATION error is generated if a pixel pack buffer
12724		 object is bound and pixels is not evenly divisible by the number of
12725		 basic machine units needed to store in memory the GL data type
12726		 corresponding to type (see table 8.2). */
12727		gl.bindBuffer(GL_PIXEL_PACK_BUFFER, buffer);
12728		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
12729
12730		gl.getTextureImage(texture_2D, 0, s_reference_format, s_reference_type, s_reference_size,
12731						   (glw::GLubyte*)NULL + 1);
12732		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage",
12733								  "a pixel pack buffer object is bound and pixels is not evenly divisible by the "
12734								  "number of basic machine units needed to store in memory the GL data type "
12735								  "corresponding to type (see table 8.2).");
12736
12737		gl.bindBuffer(GL_PIXEL_PACK_BUFFER, 0);
12738		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
12739
12740		/* Check that INVALID_OPERATION error is generated by GetTextureImage if
12741		 the buffer size required to store the requested data is greater than
12742		 bufSize. */
12743		gl.getTextureImage(texture_2D, 0, s_reference_format, s_reference_type,
12744						   s_reference_size - sizeof(s_reference_data[0]), store);
12745		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage",
12746								  "the buffer size required to store the requested data is greater than bufSize.");
12747
12748		/* Check that INVALID_OPERATION is generated by GetCompressedTextureImage
12749		 if texture is not the name of an existing texture object. */
12750		gl.getCompressedTextureImage(texture_invalid, 0, s_reference_size, store);
12751		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetCompressedTextureImage",
12752								  "texture is not the name of an existing texture object.");
12753
12754		/* Check that INVALID_VALUE is generated by GetCompressedTextureImage if
12755		 level is less than zero or greater than the maximum number of LODs
12756		 permitted by the implementation. */
12757		gl.getCompressedTextureImage(texture_2D_compressed, -1, s_reference_size, store);
12758		is_ok &=
12759			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetCompressedTextureImage", "level is less than zero.");
12760
12761		gl.getCompressedTextureImage(texture_2D_compressed, max_level, s_reference_size, store);
12762		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetCompressedTextureImage",
12763								  "level is greater than the maximum number of LODs permitted by the implementation.");
12764
12765		/* Check that INVALID_OPERATION is generated if GetCompressedTextureImage
12766		 is used to retrieve a texture that is in an uncompressed internal
12767		 format. */
12768		gl.getCompressedTextureImage(texture_2D, 0, s_reference_size, store);
12769		is_ok &=
12770			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetCompressedTextureImage",
12771							 "the function is used to retrieve a texture that is in an uncompressed internal format.");
12772
12773		/* Check that INVALID_OPERATION is generated by GetCompressedTextureImage
12774		 if a non-zero buffer object name is bound to the PIXEL_PACK_BUFFER
12775		 target, the buffer storage was not initialized with BufferStorage using
12776		 MAP_PERSISTENT_BIT flag, and the buffer object's data store is currently
12777		 mapped. */
12778		gl.bindBuffer(GL_PIXEL_PACK_BUFFER, buffer);
12779		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
12780
12781		gl.mapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_WRITE);
12782
12783		if (GL_NO_ERROR == gl.getError())
12784		{
12785			gl.getCompressedTextureImage(texture_2D_compressed, 0, s_reference_size, NULL);
12786			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetCompressedTextureImage",
12787									  "a non-zero buffer object name is bound to the PIXEL_PACK_BUFFER target, the "
12788									  "buffer storage was not initialized with BufferStorage using MAP_PERSISTENT_BIT "
12789									  "flag, and the buffer object's data store is currently mapped.");
12790
12791			gl.unmapBuffer(GL_PIXEL_PACK_BUFFER);
12792			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer has failed");
12793		}
12794		else
12795		{
12796			throw 0;
12797		}
12798
12799		gl.bindBuffer(GL_PIXEL_PACK_BUFFER, 0);
12800		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
12801
12802		/* Check that INVALID_OPERATION is generated by GetCompressedTextureImage
12803		 if a non-zero buffer object name is bound to the PIXEL_PACK_BUFFER
12804		 target and the data would be packed to the buffer object such that the
12805		 memory writes required would exceed the data store size. */
12806		gl.bindBuffer(GL_PIXEL_PACK_BUFFER, buffer);
12807		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
12808
12809		gl.getCompressedTextureImage(texture_2D_compressed, 0, s_reference_size, (char*)NULL + s_reference_size - 1);
12810		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetCompressedTextureImage",
12811								  "a non-zero buffer object name is bound to the PIXEL_PACK_BUFFER target and the data "
12812								  "would be packed to the buffer object such that the memory writes required would "
12813								  "exceed the data store size.");
12814
12815		gl.bindBuffer(GL_PIXEL_PACK_BUFFER, 0);
12816		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
12817	}
12818	catch (...)
12819	{
12820		is_ok	= false;
12821		is_error = true;
12822	}
12823
12824	/* Cleanup. */
12825	if (buffer)
12826	{
12827		gl.deleteBuffers(1, &buffer);
12828	}
12829
12830	if (texture_2D)
12831	{
12832		gl.deleteTextures(1, &texture_2D);
12833	}
12834
12835	if (texture_2D_int)
12836	{
12837		gl.deleteTextures(1, &texture_2D_int);
12838	}
12839
12840	if (texture_2D_stencil)
12841	{
12842		gl.deleteTextures(1, &texture_2D_stencil);
12843	}
12844
12845	if (texture_2D_ms)
12846	{
12847		gl.deleteTextures(1, &texture_2D_ms);
12848	}
12849
12850	if (texture_2D_compressed)
12851	{
12852		gl.deleteTextures(1, &texture_2D_compressed);
12853	}
12854
12855	if (texture_cube)
12856	{
12857		gl.deleteTextures(1, &texture_cube);
12858	}
12859
12860	if (texture_rectangle)
12861	{
12862		gl.deleteTextures(1, &texture_rectangle);
12863	}
12864
12865	while (GL_NO_ERROR != gl.getError())
12866		;
12867
12868	/* Result's setup. */
12869	if (is_ok)
12870	{
12871		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
12872	}
12873	else
12874	{
12875		if (is_error)
12876		{
12877			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
12878		}
12879		else
12880		{
12881			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
12882		}
12883	}
12884
12885	return STOP;
12886}
12887
12888/******************************** Level Parameter Query Errors Test Implementation   ********************************/
12889
12890/** @brief Image Query Errors Test constructor.
12891 *
12892 *  @param [in] context     OpenGL context.
12893 */
12894LevelParameterErrorsTest::LevelParameterErrorsTest(deqp::Context& context)
12895	: deqp::TestCase(context, "textures_level_parameter_errors", "Texture Level Parameter Query Errors Test")
12896{
12897	/* Intentionally left blank. */
12898}
12899
12900/** @brief Iterate Level Parameter Query Errors Test cases.
12901 *
12902 *  @return Iteration result.
12903 */
12904tcu::TestNode::IterateResult LevelParameterErrorsTest::iterate()
12905{
12906	/* Shortcut for GL functionality. */
12907	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
12908
12909	/* Get context setup. */
12910	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
12911	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
12912
12913	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
12914	{
12915		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
12916
12917		return STOP;
12918	}
12919
12920	/* Running tests. */
12921	bool is_ok	= true;
12922	bool is_error = false;
12923
12924	/* Objects. */
12925	glw::GLuint texture_2D		= 0;
12926	glw::GLuint texture_invalid = 0;
12927	glw::GLint  max_level		= 0;
12928	glw::GLenum pname_invalid   = 0;
12929
12930	glw::GLfloat storef[4] = {};
12931	glw::GLint   storei[4] = {};
12932
12933	try
12934	{
12935		/* Preparations. */
12936
12937		/* 2D texture */
12938		gl.genTextures(1, &texture_2D);
12939		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
12940
12941		gl.bindTexture(GL_TEXTURE_2D, texture_2D);
12942		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
12943
12944		gl.texStorage2D(GL_TEXTURE_2D, 1, GL_R8, 1, 1);
12945		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");
12946
12947		/* Limits. */
12948		gl.getIntegerv(GL_MAX_TEXTURE_SIZE, &max_level); /* assuming that x > log(x) */
12949		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");
12950
12951		/* invalid texture */
12952		while (gl.isTexture(++texture_invalid))
12953			;
12954
12955		/* invalid pname */
12956		glw::GLenum all_pnames[] = { GL_TEXTURE_WIDTH,
12957									 GL_TEXTURE_HEIGHT,
12958									 GL_TEXTURE_DEPTH,
12959									 GL_TEXTURE_SAMPLES,
12960									 GL_TEXTURE_FIXED_SAMPLE_LOCATIONS,
12961									 GL_TEXTURE_INTERNAL_FORMAT,
12962									 GL_TEXTURE_RED_SIZE,
12963									 GL_TEXTURE_GREEN_SIZE,
12964									 GL_TEXTURE_BLUE_SIZE,
12965									 GL_TEXTURE_ALPHA_SIZE,
12966									 GL_TEXTURE_DEPTH_SIZE,
12967									 GL_TEXTURE_STENCIL_SIZE,
12968									 GL_TEXTURE_SHARED_SIZE,
12969									 GL_TEXTURE_RED_TYPE,
12970									 GL_TEXTURE_GREEN_TYPE,
12971									 GL_TEXTURE_BLUE_TYPE,
12972									 GL_TEXTURE_ALPHA_TYPE,
12973									 GL_TEXTURE_DEPTH_TYPE,
12974									 GL_TEXTURE_COMPRESSED,
12975									 GL_TEXTURE_COMPRESSED_IMAGE_SIZE,
12976									 GL_TEXTURE_BUFFER_DATA_STORE_BINDING,
12977									 GL_TEXTURE_BUFFER_OFFSET,
12978									 GL_TEXTURE_BUFFER_SIZE };
12979
12980		glw::GLuint all_pnames_count = sizeof(all_pnames) / sizeof(all_pnames[0]);
12981
12982		bool is_valid = true;
12983
12984		while (is_valid)
12985		{
12986			is_valid = false;
12987
12988			++pname_invalid;
12989
12990			for (glw::GLuint i = 0; i < all_pnames_count; ++i)
12991			{
12992				if (all_pnames[i] == pname_invalid)
12993				{
12994					is_valid = true;
12995
12996					break;
12997				}
12998			}
12999		}
13000
13001		/* Tests. */
13002
13003		/* Check that INVALID_OPERATION is generated by GetTextureLevelParameterfv
13004		 and GetTextureLevelParameteriv functions if texture is not the name of
13005		 an existing texture object. */
13006		gl.getTextureLevelParameterfv(texture_invalid, 0, GL_TEXTURE_WIDTH, storef);
13007		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureLevelParameterfv",
13008								  "texture is not the name of an existing texture object.");
13009
13010		gl.getTextureLevelParameteriv(texture_invalid, 0, GL_TEXTURE_WIDTH, storei);
13011		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureLevelParameteriv",
13012								  "texture is not the name of an existing texture object.");
13013
13014		/* Check that INVALID_VALUE is generated by GetTextureLevelParameter* if
13015		 level is less than 0. */
13016		gl.getTextureLevelParameterfv(texture_2D, -1, GL_TEXTURE_WIDTH, storef);
13017		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetTextureLevelParameterfv", "level is less than 0.");
13018
13019		gl.getTextureLevelParameteriv(texture_2D, -1, GL_TEXTURE_WIDTH, storei);
13020		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetTextureLevelParameteriv", "level is less than 0.");
13021
13022		/* Check that INVALID_ENUM error is generated by GetTextureLevelParameter*
13023		 if pname is not one of supported constants. */
13024		gl.getTextureLevelParameterfv(texture_2D, 0, pname_invalid, storef);
13025		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glGetTextureLevelParameterfv",
13026								  "pname is not one of supported constants.");
13027
13028		gl.getTextureLevelParameteriv(texture_2D, 0, pname_invalid, storei);
13029		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glGetTextureLevelParameteriv",
13030								  "pname is not one of supported constants.");
13031
13032		/* Check that INVALID_VALUE may be generated if level is greater than
13033		 log2 max, where max is the returned value of MAX_TEXTURE_SIZE. */
13034		gl.getTextureLevelParameterfv(texture_2D, max_level, GL_TEXTURE_WIDTH, storef);
13035		is_ok &=
13036			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetTextureLevelParameterfv",
13037							 "level is greater than log2 max, where max is the returned value of MAX_TEXTURE_SIZE.");
13038
13039		gl.getTextureLevelParameteriv(texture_2D, max_level, GL_TEXTURE_WIDTH, storei);
13040		is_ok &=
13041			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetTextureLevelParameteriv",
13042							 "level is greater than log2 max, where max is the returned value of MAX_TEXTURE_SIZE.");
13043
13044		/* Check that INVALID_OPERATION is generated by GetTextureLevelParameter*
13045		 if TEXTURE_COMPRESSED_IMAGE_SIZE is queried on texture images with an
13046		 uncompressed internal format or on proxy targets. */
13047		gl.getTextureLevelParameterfv(texture_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, storef);
13048		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureLevelParameterfv",
13049								  "TEXTURE_COMPRESSED_IMAGE_SIZE is queried on texture images with an uncompressed "
13050								  "internal format or on proxy targets.");
13051
13052		gl.getTextureLevelParameteriv(texture_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, storei);
13053		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureLevelParameteriv",
13054								  "TEXTURE_COMPRESSED_IMAGE_SIZE is queried on texture images with an uncompressed "
13055								  "internal format or on proxy targets.");
13056	}
13057	catch (...)
13058	{
13059		is_ok	= false;
13060		is_error = true;
13061	}
13062
13063	/* Cleanup. */
13064	if (texture_2D)
13065	{
13066		gl.deleteTextures(1, &texture_2D);
13067	}
13068
13069	while (GL_NO_ERROR != gl.getError())
13070		;
13071
13072	/* Result's setup. */
13073	if (is_ok)
13074	{
13075		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
13076	}
13077	else
13078	{
13079		if (is_error)
13080		{
13081			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
13082		}
13083		else
13084		{
13085			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
13086		}
13087	}
13088
13089	return STOP;
13090}
13091
13092/******************************** Parameter Query Errors Test Implementation   ********************************/
13093
13094/** @brief Parameter Query Errors Test constructor.
13095 *
13096 *  @param [in] context     OpenGL context.
13097 */
13098ParameterErrorsTest::ParameterErrorsTest(deqp::Context& context)
13099	: deqp::TestCase(context, "textures_parameter_errors", "Texture Parameter Query Errors Test")
13100{
13101	/* Intentionally left blank. */
13102}
13103
13104/** @brief Iterate Parameter Query Errors Test cases.
13105 *
13106 *  @return Iteration result.
13107 */
13108tcu::TestNode::IterateResult ParameterErrorsTest::iterate()
13109{
13110	/* Shortcut for GL functionality. */
13111	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
13112
13113	/* Get context setup. */
13114	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
13115	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
13116
13117	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
13118	{
13119		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
13120
13121		return STOP;
13122	}
13123
13124	/* Running tests. */
13125	bool is_ok	= true;
13126	bool is_error = false;
13127
13128	/* Objects. */
13129	glw::GLuint texture_2D		= 0;
13130	glw::GLuint texture_buffer  = 0;
13131	glw::GLuint texture_invalid = 0;
13132	glw::GLenum pname_invalid   = 0;
13133
13134	glw::GLfloat storef[4] = {};
13135	glw::GLint   storei[4] = {};
13136	glw::GLuint  storeu[4] = {};
13137
13138	try
13139	{
13140		/* Preparations. */
13141
13142		/* 2D texture */
13143		gl.createTextures(GL_TEXTURE_2D, 1, &texture_2D);
13144		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
13145
13146		/* Buffer texture */
13147		gl.createTextures(GL_TEXTURE_BUFFER, 1, &texture_buffer);
13148		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
13149
13150		/* invalid texture */
13151		while (gl.isTexture(++texture_invalid))
13152			;
13153
13154		/* invalid pname */
13155		glw::GLenum all_pnames[] = { GL_IMAGE_FORMAT_COMPATIBILITY_TYPE,
13156									 GL_TEXTURE_IMMUTABLE_FORMAT,
13157									 GL_TEXTURE_IMMUTABLE_LEVELS,
13158									 GL_TEXTURE_TARGET,
13159									 GL_TEXTURE_VIEW_MIN_LEVEL,
13160									 GL_TEXTURE_VIEW_NUM_LEVELS,
13161									 GL_TEXTURE_VIEW_MIN_LAYER,
13162									 GL_TEXTURE_VIEW_NUM_LAYERS,
13163									 GL_DEPTH_STENCIL_TEXTURE_MODE,
13164									 GL_DEPTH_COMPONENT,
13165									 GL_STENCIL_INDEX,
13166									 GL_TEXTURE_BASE_LEVEL,
13167									 GL_TEXTURE_BORDER_COLOR,
13168									 GL_TEXTURE_COMPARE_MODE,
13169									 GL_TEXTURE_COMPARE_FUNC,
13170									 GL_TEXTURE_LOD_BIAS,
13171									 GL_TEXTURE_MAG_FILTER,
13172									 GL_TEXTURE_MAX_LEVEL,
13173									 GL_TEXTURE_MAX_LOD,
13174									 GL_TEXTURE_MIN_FILTER,
13175									 GL_TEXTURE_MIN_LOD,
13176									 GL_TEXTURE_SWIZZLE_R,
13177									 GL_TEXTURE_SWIZZLE_G,
13178									 GL_TEXTURE_SWIZZLE_B,
13179									 GL_TEXTURE_SWIZZLE_A,
13180									 GL_TEXTURE_SWIZZLE_RGBA,
13181									 GL_TEXTURE_WRAP_S,
13182									 GL_TEXTURE_WRAP_T,
13183									 GL_TEXTURE_WRAP_R };
13184
13185		glw::GLuint all_pnames_count = sizeof(all_pnames) / sizeof(all_pnames[0]);
13186
13187		bool is_valid = true;
13188
13189		while (is_valid)
13190		{
13191			is_valid = false;
13192
13193			++pname_invalid;
13194
13195			for (glw::GLuint i = 0; i < all_pnames_count; ++i)
13196			{
13197				if (all_pnames[i] == pname_invalid)
13198				{
13199					is_valid = true;
13200
13201					break;
13202				}
13203			}
13204		}
13205
13206		/* Tests. */
13207
13208		/* Check that INVALID_ENUM is generated by glGetTextureParameter* if pname
13209		 is not an accepted value. */
13210		gl.getTextureParameterfv(texture_2D, pname_invalid, storef);
13211		is_ok &=
13212			CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glGetTextureParameterfv", "pname is not an accepted value.");
13213
13214		gl.getTextureParameterIiv(texture_2D, pname_invalid, storei);
13215		is_ok &=
13216			CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glGetTextureParameterIiv", "pname is not an accepted value.");
13217
13218		gl.getTextureParameterIuiv(texture_2D, pname_invalid, storeu);
13219		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glGetTextureParameterIuiv",
13220								  "pname is not an accepted value.");
13221
13222		gl.getTextureParameteriv(texture_2D, pname_invalid, storei);
13223		is_ok &=
13224			CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glGetTextureParameteriv", "pname is not an accepted value.");
13225
13226		/* Check that INVALID_OPERATION is generated by glGetTextureParameter* if
13227		 texture is not the name of an existing texture object. */
13228		gl.getTextureParameterfv(texture_invalid, GL_TEXTURE_TARGET, storef);
13229		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureParameterfv",
13230								  "texture is not the name of an existing texture object.");
13231
13232		gl.getTextureParameterIiv(texture_invalid, GL_TEXTURE_TARGET, storei);
13233		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureParameterIiv",
13234								  "texture is not the name of an existing texture object.");
13235
13236		gl.getTextureParameterIuiv(texture_invalid, GL_TEXTURE_TARGET, storeu);
13237		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureParameterIuiv",
13238								  "texture is not the name of an existing texture object.");
13239
13240		gl.getTextureParameteriv(texture_invalid, GL_TEXTURE_TARGET, storei);
13241		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureParameteriv",
13242								  "texture is not the name of an existing texture object.");
13243
13244		/* Check that INVALID_OPERATION error is generated if the effective target is
13245		 not one of the supported texture targets (eg. TEXTURE_BUFFER). */
13246		gl.getTextureParameterfv(texture_buffer, GL_TEXTURE_TARGET, storef);
13247		is_ok &=
13248			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureParameterfv",
13249							 "the effective target is not one of the supported texture targets (eg. TEXTURE_BUFFER).");
13250
13251		gl.getTextureParameterIiv(texture_buffer, GL_TEXTURE_TARGET, storei);
13252		is_ok &=
13253			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureParameterIiv",
13254							 "the effective target is not one of the supported texture targets (eg. TEXTURE_BUFFER).");
13255
13256		gl.getTextureParameterIuiv(texture_buffer, GL_TEXTURE_TARGET, storeu);
13257		is_ok &=
13258			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureParameterIuiv",
13259							 "the effective target is not one of the supported texture targets (eg. TEXTURE_BUFFER).");
13260
13261		gl.getTextureParameteriv(texture_buffer, GL_TEXTURE_TARGET, storei);
13262		is_ok &=
13263			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureParameteriv",
13264							 "the effective target is not one of the supported texture targets (eg. TEXTURE_BUFFER).");
13265	}
13266	catch (...)
13267	{
13268		is_ok	= false;
13269		is_error = true;
13270	}
13271
13272	/* Cleanup. */
13273	if (texture_2D)
13274	{
13275		gl.deleteTextures(1, &texture_2D);
13276	}
13277
13278	if (texture_buffer)
13279	{
13280		gl.deleteTextures(1, &texture_buffer);
13281	}
13282
13283	while (GL_NO_ERROR != gl.getError())
13284		;
13285
13286	/* Result's setup. */
13287	if (is_ok)
13288	{
13289		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
13290	}
13291	else
13292	{
13293		if (is_error)
13294		{
13295			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
13296		}
13297		else
13298		{
13299			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
13300		}
13301	}
13302
13303	return STOP;
13304}
13305
13306} /* Textures namespace. */
13307} /* DirectStateAccess namespace. */
13308} /* gl4cts namespace. */
13309