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_FATAL("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_FATAL("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_FATAL("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_FATAL("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_FATAL("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_FATAL("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_FATAL("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_FATAL("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_FATAL("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_FATAL("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_FATAL("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_FATAL("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_FATAL("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_FATAL("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_FATAL("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_FATAL("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_FATAL("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_FATAL("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_FATAL("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_FATAL("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_FATAL("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_FATAL("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_FATAL("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_FATAL("invalid texture dimension");
2971			return DE_NULL;
2972		}
2973	}
2974
2975	DE_FATAL("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_FATAL("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_FATAL("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_FATAL("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_FATAL("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_FATAL("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_FATAL("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_FATAL("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_FATAL("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_FATAL("invalid texture dimension");
3112			return DE_NULL;
3113		}
3114	}
3115
3116	DE_FATAL("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_FATAL("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_FATAL("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_FATAL("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_FATAL("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_FATAL("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_FATAL("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_FATAL("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_FATAL("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/* Compressed m_reference data for unsupported compression formats */
4204
4205static const unsigned char data_0x8dbb_2D_8[] = {
4206	34, 237, 94, 207,
4207	252, 29, 75, 25
4208};
4209
4210static const unsigned char data_0x8dbb_3D_32[] = {
4211	34, 237, 94, 207,
4212	252, 29, 75, 25,
4213	34, 237, 44, 173,
4214	101, 230, 139, 254,
4215	34, 237, 176, 88,
4216	174, 127, 248, 206,
4217	34, 237, 127, 209,
4218	211, 203, 100, 150
4219};
4220
4221static const unsigned char data_0x8dbc_2D_8[] = {
4222	127, 0, 233, 64,
4223	0, 42, 71, 231
4224};
4225
4226static const unsigned char data_0x8dbc_3D_32[] = {
4227	127, 0, 233, 64,
4228	0, 42, 71, 231,
4229	127, 0, 20, 227,
4230	162, 33, 246, 1,
4231	127, 0, 143, 57,
4232	86, 0, 136, 53,
4233	127, 0, 192, 62,
4234	48, 69, 29, 138
4235};
4236
4237static const unsigned char data_0x8dbd_2D_16[] = {
4238	34, 237, 94, 207,
4239	252, 29, 75, 25,
4240	28, 242, 94, 111,
4241	44, 101, 35, 145
4242};
4243
4244static const unsigned char data_0x8dbd_3D_64[] = {
4245	34, 237, 94, 207,
4246	252, 29, 75, 25,
4247	28, 242, 94, 111,
4248	44, 101, 35, 145,
4249	34, 237, 44, 173,
4250	101, 230, 139, 254,
4251	28, 242, 170, 45,
4252	98, 236, 202, 228,
4253	34, 237, 176, 88,
4254	174, 127, 248, 206,
4255	28, 242, 164, 148,
4256	178, 25, 252, 206,
4257	34, 237, 127, 209,
4258	211, 203, 100, 150,
4259	28, 242, 79, 216,
4260	149, 3, 101, 87
4261};
4262
4263static const unsigned char data_0x8dbe_2D_16[] = {
4264	127, 0, 233, 64,
4265	0, 42, 71, 231,
4266	127, 0, 233, 144,
4267	23, 163, 100, 115
4268};
4269
4270static const unsigned char data_0x8dbe_3D_64[] = {
4271	127, 0, 233, 64,
4272	0, 42, 71, 231,
4273	127, 0, 233, 144,
4274	23, 163, 100, 115,
4275	127, 0, 20, 227,
4276	162, 33, 246, 1,
4277	127, 0, 94, 98,
4278	190, 84, 55, 1,
4279	127, 0, 143, 57,
4280	86, 0, 136, 53,
4281	127, 0, 163, 45,
4282	113, 232, 131, 53,
4283	127, 0, 192, 62,
4284	48, 69, 29, 138,
4285	127, 0, 128, 182,
4286	138, 61, 157, 204
4287};
4288
4289static const unsigned char data_0x8e8c_2D_16[] = {
4290	144, 43, 143, 15,
4291	254, 15, 152, 153,
4292	153, 153, 89, 143,
4293	140, 166, 183, 113
4294};
4295
4296static const unsigned char data_0x8e8c_3D_64[] = {
4297	144, 43, 143, 15,
4298	254, 15, 152, 153,
4299	153, 153, 89, 143,
4300	140, 166, 183, 113,
4301	144, 43, 143, 15,
4302	254, 15, 152, 153,
4303	153, 153, 55, 48,
4304	102, 244, 186, 241,
4305	144, 43, 143, 15,
4306	254, 15, 152, 153,
4307	153, 153, 231, 54,
4308	211, 92, 240, 14,
4309	144, 121, 253, 241,
4310	193, 15, 152, 153,
4311	153, 153, 25, 41,
4312	102, 244, 248, 135
4313};
4314
4315static const unsigned char data_0x8e8d_2D_16[] = {
4316	144, 43, 143, 15,
4317	254, 15, 152, 153,
4318	153, 153, 89, 143,
4319	140, 166, 183, 113
4320};
4321
4322static const unsigned char data_0x8e8d_3D_64[] = {
4323	144, 43, 143, 15,
4324	254, 15, 152, 153,
4325	153, 153, 89, 143,
4326	140, 166, 183, 113,
4327	144, 43, 143, 15,
4328	254, 15, 152, 153,
4329	153, 153, 55, 48,
4330	102, 244, 186, 241,
4331	144, 43, 143, 15,
4332	254, 15, 152, 153,
4333	153, 153, 231, 54,
4334	211, 92, 240, 14,
4335	144, 121, 253, 241,
4336	193, 15, 152, 153,
4337	153, 153, 25, 41,
4338	102, 244, 248, 135
4339};
4340
4341static const unsigned char data_0x8e8e_2D_16[] = {
4342	67, 155, 82, 120,
4343	142, 7, 31, 124,
4344	224, 255, 165, 221,
4345	239, 223, 122, 223
4346};
4347
4348static const unsigned char data_0x8e8e_3D_64[] = {
4349	67, 155, 82, 120,
4350	142, 7, 31, 124,
4351	224, 255, 165, 221,
4352	239, 223, 122, 223,
4353	35, 30, 124, 240,
4354	209, 166, 20, 158,
4355	11, 250, 24, 21,
4356	0, 2, 34, 2,
4357	35, 30, 124, 240,
4358	209, 166, 20, 158,
4359	5, 88, 2, 1,
4360	34, 165, 0, 241,
4361	35, 30, 124, 240,
4362	209, 166, 20, 158,
4363	33, 34, 32, 0,
4364	81, 129, 175, 80
4365};
4366
4367static const unsigned char data_0x8e8f_2D_16[] = {
4368	131, 54, 165, 148,
4369	26, 47, 62, 248,
4370	176, 254, 149, 203,
4371	222, 206, 187, 173
4372};
4373
4374static const unsigned char data_0x8e8f_3D_64[] = {
4375	131, 54, 165, 148,
4376	26, 47, 62, 248,
4377	176, 254, 149, 203,
4378	222, 206, 187, 173,
4379	99, 188, 248, 224,
4380	163, 77, 41, 165,
4381	24, 250, 36, 70,
4382	18, 20, 53, 3,
4383	99, 188, 248, 224,
4384	163, 77, 41, 165,
4385	42, 68, 19, 18,
4386	67, 166, 16, 244,
4387	99, 188, 248, 224,
4388	163, 77, 41, 165,
4389	48, 83, 65, 33,
4390	100, 66, 175, 65
4391};
4392
4393static const unsigned char data_GL_COMPRESSED_R11_EAC_2D_8[] = {
4394	146, 253, 99, 81,
4395	202, 222, 63, 243
4396};
4397
4398static const unsigned char data_GL_COMPRESSED_R11_EAC_3D_32[] = {
4399	146, 253, 99, 81,
4400	202, 222, 63, 243,
4401	146, 253, 169, 188,
4402	102, 31, 246, 55,
4403	146, 253, 123, 247,
4404	62, 71, 139, 131,
4405	146, 253, 248, 63,
4406	248, 208, 230, 213
4407};
4408
4409static const unsigned char data_GL_COMPRESSED_RG11_EAC_2D_16[] = {
4410	146, 253, 99, 81,
4411	202, 222, 63, 243,
4412	140, 254, 110, 0,
4413	160, 130, 207, 180
4414};
4415
4416static const unsigned char data_GL_COMPRESSED_RG11_EAC_3D_64[] = {
4417	146, 253, 99, 81,
4418	202, 222, 63, 243,
4419	140, 254, 110, 0,
4420	160, 130, 207, 180,
4421	146, 253, 169, 188,
4422	102, 31, 246, 55,
4423	140, 254, 2, 73,
4424	46, 104, 102, 39,
4425	146, 253, 123, 247,
4426	62, 71, 139, 131,
4427	140, 254, 155, 121,
4428	68, 17, 1, 27,
4429	146, 253, 248, 63,
4430	248, 208, 230, 213,
4431	140, 254, 240, 60,
4432	19, 214, 73, 0
4433};
4434
4435static const unsigned char data_GL_COMPRESSED_RGB8_ETC2_2D_8[] = {
4436	168, 122, 150, 252,
4437	234, 35, 0, 0
4438};
4439
4440static const unsigned char data_GL_COMPRESSED_RGB8_ETC2_3D_32[] = {
4441	168, 122, 150, 252,
4442	234, 35, 0, 0,
4443	168, 122, 150, 253,
4444	31, 140, 0, 0,
4445	138, 167, 105, 252,
4446	196, 87, 0, 0,
4447	138, 167, 105, 253,
4448	49, 248, 0, 0
4449};
4450
4451static const unsigned char data_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_2D_8[] = {
4452	83, 83, 75, 252,
4453	240, 240, 15, 4
4454};
4455
4456static const unsigned char data_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_3D_32[] = {
4457	83, 83, 75, 252,
4458	240, 240, 15, 4,
4459	107, 99, 99, 253,
4460	240, 240, 14, 15,
4461	135, 135, 135, 252,
4462	240, 240, 15, 15,
4463	108, 108, 108, 253,
4464	240, 248, 11, 11
4465};
4466
4467static const unsigned char data_GL_COMPRESSED_RGBA8_ETC2_EAC_2D_16[] = {
4468	127, 245, 255, 244,
4469	146, 255, 244, 146,
4470	168, 122, 150, 252,
4471	234, 35, 0, 0
4472};
4473
4474static const unsigned char data_GL_COMPRESSED_RGBA8_ETC2_EAC_3D_64[] = {
4475	127, 245, 255, 244,
4476	146, 255, 244, 146,
4477	168, 122, 150, 252,
4478	234, 35, 0, 0,
4479	127, 245, 255, 244,
4480	146, 255, 244, 146,
4481	168, 122, 150, 253,
4482	31, 140, 0, 0,
4483	127, 245, 255, 244,
4484	146, 255, 244, 146,
4485	138, 167, 105, 252,
4486	196, 87, 0, 0,
4487	127, 245, 255, 244,
4488	146, 255, 244, 146,
4489	138, 167, 105, 253,
4490	49, 248, 0, 0
4491};
4492
4493static const unsigned char data_GL_COMPRESSED_SIGNED_R11_EAC_2D_8[] = {
4494	73, 221, 99, 81,
4495	201, 222, 63, 241
4496};
4497
4498static const unsigned char data_GL_COMPRESSED_SIGNED_R11_EAC_3D_32[] = {
4499	73, 221, 99, 81,
4500	201, 222, 63, 241,
4501	73, 221, 165, 156,
4502	102, 31, 246, 55,
4503	73, 221, 59, 247,
4504	62, 39, 139, 131,
4505	73, 221, 248, 63,
4506	248, 208, 226, 205
4507};
4508
4509static const unsigned char data_GL_COMPRESSED_SIGNED_RG11_EAC_2D_16[] = {
4510	73, 221, 99, 81,
4511	201, 222, 63, 241,
4512	66, 191, 110, 0,
4513	96, 131, 77, 180
4514};
4515
4516static const unsigned char data_GL_COMPRESSED_SIGNED_RG11_EAC_3D_64[] = {
4517	73, 221, 99, 81,
4518	201, 222, 63, 241,
4519	66, 191, 110, 0,
4520	96, 131, 77, 180,
4521	73, 221, 165, 156,
4522	102, 31, 246, 55,
4523	66, 191, 2, 73,
4524	54, 100, 102, 38,
4525	73, 221, 59, 247,
4526	62, 39, 139, 131,
4527	66, 191, 155, 105,
4528	132, 16, 129, 27,
4529	73, 221, 248, 63,
4530	248, 208, 226, 205,
4531	66, 191, 208, 60,
4532	11, 218, 73, 0
4533};
4534
4535static const unsigned char data_GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_2D_16[] = {
4536	127, 245, 255, 244,
4537	146, 255, 244, 146,
4538	150, 122, 168, 252,
4539	234, 35, 0, 0
4540};
4541
4542static const unsigned char data_GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_3D_64[] = {
4543	127, 245, 255, 244,
4544	146, 255, 244, 146,
4545	150, 122, 168, 252,
4546	234, 35, 0, 0,
4547	127, 245, 255, 244,
4548	146, 255, 244, 146,
4549	150, 122, 168, 253,
4550	31, 140, 0, 0,
4551	127, 245, 255, 244,
4552	146, 255, 244, 146,
4553	105, 167, 138, 252,
4554	196, 87, 0, 0,
4555	127, 245, 255, 244,
4556	146, 255, 244, 146,
4557	105, 167, 138, 253,
4558	49, 248, 0, 0
4559};
4560
4561static const unsigned char data_GL_COMPRESSED_SRGB8_ETC2_2D_8[] = {
4562	168, 122, 150, 252,
4563	234, 35, 0, 0
4564};
4565
4566static const unsigned char data_GL_COMPRESSED_SRGB8_ETC2_3D_32[] = {
4567	168, 122, 150, 252,
4568	234, 35, 0, 0,
4569	168, 122, 150, 253,
4570	31, 140, 0, 0,
4571	138, 167, 105, 252,
4572	196, 87, 0, 0,
4573	138, 167, 105, 253,
4574	49, 248, 0, 0
4575};
4576
4577static const unsigned char data_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_2D_8[] = {
4578	75, 83, 83, 252,
4579	240, 240, 15, 4
4580};
4581
4582static const unsigned char data_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_3D_32[] = {
4583	75, 83, 83, 252,
4584	240, 240, 15, 4,
4585	99, 99, 107, 253,
4586	240, 240, 14, 15,
4587	135, 135, 135, 252,
4588	240, 240, 15, 15,
4589	108, 108, 108, 253,
4590	240, 248, 11, 11
4591};
4592
4593/** @brief Compressed SubImage Test constructor.
4594 *
4595 *  @param [in] context     OpenGL context.
4596 */
4597CompressedSubImageTest::CompressedSubImageTest(deqp::Context& context)
4598	: deqp::TestCase(context, "textures_compressed_subimage", "Texture Compressed SubImage Test")
4599	, m_to(0)
4600	, m_to_aux(0)
4601	, m_compressed_texture_data(DE_NULL)
4602	, m_reference(DE_NULL)
4603	, m_result(DE_NULL)
4604	, m_reference_size(0)
4605	, m_reference_internalformat(0)
4606{
4607	/* Intentionally left blank. */
4608}
4609
4610/** @brief Create texture.
4611 *
4612 *  @param [in] target      Texture target.
4613 */
4614void CompressedSubImageTest::CreateTextures(glw::GLenum target)
4615{
4616	/* Shortcut for GL functionality. */
4617	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4618
4619	/* Auxiliary texture (for content creation). */
4620	gl.genTextures(1, &m_to_aux);
4621	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
4622
4623	gl.bindTexture(target, m_to_aux);
4624	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
4625
4626	/* Test texture (for data upload). */
4627	gl.genTextures(1, &m_to);
4628	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
4629
4630	gl.bindTexture(target, m_to);
4631	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
4632}
4633
4634/** @brief Texture target selector.
4635 *
4636 *  @tparam D      Texture dimenisons.
4637 *
4638 *  @return Texture target.
4639 */
4640template <>
4641glw::GLenum CompressedSubImageTest::TextureTarget<1>()
4642{
4643	return GL_TEXTURE_1D;
4644}
4645
4646template <>
4647glw::GLenum CompressedSubImageTest::TextureTarget<2>()
4648{
4649	return GL_TEXTURE_2D;
4650}
4651
4652template <>
4653glw::GLenum CompressedSubImageTest::TextureTarget<3>()
4654{
4655	return GL_TEXTURE_2D_ARRAY;
4656}
4657
4658/** @brief Prepare texture data for the auxiliary texture.
4659 *
4660 *  @tparam D      Texture dimenisons.
4661 *
4662 *  @note parameters as passed to texImage*
4663 *
4664 *  @return False if the internal format is unsupported for online compression, True otherwise
4665 */
4666template <>
4667bool CompressedSubImageTest::TextureImage<1>(glw::GLint internalformat)
4668{
4669	/* Shortcut for GL functionality. */
4670	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4671
4672	gl.texImage1D(TextureTarget<1>(), 0, internalformat, s_texture_width, 0, GL_RGBA, GL_UNSIGNED_BYTE, s_texture_data);
4673
4674	/* Online compression may be unsupported for some formats */
4675	GLenum error = gl.getError();
4676	if (error == GL_INVALID_OPERATION)
4677		return false;
4678
4679	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");
4680
4681	return true;
4682}
4683
4684/** @brief Prepare texture data for the auxiliary texture.
4685 *
4686 *  @tparam D      Texture dimenisons.
4687 *
4688 *  @note parameters as passed to texImage*
4689 *
4690 *  @return False if the internal format is unsupported for online compression, True otherwise
4691 */
4692template <>
4693bool CompressedSubImageTest::TextureImage<2>(glw::GLint internalformat)
4694{
4695	/* Shortcut for GL functionality. */
4696	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4697
4698	gl.texImage2D(TextureTarget<2>(), 0, internalformat, s_texture_width, s_texture_height, 0, GL_RGBA,
4699				  GL_UNSIGNED_BYTE, s_texture_data);
4700
4701	/* Online compression may be unsupported for some formats */
4702	GLenum error = gl.getError();
4703	if (error == GL_INVALID_OPERATION)
4704		return false;
4705
4706	GLU_EXPECT_NO_ERROR(error, "glTexImage2D has failed");
4707
4708	return true;
4709}
4710
4711/** @brief Prepare texture data for the auxiliary texture.
4712 *
4713 *  @tparam D      Texture dimenisons.
4714 *
4715 *  @note parameters as passed to texImage*
4716 *
4717 *  @return False if the internal format is unsupported for online compression, True otherwise
4718 */
4719template <>
4720bool CompressedSubImageTest::TextureImage<3>(glw::GLint internalformat)
4721{
4722	/* Shortcut for GL functionality. */
4723	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4724
4725	gl.texImage3D(TextureTarget<3>(), 0, internalformat, s_texture_width, s_texture_height, s_texture_depth, 0, GL_RGBA,
4726				  GL_UNSIGNED_BYTE, s_texture_data);
4727
4728	/* Online compression may be unsupported for some formats */
4729	GLenum error = gl.getError();
4730	if (error == GL_INVALID_OPERATION)
4731		return false;
4732
4733	GLU_EXPECT_NO_ERROR(error, "glTexImage3D has failed");
4734
4735	return true;
4736}
4737
4738/** @brief Prepare texture data for the auxiliary texture.
4739 *
4740 *  @tparam D      Texture dimensions.
4741 *
4742 *  @note parameters as passed to compressedTexImage*
4743 */
4744template <>
4745void CompressedSubImageTest::CompressedTexImage<1>(glw::GLint internalformat)
4746{
4747	/* Shortcut for GL functionality. */
4748	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4749
4750	gl.compressedTexImage1D(TextureTarget<1>(), 0, internalformat, s_texture_width, 0, m_reference_size,
4751							m_compressed_texture_data);
4752	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage1D has failed");
4753}
4754
4755/** @brief Prepare texture data for the auxiliary texture.
4756 *
4757 *  @tparam D      Texture dimensions.
4758 *
4759 *  @note parameters as passed to compressedTexImage*
4760 */
4761template <>
4762void CompressedSubImageTest::CompressedTexImage<2>(glw::GLint internalformat)
4763{
4764	/* Shortcut for GL functionality. */
4765	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4766
4767	gl.compressedTexImage2D(TextureTarget<2>(), 0, internalformat, s_texture_width, s_texture_height, 0,
4768							m_reference_size, m_compressed_texture_data);
4769	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage2D has failed");
4770}
4771
4772/** @brief Prepare texture data for the auxiliary texture.
4773 *
4774 *  @tparam D      Texture dimensions.
4775 *
4776 *  @note parameters as passed to compressedTexImage*
4777 */
4778template <>
4779void CompressedSubImageTest::CompressedTexImage<3>(glw::GLint internalformat)
4780{
4781	/* Shortcut for GL functionality. */
4782	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4783
4784	gl.compressedTexImage3D(TextureTarget<3>(), 0, internalformat, s_texture_width, s_texture_height, s_texture_depth,
4785							0, m_reference_size, m_compressed_texture_data);
4786	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage3D has failed");
4787}
4788
4789/** @brief Prepare texture data for the compressed texture.
4790 *
4791 *  @tparam D      Texture dimenisons.
4792 *
4793 *  @return True if tested function succeeded, false otherwise.
4794 */
4795template <>
4796bool CompressedSubImageTest::CompressedTextureSubImage<1>(glw::GLint internalformat)
4797{
4798	/* Shortcut for GL functionality. */
4799	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4800
4801	/* Load texture image with tested function. */
4802	if (m_reference_size)
4803	{
4804		for (glw::GLuint block = 0; block < s_block_count; ++block)
4805		{
4806			gl.compressedTextureSubImage1D(m_to, 0, s_texture_width * block, s_texture_width, internalformat,
4807										   m_reference_size, m_compressed_texture_data);
4808		}
4809	}
4810	else
4811	{
4812		/* For 1D version there is no specific compressed texture internal format spcified in OpenGL 4.5 core profile documentation.
4813		 Only implementation depended specific internalformats may provide this functionality. As a result there may be no reference data to be substituted.
4814		 Due to this reason there is no use of CompressedTextureSubImage1D and particulary it cannot be tested. */
4815		return true;
4816	}
4817
4818	/* Check errors. */
4819	glw::GLenum error;
4820
4821	if (GL_NO_ERROR != (error = gl.getError()))
4822	{
4823		m_context.getTestContext().getLog()
4824			<< tcu::TestLog::Message << "glCompressedTextureSubImage1D unexpectedly generated error "
4825			<< glu::getErrorStr(error) << " during the test with internal format "
4826			<< glu::getTextureFormatStr(internalformat) << ". Test fails." << tcu::TestLog::EndMessage;
4827
4828		return false;
4829	}
4830
4831	return true;
4832}
4833
4834/** @brief Prepare texture data for the compressed texture.
4835 *
4836 *  @tparam D      Texture dimenisons.
4837 *
4838 *  @param [in] internalformat      Texture internal format.
4839 *
4840 *  @return True if tested function succeeded, false otherwise.
4841 */
4842template <>
4843bool CompressedSubImageTest::CompressedTextureSubImage<2>(glw::GLint internalformat)
4844{
4845	/* Shortcut for GL functionality. */
4846	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4847
4848	for (glw::GLuint y = 0; y < s_block_2d_size_y; ++y)
4849	{
4850		for (glw::GLuint x = 0; x < s_block_2d_size_x; ++x)
4851		{
4852			/* Load texture image with tested function. */
4853			gl.compressedTextureSubImage2D(m_to, 0, s_texture_width * x, s_texture_height * y, s_texture_width,
4854										   s_texture_height, internalformat, m_reference_size,
4855										   m_compressed_texture_data);
4856		}
4857	}
4858	/* Check errors. */
4859	glw::GLenum error;
4860
4861	if (GL_NO_ERROR != (error = gl.getError()))
4862	{
4863		m_context.getTestContext().getLog()
4864			<< tcu::TestLog::Message << "glCompressedTextureSubImage2D unexpectedly generated error "
4865			<< glu::getErrorStr(error) << " during the test with internal format "
4866			<< glu::getTextureFormatStr(internalformat) << ". Test fails." << tcu::TestLog::EndMessage;
4867
4868		return false;
4869	}
4870
4871	return true;
4872}
4873
4874/** @brief Prepare texture data for the compressed texture.
4875 *
4876 *  @tparam D      Texture dimenisons.
4877 *
4878 *  @param [in] internalformat      Texture internal format.
4879 *
4880 *  @return True if tested function succeeded, false otherwise.
4881 */
4882template <>
4883bool CompressedSubImageTest::CompressedTextureSubImage<3>(glw::GLint internalformat)
4884{
4885	/* Shortcut for GL functionality. */
4886	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4887
4888	for (glw::GLuint z = 0; z < s_block_3d_size; ++z)
4889	{
4890		for (glw::GLuint y = 0; y < s_block_3d_size; ++y)
4891		{
4892			for (glw::GLuint x = 0; x < s_block_3d_size; ++x)
4893			{
4894				/* Load texture image with tested function. */
4895				gl.compressedTextureSubImage3D(m_to, 0, s_texture_width * x, s_texture_height * y, s_texture_depth * z,
4896											   s_texture_width, s_texture_height, s_texture_depth, internalformat,
4897											   m_reference_size, m_compressed_texture_data);
4898			}
4899		}
4900	}
4901
4902	/* Check errors. */
4903	glw::GLenum error;
4904
4905	if (GL_NO_ERROR != (error = gl.getError()))
4906	{
4907		m_context.getTestContext().getLog()
4908			<< tcu::TestLog::Message << "glCompressedTextureSubImage2D unexpectedly generated error "
4909			<< glu::getErrorStr(error) << " during the test with internal format "
4910			<< glu::getTextureFormatStr(internalformat) << ". Test fails." << tcu::TestLog::EndMessage;
4911
4912		return false;
4913	}
4914	return true;
4915}
4916
4917struct CompressedData
4918{
4919	glw::GLenum iformat;
4920	const unsigned char *data;
4921	int data_size;
4922	int dimensions;
4923};
4924
4925static CompressedData compressed_images[] =
4926{
4927	/* 2D images */
4928
4929	{GL_COMPRESSED_RED_RGTC1, data_0x8dbb_2D_8, sizeof data_0x8dbb_2D_8, 2},
4930	{GL_COMPRESSED_SIGNED_RED_RGTC1, data_0x8dbc_2D_8, sizeof data_0x8dbc_2D_8, 2},
4931	{GL_COMPRESSED_RG_RGTC2, data_0x8dbd_2D_16, sizeof data_0x8dbd_2D_16, 2},
4932	{GL_COMPRESSED_SIGNED_RG_RGTC2, data_0x8dbe_2D_16, sizeof data_0x8dbe_2D_16, 2},
4933	{GL_COMPRESSED_RGBA_BPTC_UNORM, data_0x8e8c_2D_16, sizeof data_0x8e8c_2D_16, 2},
4934	{GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, data_0x8e8d_2D_16, sizeof data_0x8e8d_2D_16, 2},
4935	{GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, data_0x8e8e_2D_16, sizeof data_0x8e8e_2D_16, 2},
4936	{GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, data_0x8e8f_2D_16, sizeof data_0x8e8f_2D_16, 2},
4937	{GL_COMPRESSED_RGB8_ETC2, data_GL_COMPRESSED_RGB8_ETC2_2D_8,
4938			sizeof data_GL_COMPRESSED_RGB8_ETC2_2D_8, 2},
4939	{GL_COMPRESSED_SRGB8_ETC2, data_GL_COMPRESSED_SRGB8_ETC2_2D_8,
4940			sizeof data_GL_COMPRESSED_SRGB8_ETC2_2D_8, 2},
4941	{GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
4942			data_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_2D_8,
4943			sizeof data_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_2D_8, 2},
4944	{GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
4945			data_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_2D_8,
4946			sizeof data_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_2D_8, 2},
4947	{GL_COMPRESSED_RGBA8_ETC2_EAC, data_GL_COMPRESSED_RGBA8_ETC2_EAC_2D_16,
4948			sizeof data_GL_COMPRESSED_RGBA8_ETC2_EAC_2D_16, 2},
4949	{GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, data_GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_2D_16,
4950			sizeof data_GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_2D_16, 2},
4951	{GL_COMPRESSED_R11_EAC, data_GL_COMPRESSED_R11_EAC_2D_8,
4952			sizeof data_GL_COMPRESSED_R11_EAC_2D_8, 2},
4953	{GL_COMPRESSED_SIGNED_R11_EAC, data_GL_COMPRESSED_SIGNED_R11_EAC_2D_8,
4954			sizeof data_GL_COMPRESSED_SIGNED_R11_EAC_2D_8, 2},
4955	{GL_COMPRESSED_RG11_EAC, data_GL_COMPRESSED_RG11_EAC_2D_16,
4956			sizeof data_GL_COMPRESSED_SIGNED_RG11_EAC_2D_16, 2},
4957	{GL_COMPRESSED_SIGNED_RG11_EAC, data_GL_COMPRESSED_SIGNED_RG11_EAC_2D_16,
4958			sizeof data_GL_COMPRESSED_SIGNED_RG11_EAC_2D_16, 2},
4959
4960	/* 3D images */
4961
4962	{0x8dbb, data_0x8dbb_3D_32, sizeof data_0x8dbb_3D_32, 3},
4963	{0x8dbc, data_0x8dbc_3D_32, sizeof data_0x8dbc_3D_32, 3},
4964	{0x8dbd, data_0x8dbd_3D_64, sizeof data_0x8dbd_3D_64, 3},
4965	{0x8dbe, data_0x8dbe_3D_64, sizeof data_0x8dbe_3D_64, 3},
4966	{0x8e8c, data_0x8e8c_3D_64, sizeof data_0x8e8c_3D_64, 3},
4967	{0x8e8d, data_0x8e8d_3D_64, sizeof data_0x8e8d_3D_64, 3},
4968	{0x8e8e, data_0x8e8e_3D_64, sizeof data_0x8e8e_3D_64, 3},
4969	{0x8e8f, data_0x8e8f_3D_64, sizeof data_0x8e8f_3D_64, 3},
4970	{GL_COMPRESSED_RGB8_ETC2, data_GL_COMPRESSED_RGB8_ETC2_3D_32,
4971			sizeof data_GL_COMPRESSED_RGB8_ETC2_3D_32, 3},
4972	{GL_COMPRESSED_SRGB8_ETC2, data_GL_COMPRESSED_SRGB8_ETC2_3D_32,
4973			sizeof data_GL_COMPRESSED_SRGB8_ETC2_3D_32, 3},
4974	{GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
4975			data_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_3D_32,
4976			sizeof data_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_3D_32, 3},
4977	{GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
4978			data_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_3D_32,
4979			sizeof data_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_3D_32, 3},
4980	{GL_COMPRESSED_R11_EAC, data_GL_COMPRESSED_R11_EAC_3D_32,
4981			sizeof data_GL_COMPRESSED_R11_EAC_3D_32, 3},
4982	{GL_COMPRESSED_SIGNED_R11_EAC, data_GL_COMPRESSED_SIGNED_R11_EAC_3D_32,
4983			sizeof data_GL_COMPRESSED_SIGNED_R11_EAC_3D_32, 3},
4984
4985	{GL_COMPRESSED_RGBA8_ETC2_EAC, data_GL_COMPRESSED_RGBA8_ETC2_EAC_3D_64,
4986			sizeof data_GL_COMPRESSED_RGBA8_ETC2_EAC_3D_64, 3},
4987	{GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, data_GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_3D_64,
4988			sizeof data_GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_3D_64, 3},
4989	{GL_COMPRESSED_RG11_EAC, data_GL_COMPRESSED_RG11_EAC_3D_64,
4990			sizeof data_GL_COMPRESSED_RG11_EAC_3D_64, 3},
4991	{GL_COMPRESSED_SIGNED_RG11_EAC, data_GL_COMPRESSED_SIGNED_RG11_EAC_3D_64,
4992			sizeof data_GL_COMPRESSED_SIGNED_RG11_EAC_3D_64, 3}
4993};
4994
4995/** @brief Prepare the reference data.
4996 *
4997 *  @tparam D      Texture dimenisons.
4998 *
4999 *  @return False if the internal format is unsupported for online compression, True otherwise
5000 */
5001template <glw::GLuint D>
5002bool CompressedSubImageTest::PrepareReferenceData(glw::GLenum internalformat)
5003{
5004	/* Shortcut for GL functionality. */
5005	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5006
5007	/* Using OpenGL to compress raw data. */
5008	gl.bindTexture(TextureTarget<D>(), m_to_aux);
5009	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
5010
5011	glw::GLint is_compressed_texture = 0;
5012	glw::GLint compressed_texture_size = 0;
5013
5014	/* Quick checks. */
5015	if ((DE_NULL != m_reference) || (DE_NULL != m_compressed_texture_data))
5016	{
5017		throw 0;
5018	}
5019
5020	/* "if" path is taken when there is no support for online compression for the format
5021	 * and we upload compressed data directly */
5022	if (!TextureImage<D>(internalformat))
5023	{
5024		for (unsigned int i=0; i<sizeof compressed_images / sizeof *compressed_images; i++)
5025		{
5026			if (internalformat == compressed_images[i].iformat
5027					&& D == compressed_images[i].dimensions)
5028			{
5029				is_compressed_texture = 1;
5030				compressed_texture_size = compressed_images[i].data_size;
5031
5032				m_reference_size = compressed_texture_size;
5033				m_reference_internalformat = compressed_images[i].iformat;
5034
5035				m_reference = new glw::GLubyte[compressed_texture_size];
5036				m_compressed_texture_data = new glw::GLubyte[compressed_texture_size];
5037
5038				memcpy(m_reference, compressed_images[i].data, compressed_texture_size);
5039				memcpy(m_compressed_texture_data, compressed_images[i].data, compressed_texture_size);
5040			}
5041		}
5042
5043		if (!is_compressed_texture)
5044			return false;
5045
5046		PrepareCompressedStorage<D>(m_reference_internalformat);
5047	}
5048	else
5049	{
5050		/* Check that really compressed texture. */
5051		gl.getTexLevelParameteriv(TextureTarget<D>(), 0, GL_TEXTURE_COMPRESSED, &is_compressed_texture);
5052
5053		if (is_compressed_texture)
5054		{
5055			/* Query texture size. */
5056			gl.getTexLevelParameteriv(TextureTarget<D>(), 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &compressed_texture_size);
5057
5058			/* If compressed then download. */
5059			if (compressed_texture_size)
5060			{
5061				/* Prepare storage. */
5062				m_compressed_texture_data = new glw::GLubyte[compressed_texture_size];
5063
5064				if (DE_NULL != m_compressed_texture_data)
5065				{
5066					m_reference_size = compressed_texture_size;
5067				}
5068				else
5069				{
5070					throw 0;
5071				}
5072
5073				/* Download the source compressed texture image. */
5074				gl.getCompressedTexImage(TextureTarget<D>(), 0, m_compressed_texture_data);
5075				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");
5076
5077				// Upload the source compressed texture image to the texture object.
5078				// Some compressed texture format can be emulated by the driver (like the ETC2/EAC formats)
5079				// The compressed data sent by CompressedTexImage will be stored uncompressed by the driver
5080				// and will be re-compressed if the application call glGetCompressedTexImage.
5081				// The compression/decompression is not lossless, so when this happen it's possible for the source
5082				// and destination (from glGetCompressedTexImage) compressed data to be different.
5083				// To avoid that we will store both the source (in m_compressed_texture_data) and the destination
5084				// (in m_reference). The destination will be used later to make sure getCompressedTextureSubImage
5085				// return the expected value
5086				CompressedTexImage<D>(internalformat);
5087
5088				m_reference = new glw::GLubyte[m_reference_size];
5089
5090				if (DE_NULL == m_reference)
5091				{
5092					throw 0;
5093				}
5094
5095				/* Download compressed texture image. */
5096				gl.getCompressedTexImage(TextureTarget<D>(), 0, m_reference);
5097				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");
5098			}
5099		}
5100
5101		PrepareStorage<D>(internalformat);
5102	}
5103
5104	return true;
5105}
5106
5107/** @brief Prepare texture storage.
5108 *
5109 *  @tparam D      Texture dimenisons.
5110 *
5111 *  @param [in] internalformat      Texture internal format.
5112 */
5113template <>
5114void CompressedSubImageTest::PrepareStorage<1>(glw::GLenum internalformat)
5115{
5116	/* Shortcut for GL functionality. */
5117	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5118
5119	gl.bindTexture(TextureTarget<1>(), m_to);
5120	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
5121
5122	gl.texImage1D(TextureTarget<1>(), 0, internalformat, s_texture_width * s_block_count, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5123				  NULL);
5124	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");
5125}
5126
5127/** @brief Prepare texture storage.
5128 *
5129 *  @tparam D      Texture dimenisons.
5130 *
5131 *  @param [in] internalformat      Texture internal format.
5132 */
5133template <>
5134void CompressedSubImageTest::PrepareStorage<2>(glw::GLenum internalformat)
5135{
5136	/* Shortcut for GL functionality. */
5137	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5138
5139	gl.bindTexture(TextureTarget<2>(), m_to);
5140	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
5141
5142	gl.texImage2D(TextureTarget<2>(), 0, internalformat, s_texture_width * s_block_2d_size_x,
5143				  s_texture_height * s_block_2d_size_y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
5144	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");
5145}
5146
5147/** @brief Prepare texture storage.
5148 *
5149 *  @tparam D      Texture dimenisons.
5150 *
5151 *  @param [in] internalformat      Texture internal format.
5152 */
5153template <>
5154void CompressedSubImageTest::PrepareStorage<3>(glw::GLenum internalformat)
5155{
5156	/* Shortcut for GL functionality. */
5157	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5158
5159	gl.bindTexture(TextureTarget<3>(), m_to);
5160	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
5161
5162	gl.texImage3D(TextureTarget<3>(), 0, internalformat, s_texture_width * s_block_3d_size,
5163				  s_texture_height * s_block_3d_size, s_texture_depth * s_block_3d_size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5164				  NULL);
5165	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");
5166}
5167
5168/** @brief Prepare compressed texture storage.
5169 * @tparam D		Texture dimensions.
5170 *
5171 * @tparam [in] internalformat		Texture internal format.
5172 */
5173template <>
5174void CompressedSubImageTest::PrepareCompressedStorage<1>(glw::GLenum internalformat)
5175{
5176	/* Shortcut for GL functionality */
5177	const glw::Functions &gl = m_context.getRenderContext().getFunctions();
5178
5179	gl.bindTexture(TextureTarget<1>(), m_to);
5180	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
5181
5182	gl.compressedTexImage1D(TextureTarget<1>(), 0, internalformat, s_texture_width * s_block_count,
5183			0, s_texture_width * s_block_count, 0);
5184	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage1D has failed");
5185}
5186
5187/** @brief Prepare compressed texture storage.
5188 * @tparam D		Texture dimensions.
5189 *
5190 * @tparam [in] internalformat		Texture internal format.
5191 */
5192template <>
5193void CompressedSubImageTest::PrepareCompressedStorage<2>(glw::GLenum internalformat)
5194{
5195	/* Shortcut for GL functionality */
5196	const glw::Functions &gl = m_context.getRenderContext().getFunctions();
5197
5198	gl.bindTexture(TextureTarget<2>(), m_to);
5199	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
5200
5201	GLsizei size_x = s_texture_width * s_block_2d_size_x;
5202	GLsizei size_y = s_texture_height * s_block_2d_size_y;
5203	GLsizei size = m_reference_size * s_block_2d_size_x * s_block_2d_size_y;
5204
5205	gl.compressedTexImage2D(TextureTarget<2>(), 0, internalformat, size_x, size_y,
5206			0, size, 0);
5207	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage2D has failed");
5208}
5209
5210/** @brief Prepare compressed texture storage.
5211 * @tparam D		Texture dimensions.
5212 *
5213 * @tparam [in] internalformat		Texture internal format.
5214 */
5215template <>
5216void CompressedSubImageTest::PrepareCompressedStorage<3>(glw::GLenum internalformat)
5217{
5218	/* Shortcut for GL functionality */
5219	const glw::Functions &gl = m_context.getRenderContext().getFunctions();
5220
5221	gl.bindTexture(TextureTarget<3>(), m_to);
5222	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
5223
5224	GLsizei size_x = s_texture_width * s_block_3d_size;
5225	GLsizei size_y = s_texture_height * s_block_3d_size;
5226	GLsizei size_z = s_texture_depth * s_block_3d_size;
5227	GLsizei size = m_reference_size * s_block_3d_size * s_block_3d_size * s_block_3d_size;
5228
5229	gl.compressedTexImage3D(TextureTarget<3>(), 0, internalformat, size_x, size_y, size_z, 0,
5230			size, 0);
5231	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage3D has failed");
5232}
5233
5234/** @brief Compare results with the reference.
5235 *
5236 *  @tparam T      Type.
5237 *  @tparam S      Size (# of components).
5238 *  @tparam N      Is normalized.
5239 *
5240 *  @param [in] internalformat      Texture internal format.
5241 *
5242 *  @return True if equal, false otherwise.
5243 */
5244template <glw::GLuint D>
5245bool CompressedSubImageTest::CheckData(glw::GLenum internalformat)
5246{
5247	/* Shortcut for GL functionality. */
5248	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5249
5250	/* Check texture content with reference. */
5251	m_result = new glw::GLubyte[m_reference_size * s_block_count];
5252
5253	if (DE_NULL == m_result)
5254	{
5255		throw 0;
5256	}
5257
5258	gl.getCompressedTexImage(TextureTarget<D>(), 0, m_result);
5259	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");
5260	for (glw::GLuint block = 0; block < s_block_count; ++block)
5261	{
5262		for (glw::GLuint i = 0; i < m_reference_size; ++i)
5263		{
5264			if (m_reference[i] != m_result[block * m_reference_size + i])
5265			{
5266				m_context.getTestContext().getLog()
5267					<< tcu::TestLog::Message << "glCompressedTextureSubImage*D created texture with data "
5268					<< DataToString(m_reference_size, m_reference) << " however texture contains data "
5269					<< DataToString(m_reference_size, &(m_result[block * m_reference_size])) << ". Texture target was "
5270					<< glu::getTextureTargetStr(TextureTarget<D>()) << " and internal format was "
5271					<< glu::getTextureFormatStr(internalformat) << ". Test fails." << tcu::TestLog::EndMessage;
5272
5273				return false;
5274			}
5275		}
5276	}
5277
5278	return true;
5279}
5280
5281/** @brief Compare results with the reference.
5282 *
5283 *  @tparam T      Type.
5284 *  @tparam S      Size (# of components).
5285 *  @tparam N      Is normalized.
5286 *
5287 *  @param [in] internalformat      Texture internal format.
5288 *
5289 *  @return True if equal, false otherwise.
5290 */
5291template <>
5292bool CompressedSubImageTest::CheckData<3>(glw::GLenum internalformat)
5293{
5294	/* Shortcut for GL functionality. */
5295	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5296
5297	/* Check texture content with reference. */
5298	m_result = new glw::GLubyte[m_reference_size * s_block_count];
5299
5300	if (DE_NULL == m_result)
5301	{
5302		throw 0;
5303	}
5304
5305	gl.getCompressedTexImage(TextureTarget<3>(), 0, m_result);
5306	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");
5307
5308	glw::GLuint reference_layer_size = m_reference_size / s_texture_depth;
5309
5310	for (glw::GLuint i = 0; i < m_reference_size * s_block_count; ++i)
5311	{
5312		// we will read the result one bytes at the time and compare with the reference
5313		// for each bytes of the result image we need to figure out which byte in the reference image it corresponds to
5314		glw::GLuint refIdx		= i % reference_layer_size;
5315		glw::GLuint refLayerIdx = (i / (reference_layer_size * s_block_3d_size * s_block_3d_size)) % s_texture_depth;
5316		if (m_reference[refLayerIdx * reference_layer_size + refIdx] != m_result[i])
5317		{
5318			m_context.getTestContext().getLog()
5319				<< tcu::TestLog::Message << "glCompressedTextureSubImage3D created texture with data "
5320				<< DataToString(reference_layer_size, &(m_reference[refLayerIdx * reference_layer_size]))
5321				<< " however texture contains data "
5322				<< DataToString(reference_layer_size, &(m_result[i % reference_layer_size])) << ". Texture target was "
5323				<< glu::getTextureTargetStr(TextureTarget<3>()) << " and internal format was "
5324				<< glu::getTextureFormatStr(internalformat) << ". Test fails." << tcu::TestLog::EndMessage;
5325
5326			return false;
5327		}
5328	}
5329
5330	return true;
5331}
5332/** @brief Test case function.
5333 *
5334 *  @tparam D       Number of texture dimensions.
5335 *
5336 *  @param [in] internal format     Texture internal format.
5337 *
5338 *  @param [in] can be unsupported     If the format may not support online compression
5339 *
5340 *  @return True if test succeeded, false otherwise.
5341 */
5342template <glw::GLuint D>
5343bool CompressedSubImageTest::Test(glw::GLenum internalformat, bool can_be_unsupported)
5344{
5345	/* Create texture image. */
5346	CreateTextures(TextureTarget<D>());
5347
5348	if (!PrepareReferenceData<D>(internalformat))
5349	{
5350		CleanAll();
5351		return can_be_unsupported;
5352	}
5353
5354	/* Setup data with CompressedTextureSubImage<D>D function and check for errors. */
5355	if (!CompressedTextureSubImage<D>(internalformat))
5356	{
5357		CleanAll();
5358
5359		return false;
5360	}
5361
5362	/* If compressed reference data was generated than compare values. */
5363	if (m_reference)
5364	{
5365		if (!CheckData<D>(internalformat))
5366		{
5367			CleanAll();
5368
5369			return false;
5370		}
5371	}
5372
5373	CleanAll();
5374
5375	return true;
5376}
5377
5378/** @brief Clean GL objects, test variables and GL errors.
5379 */
5380void CompressedSubImageTest::CleanAll()
5381{
5382	/* Shortcut for GL functionality. */
5383	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5384
5385	/* Textures. */
5386	if (m_to)
5387	{
5388		gl.deleteTextures(1, &m_to);
5389
5390		m_to = 0;
5391	}
5392
5393	if (m_to_aux)
5394	{
5395		gl.deleteTextures(1, &m_to_aux);
5396
5397		m_to_aux = 0;
5398	}
5399
5400	/* Reference data storage. */
5401	if (DE_NULL != m_reference)
5402	{
5403		delete[] m_reference;
5404
5405		m_reference = DE_NULL;
5406	}
5407
5408	if (DE_NULL != m_compressed_texture_data)
5409	{
5410		delete[] m_compressed_texture_data;
5411
5412		m_compressed_texture_data = DE_NULL;
5413	}
5414
5415	if (DE_NULL != m_result)
5416	{
5417		delete[] m_result;
5418
5419		m_result = DE_NULL;
5420	}
5421
5422	m_reference_size = 0;
5423
5424	/* Errors. */
5425	while (GL_NO_ERROR != gl.getError())
5426		;
5427}
5428
5429/** @brief Convert raw data into string for logging purposes.
5430 *
5431 *  @param [in] count      Count of the data.
5432 *  @param [in] data       Raw data.
5433 *
5434 *  @return String representation of data.
5435 */
5436std::string CompressedSubImageTest::DataToString(glw::GLuint count, const glw::GLubyte data[])
5437{
5438	std::string data_str = "[";
5439
5440	for (glw::GLuint i = 0; i < count; ++i)
5441	{
5442		std::stringstream int_sstream;
5443
5444		int_sstream << unsigned(data[i]);
5445
5446		data_str.append(int_sstream.str());
5447
5448		if (i + 1 < count)
5449		{
5450			data_str.append(", ");
5451		}
5452		else
5453		{
5454			data_str.append("]");
5455		}
5456	}
5457
5458	return data_str;
5459}
5460
5461/** @brief Iterate Compressed SubImage Test cases.
5462 *
5463 *  @return Iteration result.
5464 */
5465tcu::TestNode::IterateResult CompressedSubImageTest::iterate()
5466{
5467	/* Shortcut for GL functionality. */
5468	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5469
5470	/* Get context setup. */
5471	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
5472	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
5473
5474	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
5475	{
5476		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
5477
5478		return STOP;
5479	}
5480
5481	/* Running tests. */
5482	bool is_ok	= true;
5483	bool is_error = false;
5484
5485	try
5486	{
5487		is_ok &= Test<1>(GL_COMPRESSED_RGB, false);
5488
5489		is_ok &= Test<2>(GL_COMPRESSED_RED_RGTC1, false);
5490		is_ok &= Test<2>(GL_COMPRESSED_SIGNED_RED_RGTC1, false);
5491		is_ok &= Test<2>(GL_COMPRESSED_RG_RGTC2, false);
5492		is_ok &= Test<2>(GL_COMPRESSED_SIGNED_RG_RGTC2, false);
5493		is_ok &= Test<2>(GL_COMPRESSED_RGBA_BPTC_UNORM, false);
5494		is_ok &= Test<2>(GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, false);
5495		is_ok &= Test<2>(GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, false);
5496		is_ok &= Test<2>(GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, false);
5497		is_ok &= Test<2>(GL_COMPRESSED_RGB8_ETC2, true);
5498		is_ok &= Test<2>(GL_COMPRESSED_SRGB8_ETC2, true);
5499		is_ok &= Test<2>(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, true);
5500		is_ok &= Test<2>(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, true);
5501		is_ok &= Test<2>(GL_COMPRESSED_RGBA8_ETC2_EAC, true);
5502		is_ok &= Test<2>(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, true);
5503		is_ok &= Test<2>(GL_COMPRESSED_R11_EAC, true);
5504		is_ok &= Test<2>(GL_COMPRESSED_SIGNED_R11_EAC, true);
5505		is_ok &= Test<2>(GL_COMPRESSED_RG11_EAC, true);
5506		is_ok &= Test<2>(GL_COMPRESSED_SIGNED_RG11_EAC, true);
5507
5508		is_ok &= Test<3>(GL_COMPRESSED_RED_RGTC1, false);
5509		is_ok &= Test<3>(GL_COMPRESSED_SIGNED_RED_RGTC1, false);
5510		is_ok &= Test<3>(GL_COMPRESSED_RG_RGTC2, false);
5511		is_ok &= Test<3>(GL_COMPRESSED_SIGNED_RG_RGTC2, false);
5512		is_ok &= Test<3>(GL_COMPRESSED_RGBA_BPTC_UNORM, false);
5513		is_ok &= Test<3>(GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, false);
5514		is_ok &= Test<3>(GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, false);
5515		is_ok &= Test<3>(GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, false);
5516		is_ok &= Test<3>(GL_COMPRESSED_RGB8_ETC2, true);
5517		is_ok &= Test<3>(GL_COMPRESSED_SRGB8_ETC2, true);
5518		is_ok &= Test<3>(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, true);
5519		is_ok &= Test<3>(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, true);
5520		is_ok &= Test<3>(GL_COMPRESSED_RGBA8_ETC2_EAC, true);
5521		is_ok &= Test<3>(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, true);
5522		is_ok &= Test<3>(GL_COMPRESSED_R11_EAC, true);
5523		is_ok &= Test<3>(GL_COMPRESSED_SIGNED_R11_EAC, true);
5524		is_ok &= Test<3>(GL_COMPRESSED_RG11_EAC, true);
5525		is_ok &= Test<3>(GL_COMPRESSED_SIGNED_RG11_EAC, true);
5526	}
5527	catch (...)
5528	{
5529		is_ok	= false;
5530		is_error = true;
5531	}
5532
5533	/* Cleanup. */
5534	CleanAll();
5535
5536	/* Errors clean up. */
5537	while (gl.getError())
5538		;
5539
5540	/* Result's setup. */
5541	if (is_ok)
5542	{
5543		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
5544	}
5545	else
5546	{
5547		if (is_error)
5548		{
5549			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
5550		}
5551		else
5552		{
5553			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
5554		}
5555	}
5556
5557	return STOP;
5558}
5559
5560/** Reference data. */
5561const glw::GLubyte CompressedSubImageTest::s_texture_data[] = {
5562	0x00, 0x00, 0x00, 0xFF, 0x7f, 0x7f, 0x7f, 0x00, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0x00,
5563	0x88, 0x00, 0x15, 0xFF, 0xed, 0x1c, 0x24, 0x00, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x00, 0x00,
5564	0xc8, 0xbf, 0xe7, 0xFF, 0x70, 0x92, 0xbe, 0x00, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0x00,
5565	0xa3, 0x49, 0xa4, 0xFF, 0x3f, 0x48, 0xcc, 0x00, 0x00, 0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0x00,
5566
5567	0xa3, 0x49, 0xa4, 0xFF, 0xc8, 0xbf, 0xe7, 0x00, 0x88, 0x00, 0x15, 0xff, 0x00, 0x00, 0x00, 0x00,
5568	0x3f, 0x48, 0xcc, 0xFF, 0x70, 0x92, 0xbe, 0x00, 0xed, 0x1c, 0x24, 0xff, 0x7f, 0x7f, 0x7f, 0x00,
5569	0x00, 0xa2, 0xe8, 0xFF, 0x99, 0xd9, 0xea, 0x00, 0xff, 0x7f, 0x27, 0xff, 0xc3, 0xc3, 0xc3, 0x00,
5570	0x22, 0xb1, 0x4c, 0xFF, 0xb5, 0xe6, 0x1d, 0x00, 0xff, 0xf2, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
5571
5572	0x22, 0xb1, 0x4c, 0xFF, 0x00, 0xa2, 0xe8, 0x00, 0x3f, 0x48, 0xcc, 0xff, 0xa3, 0x49, 0xa4, 0x00,
5573	0xb5, 0xe6, 0x1d, 0xFF, 0x99, 0xd9, 0xea, 0x00, 0x70, 0x92, 0xbe, 0xff, 0xc8, 0xbf, 0xe7, 0x00,
5574	0xff, 0xf2, 0x00, 0xFF, 0xff, 0x7f, 0x27, 0x00, 0xed, 0x1c, 0x24, 0xff, 0x88, 0x00, 0x15, 0x00,
5575	0xff, 0xff, 0xff, 0xFF, 0xc3, 0xc3, 0xc3, 0x00, 0x7f, 0x7f, 0x7f, 0xff, 0x00, 0x00, 0x00, 0x00,
5576
5577	0xff, 0xff, 0xff, 0xFF, 0xff, 0xf2, 0x00, 0x00, 0xb5, 0xe6, 0x1d, 0xff, 0x22, 0xb1, 0x4c, 0x00,
5578	0xc3, 0xc3, 0xc3, 0xFF, 0xff, 0x7f, 0x27, 0x00, 0x99, 0xd9, 0xea, 0xff, 0x00, 0xa2, 0xe8, 0x00,
5579	0x7f, 0x7f, 0x7f, 0xFF, 0xed, 0x1c, 0x24, 0x00, 0x70, 0x92, 0xbe, 0xff, 0x3f, 0x48, 0xcc, 0x00,
5580	0x00, 0x00, 0x00, 0xFF, 0x88, 0x00, 0x15, 0x00, 0xc8, 0xbf, 0xe7, 0xff, 0xa3, 0x49, 0xa4, 0x00
5581};
5582
5583/** Reference data parameters. */
5584const glw::GLuint CompressedSubImageTest::s_texture_width   = 4;
5585const glw::GLuint CompressedSubImageTest::s_texture_height  = 4;
5586const glw::GLuint CompressedSubImageTest::s_texture_depth   = 4;
5587const glw::GLuint CompressedSubImageTest::s_block_count		= 8;
5588const glw::GLuint CompressedSubImageTest::s_block_2d_size_x = 4;
5589const glw::GLuint CompressedSubImageTest::s_block_2d_size_y = 2;
5590const glw::GLuint CompressedSubImageTest::s_block_3d_size   = 2;
5591
5592/******************************** Copy SubImage Test Implementation   ********************************/
5593
5594/** @brief Compressed SubImage Test constructor.
5595 *
5596 *  @param [in] context     OpenGL context.
5597 */
5598CopyTest::CopyTest(deqp::Context& context)
5599	: deqp::TestCase(context, "textures_copy", "Texture Copy Test")
5600	, m_fbo(0)
5601	, m_to_src(0)
5602	, m_to_dst(0)
5603	, m_result(DE_NULL)
5604{
5605	/* Intentionally left blank. */
5606}
5607
5608/** @brief Texture target selector.
5609 *
5610 *  @tparam D      Texture dimenisons.
5611 *
5612 *  @return Texture target.
5613 */
5614template <>
5615glw::GLenum CopyTest::TextureTarget<1>()
5616{
5617	return GL_TEXTURE_1D;
5618}
5619template <>
5620glw::GLenum CopyTest::TextureTarget<2>()
5621{
5622	return GL_TEXTURE_2D;
5623}
5624template <>
5625glw::GLenum CopyTest::TextureTarget<3>()
5626{
5627	return GL_TEXTURE_3D;
5628}
5629
5630/** @brief Copy texture, check errors and log.
5631 *
5632 *  @note Parameters as passed to CopyTextureSubImage*D
5633 *
5634 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
5635 */
5636bool CopyTest::CopyTextureSubImage1DAndCheckErrors(glw::GLuint texture, glw::GLint level, glw::GLint xoffset,
5637												   glw::GLint x, glw::GLint y, glw::GLsizei width)
5638{
5639	/* Shortcut for GL functionality. */
5640	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5641
5642	gl.readBuffer(GL_COLOR_ATTACHMENT0);
5643	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");
5644
5645	gl.copyTextureSubImage1D(texture, level, xoffset, x, y, width);
5646
5647	/* Check errors. */
5648	glw::GLenum error;
5649
5650	if (GL_NO_ERROR != (error = gl.getError()))
5651	{
5652		m_context.getTestContext().getLog() << tcu::TestLog::Message
5653											<< "glCopyTextureSubImage1D unexpectedly generated error "
5654											<< glu::getErrorStr(error) << ". Test fails." << tcu::TestLog::EndMessage;
5655
5656		return false;
5657	}
5658
5659	return true;
5660}
5661
5662/** @brief Copy texture, check errors and log.
5663 *
5664 *  @note Parameters as passed to CopyTextureSubImage*D
5665 *
5666 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
5667 */
5668bool CopyTest::CopyTextureSubImage2DAndCheckErrors(glw::GLuint texture, glw::GLint level, glw::GLint xoffset,
5669												   glw::GLint yoffset, glw::GLint x, glw::GLint y, glw::GLsizei width,
5670												   glw::GLsizei height)
5671{
5672	/* Shortcut for GL functionality. */
5673	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5674
5675	gl.readBuffer(GL_COLOR_ATTACHMENT0);
5676	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");
5677
5678	gl.copyTextureSubImage2D(texture, level, xoffset, yoffset, x, y, width, height);
5679
5680	/* Check errors. */
5681	glw::GLenum error;
5682
5683	if (GL_NO_ERROR != (error = gl.getError()))
5684	{
5685		m_context.getTestContext().getLog() << tcu::TestLog::Message
5686											<< "glCopyTextureSubImage2D unexpectedly generated error "
5687											<< glu::getErrorStr(error) << ". Test fails." << tcu::TestLog::EndMessage;
5688
5689		return false;
5690	}
5691
5692	return true;
5693}
5694
5695/** @brief Copy texture, check errors and log.
5696 *
5697 *  @note Parameters as passed to CopyTextureSubImage*D
5698 *
5699 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
5700 */
5701bool CopyTest::CopyTextureSubImage3DAndCheckErrors(glw::GLuint texture, glw::GLint level, glw::GLint xoffset,
5702												   glw::GLint yoffset, glw::GLint zoffset, glw::GLint x, glw::GLint y,
5703												   glw::GLsizei width, glw::GLsizei height)
5704{
5705	/* Shortcut for GL functionality. */
5706	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5707
5708	gl.readBuffer(GL_COLOR_ATTACHMENT0 + zoffset);
5709	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");
5710
5711	gl.copyTextureSubImage3D(texture, level, xoffset, yoffset, zoffset, x, y, width, height);
5712
5713	/* Check errors. */
5714	glw::GLenum error;
5715
5716	if (GL_NO_ERROR != (error = gl.getError()))
5717	{
5718		m_context.getTestContext().getLog() << tcu::TestLog::Message
5719											<< "glCopyTextureSubImage3D unexpectedly generated error "
5720											<< glu::getErrorStr(error) << ". Test fails." << tcu::TestLog::EndMessage;
5721
5722		return false;
5723	}
5724
5725	return true;
5726}
5727
5728/** @brief Create texture.
5729 *
5730 *  @tparam D      Dimmensions.
5731 */
5732template <>
5733void CopyTest::CreateSourceTexture<1>()
5734{
5735	/* Shortcut for GL functionality. */
5736	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5737
5738	gl.genTextures(1, &m_to_src);
5739	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
5740
5741	gl.bindTexture(TextureTarget<1>(), m_to_src);
5742	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
5743
5744	gl.texImage1D(TextureTarget<1>(), 0, GL_RGBA8, s_texture_width, 0, GL_RGBA, GL_UNSIGNED_BYTE, s_texture_data);
5745	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D call failed.");
5746}
5747
5748/** @brief Create texture.
5749 *
5750 *  @tparam D      Dimmensions.
5751 */
5752template <>
5753void CopyTest::CreateSourceTexture<2>()
5754{
5755	/* Shortcut for GL functionality. */
5756	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5757
5758	gl.genTextures(1, &m_to_src);
5759	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
5760
5761	gl.bindTexture(TextureTarget<2>(), m_to_src);
5762	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
5763
5764	gl.texImage2D(TextureTarget<2>(), 0, GL_RGBA8, s_texture_width, s_texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5765				  s_texture_data);
5766	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D call failed.");
5767}
5768
5769/** @brief Create texture.
5770 *
5771 *  @tparam D      Dimmensions.
5772 */
5773template <>
5774void CopyTest::CreateSourceTexture<3>()
5775{
5776	/* Shortcut for GL functionality. */
5777	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5778
5779	gl.genTextures(1, &m_to_src);
5780	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
5781
5782	gl.bindTexture(TextureTarget<3>(), m_to_src);
5783	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
5784
5785	gl.texImage3D(TextureTarget<3>(), 0, GL_RGBA8, s_texture_width, s_texture_height, s_texture_depth, 0, GL_RGBA,
5786				  GL_UNSIGNED_BYTE, s_texture_data);
5787	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D call failed.");
5788}
5789
5790/** @brief Create texture.
5791 *
5792 *  @tparam D      Dimmensions.
5793 */
5794template <>
5795void CopyTest::CreateDestinationTexture<1>()
5796{
5797	/* Shortcut for GL functionality. */
5798	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5799
5800	gl.genTextures(1, &m_to_dst);
5801	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
5802
5803	gl.bindTexture(TextureTarget<1>(), m_to_dst);
5804	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
5805
5806	gl.texImage1D(TextureTarget<1>(), 0, GL_RGBA8, s_texture_width, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
5807	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D call failed.");
5808}
5809
5810/** @brief Create texture.
5811 *
5812 *  @tparam D      Dimmensions.
5813 */
5814template <>
5815void CopyTest::CreateDestinationTexture<2>()
5816{
5817	/* Shortcut for GL functionality. */
5818	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5819
5820	gl.genTextures(1, &m_to_dst);
5821	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
5822
5823	gl.bindTexture(TextureTarget<2>(), m_to_dst);
5824	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
5825
5826	gl.texImage2D(TextureTarget<2>(), 0, GL_RGBA8, s_texture_width, s_texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5827				  DE_NULL);
5828	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D call failed.");
5829}
5830
5831/** @brief Create texture.
5832 *
5833 *  @tparam D      Dimmensions.
5834 */
5835template <>
5836void CopyTest::CreateDestinationTexture<3>()
5837{
5838	/* Shortcut for GL functionality. */
5839	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5840
5841	gl.genTextures(1, &m_to_dst);
5842	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
5843
5844	gl.bindTexture(TextureTarget<3>(), m_to_dst);
5845	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
5846
5847	gl.texImage3D(TextureTarget<3>(), 0, GL_RGBA8, s_texture_width, s_texture_height, s_texture_depth, 0, GL_RGBA,
5848				  GL_UNSIGNED_BYTE, DE_NULL);
5849	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D call failed.");
5850}
5851
5852/** @brief Create framebuffer.
5853 *
5854 *  @tparam D      Dimmensions.
5855 */
5856template <>
5857void CopyTest::CreateSourceFramebuffer<1>()
5858{
5859	/* Shortcut for GL functionality. */
5860	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5861
5862	/* Prepare framebuffer. */
5863	gl.genFramebuffers(1, &m_fbo);
5864	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
5865
5866	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
5867	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
5868
5869	gl.framebufferTexture1D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, TextureTarget<1>(), m_to_src, 0);
5870	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture1D call failed.");
5871
5872	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
5873	{
5874		throw 0;
5875	}
5876
5877	gl.viewport(0, 0, s_texture_width, 1);
5878	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
5879}
5880
5881/** @brief Create framebuffer.
5882 *
5883 *  @tparam D      Dimmensions.
5884 */
5885template <>
5886void CopyTest::CreateSourceFramebuffer<2>()
5887{
5888	/* Shortcut for GL functionality. */
5889	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5890
5891	/* Prepare framebuffer. */
5892	gl.genFramebuffers(1, &m_fbo);
5893	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
5894
5895	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
5896	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
5897
5898	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, TextureTarget<2>(), m_to_src, 0);
5899	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture1D call failed.");
5900
5901	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
5902	{
5903		throw 0;
5904	}
5905
5906	gl.viewport(0, 0, s_texture_width, s_texture_height);
5907	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
5908}
5909
5910/** @brief Create framebuffer.
5911 *
5912 *  @tparam D      Dimmensions.
5913 */
5914template <>
5915void CopyTest::CreateSourceFramebuffer<3>()
5916{
5917	/* Shortcut for GL functionality. */
5918	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5919
5920	/* Prepare framebuffer. */
5921	gl.genFramebuffers(1, &m_fbo);
5922	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
5923
5924	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
5925	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
5926
5927	for (glw::GLuint i = 0; i < s_texture_depth; ++i)
5928	{
5929		gl.framebufferTexture3D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, TextureTarget<3>(), m_to_src, 0, i);
5930		GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture1D call failed.");
5931	}
5932
5933	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
5934	{
5935		throw 0;
5936	}
5937
5938	gl.viewport(0, 0, s_texture_width, s_texture_height);
5939	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
5940}
5941
5942/** @brief Dispatch function to create test objects */
5943template <glw::GLuint D>
5944void				  CopyTest::CreateAll()
5945{
5946	CreateSourceTexture<D>();
5947	CreateSourceFramebuffer<D>();
5948	CreateDestinationTexture<D>();
5949}
5950
5951/** @brief Test function */
5952template <>
5953bool CopyTest::Test<1>()
5954{
5955	CreateAll<1>();
5956
5957	bool result = true;
5958
5959	result &= CopyTextureSubImage1DAndCheckErrors(m_to_dst, 0, 0, 0, 0, s_texture_width / 2);
5960	result &= CopyTextureSubImage1DAndCheckErrors(m_to_dst, 0, s_texture_width / 2, s_texture_width / 2, 0,
5961												  s_texture_width / 2);
5962
5963	result &= CheckData(TextureTarget<1>(), 4 /* RGBA */ * s_texture_width);
5964
5965	CleanAll();
5966
5967	return result;
5968}
5969
5970/** @brief Test function */
5971template <>
5972bool CopyTest::Test<2>()
5973{
5974	CreateAll<2>();
5975
5976	bool result = true;
5977
5978	result &= CopyTextureSubImage2DAndCheckErrors(m_to_dst, 0, 0, 0, 0, 0, s_texture_width / 2, s_texture_height / 2);
5979	result &= CopyTextureSubImage2DAndCheckErrors(m_to_dst, 0, s_texture_width / 2, 0, s_texture_width / 2, 0,
5980												  s_texture_width / 2, s_texture_height / 2);
5981	result &= CopyTextureSubImage2DAndCheckErrors(m_to_dst, 0, 0, s_texture_height / 2, 0, s_texture_height / 2,
5982												  s_texture_width / 2, s_texture_height / 2);
5983	result &=
5984		CopyTextureSubImage2DAndCheckErrors(m_to_dst, 0, s_texture_width / 2, s_texture_height / 2, s_texture_width / 2,
5985											s_texture_height / 2, s_texture_width / 2, s_texture_height / 2);
5986
5987	result &= CheckData(TextureTarget<2>(), 4 /* RGBA */ * s_texture_width * s_texture_height);
5988
5989	CleanAll();
5990
5991	return result;
5992}
5993
5994/** @brief Test function */
5995template <>
5996bool CopyTest::Test<3>()
5997{
5998	CreateAll<3>();
5999
6000	bool result = true;
6001
6002	for (glw::GLuint i = 0; i < s_texture_depth; ++i)
6003	{
6004		result &=
6005			CopyTextureSubImage3DAndCheckErrors(m_to_dst, 0, 0, 0, i, 0, 0, s_texture_width / 2, s_texture_height / 2);
6006		result &= CopyTextureSubImage3DAndCheckErrors(m_to_dst, 0, s_texture_width / 2, 0, i, s_texture_width / 2, 0,
6007													  s_texture_width / 2, s_texture_height / 2);
6008		result &= CopyTextureSubImage3DAndCheckErrors(m_to_dst, 0, 0, s_texture_height / 2, i, 0, s_texture_height / 2,
6009													  s_texture_width / 2, s_texture_height / 2);
6010		result &= CopyTextureSubImage3DAndCheckErrors(m_to_dst, 0, s_texture_width / 2, s_texture_height / 2, i,
6011													  s_texture_width / 2, s_texture_height / 2, s_texture_width / 2,
6012													  s_texture_height / 2);
6013	}
6014
6015	result &= CheckData(TextureTarget<3>(), 4 /* RGBA */ * s_texture_width * s_texture_height * s_texture_depth);
6016
6017	CleanAll();
6018
6019	return result;
6020}
6021
6022/** @brief Compre results with the reference.
6023 *
6024 *  @param [in] target      Texture target.
6025 *  @param [in] size        Size of the buffer.
6026 *
6027 *  @return True if equal, false otherwise.
6028 */
6029bool CopyTest::CheckData(glw::GLenum target, glw::GLuint size)
6030{
6031	/* Shortcut for GL functionality. */
6032	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6033
6034	/* Check texture content with reference. */
6035	m_result = new glw::GLubyte[size];
6036
6037	if (DE_NULL == m_result)
6038	{
6039		throw 0;
6040	}
6041
6042	gl.getTexImage(target, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_result);
6043	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");
6044
6045	for (glw::GLuint i = 0; i < size; ++i)
6046	{
6047		if (s_texture_data[i] != m_result[i])
6048		{
6049			m_context.getTestContext().getLog()
6050				<< tcu::TestLog::Message << "glCopyTextureSubImage*D created texture with data "
6051				<< DataToString(size, s_texture_data) << " however texture contains data "
6052				<< DataToString(size, m_result) << ". Texture target was " << glu::getTextureTargetStr(target)
6053				<< ". Test fails." << tcu::TestLog::EndMessage;
6054
6055			return false;
6056		}
6057	}
6058
6059	return true;
6060}
6061
6062/** @brief Convert raw data into string for logging purposes.
6063 *
6064 *  @param [in] count      Count of the data.
6065 *  @param [in] data       Raw data.
6066 *
6067 *  @return String representation of data.
6068 */
6069std::string CopyTest::DataToString(glw::GLuint count, const glw::GLubyte data[])
6070{
6071	std::string data_str = "[";
6072
6073	for (glw::GLuint i = 0; i < count; ++i)
6074	{
6075		std::stringstream int_sstream;
6076
6077		int_sstream << unsigned(data[i]);
6078
6079		data_str.append(int_sstream.str());
6080
6081		if (i + 1 < count)
6082		{
6083			data_str.append(", ");
6084		}
6085		else
6086		{
6087			data_str.append("]");
6088		}
6089	}
6090
6091	return data_str;
6092}
6093
6094/** @brief Clean GL objects, test variables and GL errors.
6095 */
6096void CopyTest::CleanAll()
6097{
6098	/* Shortcut for GL functionality. */
6099	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6100
6101	if (m_fbo)
6102	{
6103		gl.deleteFramebuffers(1, &m_fbo);
6104
6105		m_fbo = 0;
6106	}
6107
6108	if (m_to_src)
6109	{
6110		gl.deleteTextures(1, &m_to_src);
6111
6112		m_to_src = 0;
6113	}
6114
6115	if (m_to_dst)
6116	{
6117		gl.deleteTextures(1, &m_to_dst);
6118
6119		m_to_dst = 0;
6120	}
6121
6122	if (DE_NULL == m_result)
6123	{
6124		delete[] m_result;
6125
6126		m_result = DE_NULL;
6127	}
6128
6129	while (GL_NO_ERROR != gl.getError())
6130		;
6131}
6132
6133/** @brief Iterate Copy Test cases.
6134 *
6135 *  @return Iteration result.
6136 */
6137tcu::TestNode::IterateResult CopyTest::iterate()
6138{
6139	/* Get context setup. */
6140	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
6141	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
6142
6143	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
6144	{
6145		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
6146
6147		return STOP;
6148	}
6149
6150	/* Running tests. */
6151	bool is_ok	= true;
6152	bool is_error = false;
6153
6154	try
6155	{
6156		is_ok &= Test<1>();
6157		is_ok &= Test<2>();
6158		is_ok &= Test<3>();
6159	}
6160	catch (...)
6161	{
6162		is_ok	= false;
6163		is_error = true;
6164	}
6165
6166	/* Cleanup. */
6167	CleanAll();
6168
6169	/* Result's setup. */
6170	if (is_ok)
6171	{
6172		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
6173	}
6174	else
6175	{
6176		if (is_error)
6177		{
6178			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
6179		}
6180		else
6181		{
6182			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
6183		}
6184	}
6185
6186	return STOP;
6187}
6188
6189/** Reference data. */
6190const glw::GLubyte CopyTest::s_texture_data[] = {
6191	0x00, 0x00, 0x00, 0xFF, 0x7f, 0x7f, 0x7f, 0x00, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0x00,
6192	0x88, 0x00, 0x15, 0xFF, 0xed, 0x1c, 0x24, 0x00, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x00, 0x00,
6193	0xc8, 0xbf, 0xe7, 0xFF, 0x70, 0x92, 0xbe, 0x00, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0x00,
6194	0xa3, 0x49, 0xa4, 0xFF, 0x3f, 0x48, 0xcc, 0x00, 0x00, 0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0x00,
6195
6196	0xa3, 0x49, 0xa4, 0xFF, 0xc8, 0xbf, 0xe7, 0x00, 0x88, 0x00, 0x15, 0xff, 0x00, 0x00, 0x00, 0x00,
6197	0x3f, 0x48, 0xcc, 0xFF, 0x70, 0x92, 0xbe, 0x00, 0xed, 0x1c, 0x24, 0xff, 0x7f, 0x7f, 0x7f, 0x00,
6198	0x00, 0xa2, 0xe8, 0xFF, 0x99, 0xd9, 0xea, 0x00, 0xff, 0x7f, 0x27, 0xff, 0xc3, 0xc3, 0xc3, 0x00,
6199	0x22, 0xb1, 0x4c, 0xFF, 0xb5, 0xe6, 0x1d, 0x00, 0xff, 0xf2, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
6200
6201	0x22, 0xb1, 0x4c, 0xFF, 0x00, 0xa2, 0xe8, 0x00, 0x3f, 0x48, 0xcc, 0xff, 0xa3, 0x49, 0xa4, 0x00,
6202	0xb5, 0xe6, 0x1d, 0xFF, 0x99, 0xd9, 0xea, 0x00, 0x70, 0x92, 0xbe, 0xff, 0xc8, 0xbf, 0xe7, 0x00,
6203	0xff, 0xf2, 0x00, 0xFF, 0xff, 0x7f, 0x27, 0x00, 0xed, 0x1c, 0x24, 0xff, 0x88, 0x00, 0x15, 0x00,
6204	0xff, 0xff, 0xff, 0xFF, 0xc3, 0xc3, 0xc3, 0x00, 0x7f, 0x7f, 0x7f, 0xff, 0x00, 0x00, 0x00, 0x00,
6205
6206	0xff, 0xff, 0xff, 0xFF, 0xff, 0xf2, 0x00, 0x00, 0xb5, 0xe6, 0x1d, 0xff, 0x22, 0xb1, 0x4c, 0x00,
6207	0xc3, 0xc3, 0xc3, 0xFF, 0xff, 0x7f, 0x27, 0x00, 0x99, 0xd9, 0xea, 0xff, 0x00, 0xa2, 0xe8, 0x00,
6208	0x7f, 0x7f, 0x7f, 0xFF, 0xed, 0x1c, 0x24, 0x00, 0x70, 0x92, 0xbe, 0xff, 0x3f, 0x48, 0xcc, 0x00,
6209	0x00, 0x00, 0x00, 0xFF, 0x88, 0x00, 0x15, 0x00, 0xc8, 0xbf, 0xe7, 0xff, 0xa3, 0x49, 0xa4, 0x00
6210};
6211
6212/** Reference data parameters. */
6213const glw::GLuint CopyTest::s_texture_width  = 4;
6214const glw::GLuint CopyTest::s_texture_height = 4;
6215const glw::GLuint CopyTest::s_texture_depth  = 4;
6216
6217/******************************** Get Set Parameter Test Implementation   ********************************/
6218
6219/** @brief Get Set Parameter Test constructor.
6220 *
6221 *  @param [in] context     OpenGL context.
6222 */
6223GetSetParameterTest::GetSetParameterTest(deqp::Context& context)
6224	: deqp::TestCase(context, "textures_get_set_parameter", "Texture Get Set Parameter Test")
6225{
6226	/* Intentionally left blank. */
6227}
6228
6229/** @brief Iterate Get Set Parameter Test cases.
6230 *
6231 *  @return Iteration result.
6232 */
6233tcu::TestNode::IterateResult GetSetParameterTest::iterate()
6234{
6235	/* Shortcut for GL functionality. */
6236	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6237
6238	/* Get context setup. */
6239	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
6240	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
6241
6242	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
6243	{
6244		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
6245
6246		return STOP;
6247	}
6248
6249	/* Running tests. */
6250	bool is_ok	= true;
6251	bool is_error = false;
6252
6253	/* Texture. */
6254	glw::GLuint texture = 0;
6255
6256	try
6257	{
6258		gl.genTextures(1, &texture);
6259		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
6260
6261		gl.bindTexture(GL_TEXTURE_3D, texture);
6262		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
6263
6264		{
6265			glw::GLenum name	  = GL_DEPTH_STENCIL_TEXTURE_MODE;
6266			glw::GLint  value_src = GL_DEPTH_COMPONENT;
6267			glw::GLint  value_dst = 0;
6268
6269			gl.textureParameteri(texture, name, value_src);
6270			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
6271
6272			gl.getTextureParameteriv(texture, name, &value_dst);
6273			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
6274
6275			is_ok &= CompareAndLog(value_src, value_dst, name);
6276		}
6277
6278		{
6279			glw::GLenum name	  = GL_TEXTURE_BASE_LEVEL;
6280			glw::GLint  value_src = 2;
6281			glw::GLint  value_dst = 0;
6282
6283			gl.textureParameteri(texture, name, value_src);
6284			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
6285
6286			gl.getTextureParameteriv(texture, name, &value_dst);
6287			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
6288
6289			is_ok &= CompareAndLog(value_src, value_dst, name);
6290		}
6291
6292		{
6293			glw::GLenum  name		  = GL_TEXTURE_BORDER_COLOR;
6294			glw::GLfloat value_src[4] = { 0.25, 0.5, 0.75, 1.0 };
6295			glw::GLfloat value_dst[4] = {};
6296
6297			gl.textureParameterfv(texture, name, value_src);
6298			is_ok &= CheckErrorAndLog("glTextureParameterfv", name);
6299
6300			gl.getTextureParameterfv(texture, name, value_dst);
6301			is_ok &= CheckErrorAndLog("glGetTextureParameterfv", name);
6302
6303			is_ok &= CompareAndLog(value_src, value_dst, name);
6304		}
6305
6306		{
6307			glw::GLenum name		 = GL_TEXTURE_BORDER_COLOR;
6308			glw::GLint  value_src[4] = { 0, 64, -64, -32 };
6309			glw::GLint  value_dst[4] = {};
6310
6311			gl.textureParameterIiv(texture, name, value_src);
6312			is_ok &= CheckErrorAndLog("glTextureParameterIiv", name);
6313
6314			gl.getTextureParameterIiv(texture, name, value_dst);
6315			is_ok &= CheckErrorAndLog("glGetTextureParameterIiv", name);
6316
6317			is_ok &= CompareAndLog(value_src, value_dst, name);
6318		}
6319
6320		{
6321			glw::GLenum name		 = GL_TEXTURE_BORDER_COLOR;
6322			glw::GLuint value_src[4] = { 0, 64, 128, 192 };
6323			glw::GLuint value_dst[4] = {};
6324
6325			gl.textureParameterIuiv(texture, name, value_src);
6326			is_ok &= CheckErrorAndLog("glTextureParameterIuiv", name);
6327
6328			gl.getTextureParameterIuiv(texture, name, value_dst);
6329			is_ok &= CheckErrorAndLog("glGetTextureParameterIuiv", name);
6330
6331			is_ok &= CompareAndLog(value_src, value_dst, name);
6332		}
6333
6334		{
6335			glw::GLenum name	  = GL_TEXTURE_COMPARE_FUNC;
6336			glw::GLint  value_src = GL_LEQUAL;
6337			glw::GLint  value_dst = 0;
6338
6339			gl.textureParameteri(texture, name, value_src);
6340			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
6341
6342			gl.getTextureParameteriv(texture, name, &value_dst);
6343			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
6344
6345			is_ok &= CompareAndLog(value_src, value_dst, name);
6346		}
6347
6348		{
6349			glw::GLenum name	  = GL_TEXTURE_COMPARE_MODE;
6350			glw::GLint  value_src = GL_COMPARE_REF_TO_TEXTURE;
6351			glw::GLint  value_dst = 0;
6352
6353			gl.textureParameteri(texture, name, value_src);
6354			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
6355
6356			gl.getTextureParameteriv(texture, name, &value_dst);
6357			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
6358
6359			is_ok &= CompareAndLog(value_src, value_dst, name);
6360		}
6361
6362		{
6363			glw::GLenum  name	  = GL_TEXTURE_LOD_BIAS;
6364			glw::GLfloat value_src = -2.f;
6365			glw::GLfloat value_dst = 0.f;
6366
6367			gl.textureParameterf(texture, name, value_src);
6368			is_ok &= CheckErrorAndLog("glTextureParameterf", name);
6369
6370			gl.getTextureParameterfv(texture, name, &value_dst);
6371			is_ok &= CheckErrorAndLog("glGetTextureParameterfv", name);
6372
6373			is_ok &= CompareAndLog(value_src, value_dst, name);
6374		}
6375
6376		{
6377			glw::GLenum name	  = GL_TEXTURE_MIN_FILTER;
6378			glw::GLint  value_src = GL_LINEAR_MIPMAP_NEAREST;
6379			glw::GLint  value_dst = 0;
6380
6381			gl.textureParameteri(texture, name, value_src);
6382			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
6383
6384			gl.getTextureParameteriv(texture, name, &value_dst);
6385			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
6386
6387			is_ok &= CompareAndLog(value_src, value_dst, name);
6388		}
6389
6390		{
6391			glw::GLenum name	  = GL_TEXTURE_MAG_FILTER;
6392			glw::GLint  value_src = GL_NEAREST;
6393			glw::GLint  value_dst = 0;
6394
6395			gl.textureParameteri(texture, name, value_src);
6396			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
6397
6398			gl.getTextureParameteriv(texture, name, &value_dst);
6399			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
6400
6401			is_ok &= CompareAndLog(value_src, value_dst, name);
6402		}
6403
6404		{
6405			glw::GLenum name	  = GL_TEXTURE_MIN_LOD;
6406			glw::GLint  value_src = -100;
6407			glw::GLint  value_dst = 0;
6408
6409			gl.textureParameteri(texture, name, value_src);
6410			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
6411
6412			gl.getTextureParameteriv(texture, name, &value_dst);
6413			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
6414
6415			is_ok &= CompareAndLog(value_src, value_dst, name);
6416		}
6417
6418		{
6419			glw::GLenum name	  = GL_TEXTURE_MAX_LOD;
6420			glw::GLint  value_src = 100;
6421			glw::GLint  value_dst = 0;
6422
6423			gl.textureParameteri(texture, name, value_src);
6424			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
6425
6426			gl.getTextureParameteriv(texture, name, &value_dst);
6427			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
6428
6429			is_ok &= CompareAndLog(value_src, value_dst, name);
6430		}
6431
6432		{
6433			glw::GLenum name	  = GL_TEXTURE_MAX_LEVEL;
6434			glw::GLint  value_src = 100;
6435			glw::GLint  value_dst = 0;
6436
6437			gl.textureParameteri(texture, name, value_src);
6438			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
6439
6440			gl.getTextureParameteriv(texture, name, &value_dst);
6441			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
6442
6443			is_ok &= CompareAndLog(value_src, value_dst, name);
6444		}
6445
6446		{
6447			glw::GLenum name	  = GL_TEXTURE_SWIZZLE_R;
6448			glw::GLint  value_src = GL_BLUE;
6449			glw::GLint  value_dst = 0;
6450
6451			gl.textureParameteri(texture, name, value_src);
6452			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
6453
6454			gl.getTextureParameteriv(texture, name, &value_dst);
6455			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
6456
6457			is_ok &= CompareAndLog(value_src, value_dst, name);
6458		}
6459
6460		{
6461			glw::GLenum name	  = GL_TEXTURE_SWIZZLE_G;
6462			glw::GLint  value_src = GL_ALPHA;
6463			glw::GLint  value_dst = 0;
6464
6465			gl.textureParameteri(texture, name, value_src);
6466			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
6467
6468			gl.getTextureParameteriv(texture, name, &value_dst);
6469			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
6470
6471			is_ok &= CompareAndLog(value_src, value_dst, name);
6472		}
6473
6474		{
6475			glw::GLenum name	  = GL_TEXTURE_SWIZZLE_B;
6476			glw::GLint  value_src = GL_RED;
6477			glw::GLint  value_dst = 0;
6478
6479			gl.textureParameteri(texture, name, value_src);
6480			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
6481
6482			gl.getTextureParameteriv(texture, name, &value_dst);
6483			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
6484
6485			is_ok &= CompareAndLog(value_src, value_dst, name);
6486		}
6487
6488		{
6489			glw::GLenum name	  = GL_TEXTURE_SWIZZLE_A;
6490			glw::GLint  value_src = GL_GREEN;
6491			glw::GLint  value_dst = 0;
6492
6493			gl.textureParameteri(texture, name, value_src);
6494			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
6495
6496			gl.getTextureParameteriv(texture, name, &value_dst);
6497			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
6498
6499			is_ok &= CompareAndLog(value_src, value_dst, name);
6500		}
6501
6502		{
6503			glw::GLenum name		 = GL_TEXTURE_SWIZZLE_RGBA;
6504			glw::GLint  value_src[4] = { GL_ZERO, GL_ONE, GL_ZERO, GL_ONE };
6505			glw::GLint  value_dst[4] = {};
6506
6507			gl.textureParameteriv(texture, name, value_src);
6508			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
6509
6510			gl.getTextureParameteriv(texture, name, value_dst);
6511			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
6512
6513			is_ok &= CompareAndLog(value_src, value_dst, name);
6514		}
6515
6516		{
6517			glw::GLenum name	  = GL_TEXTURE_WRAP_S;
6518			glw::GLint  value_src = GL_MIRROR_CLAMP_TO_EDGE;
6519			glw::GLint  value_dst = 11;
6520
6521			gl.textureParameteri(texture, name, value_src);
6522			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
6523
6524			gl.getTextureParameteriv(texture, name, &value_dst);
6525			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
6526
6527			is_ok &= CompareAndLog(value_src, value_dst, name);
6528		}
6529
6530		{
6531			glw::GLenum name	  = GL_TEXTURE_WRAP_T;
6532			glw::GLint  value_src = GL_CLAMP_TO_EDGE;
6533			glw::GLint  value_dst = 11;
6534
6535			gl.textureParameteri(texture, name, value_src);
6536			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
6537
6538			gl.getTextureParameteriv(texture, name, &value_dst);
6539			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
6540
6541			is_ok &= CompareAndLog(value_src, value_dst, name);
6542		}
6543
6544		{
6545			glw::GLenum name	  = GL_TEXTURE_WRAP_R;
6546			glw::GLint  value_src = GL_CLAMP_TO_EDGE;
6547			glw::GLint  value_dst = 11;
6548
6549			gl.textureParameteriv(texture, name, &value_src);
6550			is_ok &= CheckErrorAndLog("glTextureParameteri", name);
6551
6552			gl.getTextureParameteriv(texture, name, &value_dst);
6553			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);
6554
6555			is_ok &= CompareAndLog(value_src, value_dst, name);
6556		}
6557	}
6558	catch (...)
6559	{
6560		is_ok	= false;
6561		is_error = true;
6562	}
6563
6564	/* Cleanup. */
6565	if (texture)
6566	{
6567		gl.deleteTextures(1, &texture);
6568	}
6569
6570	while (GL_NO_ERROR != gl.getError())
6571		;
6572
6573	/* Result's setup. */
6574	if (is_ok)
6575	{
6576		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
6577	}
6578	else
6579	{
6580		if (is_error)
6581		{
6582			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
6583		}
6584		else
6585		{
6586			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
6587		}
6588	}
6589
6590	return STOP;
6591}
6592
6593/** @brief Check for errors and log.
6594 *
6595 *  @param [in] fname     Name of the function (to be logged).
6596 *  @param [in] pname     Parameter name with which function was called.
6597 *
6598 *  @return True if no error, false otherwise.
6599 */
6600bool GetSetParameterTest::CheckErrorAndLog(const glw::GLchar* fname, glw::GLenum pname)
6601{
6602	/* Shortcut for GL functionality. */
6603	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6604
6605	/* Check errors. */
6606	glw::GLenum error;
6607
6608	if (GL_NO_ERROR != (error = gl.getError()))
6609	{
6610		m_context.getTestContext().getLog() << tcu::TestLog::Message << fname << " unexpectedly generated error "
6611											<< glu::getErrorStr(error) << " during test of pname "
6612											<< glu::getTextureParameterStr(pname) << ". Test fails."
6613											<< tcu::TestLog::EndMessage;
6614
6615		return false;
6616	}
6617
6618	return true;
6619}
6620
6621/** @brief Compare queried value of parameter with the expected vale.
6622 *
6623 *  @param [in] value_src           First value.
6624 *  @param [in] value_dst           Second value.
6625 *  @param [in] pname               Parameter name.
6626 *
6627 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
6628 */
6629bool GetSetParameterTest::CompareAndLog(glw::GLint value_src, glw::GLint value_dst, glw::GLenum pname)
6630{
6631	if (value_src != value_dst)
6632	{
6633		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Queried value of pname "
6634											<< glu::getTextureParameterStr(pname) << " is equal to " << value_dst
6635											<< ", however " << value_src << " was expected. Test fails."
6636											<< tcu::TestLog::EndMessage;
6637
6638		return false;
6639	}
6640
6641	return true;
6642}
6643
6644/** @brief Compare queried value of parameter with the expected vale.
6645 *
6646 *  @param [in] value_src           First value.
6647 *  @param [in] value_dst           Second value.
6648 *  @param [in] pname               Parameter name.
6649 *
6650 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
6651 */
6652bool GetSetParameterTest::CompareAndLog(glw::GLuint value_src, glw::GLuint value_dst, glw::GLenum pname)
6653{
6654	if (value_src != value_dst)
6655	{
6656		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Queried value of pname "
6657											<< glu::getTextureParameterStr(pname) << " is equal to " << value_dst
6658											<< ", however " << value_src << " was expected. Test fails."
6659											<< tcu::TestLog::EndMessage;
6660
6661		return false;
6662	}
6663
6664	return true;
6665}
6666
6667/** @brief Compare queried value of parameter with the expected vale.
6668 *
6669 *  @param [in] value_src           First value.
6670 *  @param [in] value_dst           Second value.
6671 *  @param [in] pname               Parameter name.
6672 *
6673 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
6674 */
6675bool GetSetParameterTest::CompareAndLog(glw::GLfloat value_src, glw::GLfloat value_dst, glw::GLenum pname)
6676{
6677	if (de::abs(value_src - value_dst) > 0.0125 /* Precision */)
6678	{
6679		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Queried value of pname "
6680											<< glu::getTextureParameterStr(pname) << " is equal to " << value_dst
6681											<< ", however " << value_src << " was expected. Test fails."
6682											<< tcu::TestLog::EndMessage;
6683
6684		return false;
6685	}
6686
6687	return true;
6688}
6689
6690/** @brief Compare queried value of parameter with the expected vale.
6691 *
6692 *  @param [in] value_src           First value.
6693 *  @param [in] value_dst           Second value.
6694 *  @param [in] pname               Parameter name.
6695 *
6696 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
6697 */
6698bool GetSetParameterTest::CompareAndLog(glw::GLint value_src[4], glw::GLint value_dst[4], glw::GLenum pname)
6699{
6700	if ((value_src[0] != value_dst[0]) || (value_src[1] != value_dst[1]) || (value_src[2] != value_dst[2]) ||
6701		(value_src[3] != value_dst[3]))
6702	{
6703		m_context.getTestContext().getLog()
6704			<< tcu::TestLog::Message << "Queried value of pname " << glu::getTextureParameterStr(pname)
6705			<< " is equal to [" << value_dst[0] << ", " << value_dst[1] << ", " << value_dst[2] << ", " << value_dst[3]
6706			<< "], however " << value_src[0] << ", " << value_src[1] << ", " << value_src[2] << ", " << value_src[3]
6707			<< "] was expected. Test fails." << tcu::TestLog::EndMessage;
6708
6709		return false;
6710	}
6711
6712	return true;
6713}
6714
6715/** @brief Compare queried value of parameter with the expected vale.
6716 *
6717 *  @param [in] value_src           First value.
6718 *  @param [in] value_dst           Second value.
6719 *  @param [in] pname               Parameter name.
6720 *
6721 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
6722 */
6723bool GetSetParameterTest::CompareAndLog(glw::GLuint value_src[4], glw::GLuint value_dst[4], glw::GLenum pname)
6724{
6725	if ((value_src[0] != value_dst[0]) || (value_src[1] != value_dst[1]) || (value_src[2] != value_dst[2]) ||
6726		(value_src[3] != value_dst[3]))
6727	{
6728		m_context.getTestContext().getLog()
6729			<< tcu::TestLog::Message << "Queried value of pname " << glu::getTextureParameterStr(pname)
6730			<< " is equal to [" << value_dst[0] << ", " << value_dst[1] << ", " << value_dst[2] << ", " << value_dst[3]
6731			<< "], however " << value_src[0] << ", " << value_src[1] << ", " << value_src[2] << ", " << value_src[3]
6732			<< "] was expected. Test fails." << tcu::TestLog::EndMessage;
6733
6734		return false;
6735	}
6736
6737	return true;
6738}
6739
6740/** @brief Compare queried value of parameter with the expected vale.
6741 *
6742 *  @param [in] value_src           First value.
6743 *  @param [in] value_dst           Second value.
6744 *  @param [in] pname               Parameter name.
6745 *
6746 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
6747 */
6748bool GetSetParameterTest::CompareAndLog(glw::GLfloat value_src[4], glw::GLfloat value_dst[4], glw::GLenum pname)
6749{
6750	if ((de::abs(value_src[0] - value_dst[0]) > 0.0125 /* Precision */) ||
6751		(de::abs(value_src[1] - value_dst[1]) > 0.0125 /* Precision */) ||
6752		(de::abs(value_src[2] - value_dst[2]) > 0.0125 /* Precision */) ||
6753		(de::abs(value_src[3] - value_dst[3]) > 0.0125 /* Precision */))
6754	{
6755		m_context.getTestContext().getLog()
6756			<< tcu::TestLog::Message << "Queried value of pname " << glu::getTextureParameterStr(pname)
6757			<< " is equal to [" << value_dst[0] << ", " << value_dst[1] << ", " << value_dst[2] << ", " << value_dst[3]
6758			<< "], however " << value_src[0] << ", " << value_src[1] << ", " << value_src[2] << ", " << value_src[3]
6759			<< "] was expected. Test fails." << tcu::TestLog::EndMessage;
6760
6761		return false;
6762	}
6763
6764	return true;
6765}
6766
6767/******************************** Defaults Test Implementation   ********************************/
6768
6769/** @brief Defaults Test constructor.
6770 *
6771 *  @param [in] context     OpenGL context.
6772 */
6773DefaultsTest::DefaultsTest(deqp::Context& context)
6774	: deqp::TestCase(context, "textures_defaults", "Texture Defaults Test")
6775{
6776	/* Intentionally left blank. */
6777}
6778
6779/** @brief Defaults Test cases.
6780 *
6781 *  @return Iteration result.
6782 */
6783tcu::TestNode::IterateResult DefaultsTest::iterate()
6784{
6785	/* Shortcut for GL functionality. */
6786	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6787
6788	/* Get context setup. */
6789	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
6790	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
6791
6792	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
6793	{
6794		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
6795
6796		return STOP;
6797	}
6798
6799	/* Running tests. */
6800	bool is_ok	= true;
6801	bool is_error = false;
6802
6803	/* Texture. */
6804	glw::GLuint texture = 0;
6805
6806	try
6807	{
6808		gl.createTextures(GL_TEXTURE_3D, 1, &texture);
6809		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
6810
6811		{
6812			glw::GLenum name	  = GL_DEPTH_STENCIL_TEXTURE_MODE;
6813			glw::GLint  value_ref = GL_DEPTH_COMPONENT;
6814			glw::GLint  value_dst = 0;
6815
6816			gl.getTextureParameteriv(texture, name, &value_dst);
6817			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6818
6819			is_ok &= CompareAndLog(value_ref, value_dst, name);
6820		}
6821
6822		{
6823			glw::GLenum name	  = GL_TEXTURE_BASE_LEVEL;
6824			glw::GLint  value_ref = 0;
6825			glw::GLint  value_dst = 1;
6826
6827			gl.getTextureParameteriv(texture, name, &value_dst);
6828			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6829
6830			is_ok &= CompareAndLog(value_ref, value_dst, name);
6831		}
6832
6833		{
6834			glw::GLenum  name		  = GL_TEXTURE_BORDER_COLOR;
6835			glw::GLfloat value_ref[4] = { 0.f, 0.f, 0.f, 0.f };
6836			glw::GLfloat value_dst[4] = {};
6837
6838			gl.getTextureParameterfv(texture, name, value_dst);
6839			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6840
6841			is_ok &= CompareAndLog(value_ref, value_dst, name);
6842		}
6843
6844		{
6845			glw::GLenum name	  = GL_TEXTURE_COMPARE_FUNC;
6846			glw::GLint  value_ref = GL_LEQUAL;
6847			glw::GLint  value_dst = 0;
6848
6849			gl.getTextureParameteriv(texture, name, &value_dst);
6850			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6851
6852			is_ok &= CompareAndLog(value_ref, value_dst, name);
6853		}
6854
6855		{
6856			glw::GLenum name	  = GL_TEXTURE_COMPARE_MODE;
6857			glw::GLint  value_ref = GL_NONE;
6858			glw::GLint  value_dst = 0;
6859
6860			gl.getTextureParameteriv(texture, name, &value_dst);
6861			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6862
6863			is_ok &= CompareAndLog(value_ref, value_dst, name);
6864		}
6865
6866		{
6867			glw::GLenum  name	  = GL_TEXTURE_LOD_BIAS;
6868			glw::GLfloat value_ref = 0.f;
6869			glw::GLfloat value_dst = 0.f;
6870
6871			gl.getTextureParameterfv(texture, name, &value_dst);
6872			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6873
6874			is_ok &= CompareAndLog(value_ref, value_dst, name);
6875		}
6876
6877		{
6878			glw::GLenum name	  = GL_TEXTURE_MIN_FILTER;
6879			glw::GLint  value_ref = GL_NEAREST_MIPMAP_LINEAR;
6880			glw::GLint  value_dst = 0;
6881
6882			gl.getTextureParameteriv(texture, name, &value_dst);
6883			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6884
6885			is_ok &= CompareAndLog(value_ref, value_dst, name);
6886		}
6887
6888		{
6889			glw::GLenum name	  = GL_TEXTURE_MAG_FILTER;
6890			glw::GLint  value_ref = GL_LINEAR;
6891			glw::GLint  value_dst = 0;
6892
6893			gl.getTextureParameteriv(texture, name, &value_dst);
6894			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6895
6896			is_ok &= CompareAndLog(value_ref, value_dst, name);
6897		}
6898
6899		{
6900			glw::GLenum name	  = GL_TEXTURE_MIN_LOD;
6901			glw::GLint  value_ref = -1000;
6902			glw::GLint  value_dst = 0;
6903
6904			gl.getTextureParameteriv(texture, name, &value_dst);
6905			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6906
6907			is_ok &= CompareAndLog(value_ref, value_dst, name);
6908		}
6909
6910		{
6911			glw::GLenum name	  = GL_TEXTURE_MAX_LOD;
6912			glw::GLint  value_ref = 1000;
6913			glw::GLint  value_dst = 0;
6914
6915			gl.getTextureParameteriv(texture, name, &value_dst);
6916			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6917
6918			is_ok &= CompareAndLog(value_ref, value_dst, name);
6919		}
6920
6921		{
6922			glw::GLenum name	  = GL_TEXTURE_MAX_LEVEL;
6923			glw::GLint  value_ref = 1000;
6924			glw::GLint  value_dst = 0;
6925
6926			gl.getTextureParameteriv(texture, name, &value_dst);
6927			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6928
6929			is_ok &= CompareAndLog(value_ref, value_dst, name);
6930		}
6931
6932		{
6933			glw::GLenum name	  = GL_TEXTURE_SWIZZLE_R;
6934			glw::GLint  value_ref = GL_RED;
6935			glw::GLint  value_dst = 0;
6936
6937			gl.getTextureParameteriv(texture, name, &value_dst);
6938			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6939
6940			is_ok &= CompareAndLog(value_ref, value_dst, name);
6941		}
6942
6943		{
6944			glw::GLenum name	  = GL_TEXTURE_SWIZZLE_G;
6945			glw::GLint  value_ref = GL_GREEN;
6946			glw::GLint  value_dst = 0;
6947
6948			gl.getTextureParameteriv(texture, name, &value_dst);
6949			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6950
6951			is_ok &= CompareAndLog(value_ref, value_dst, name);
6952		}
6953
6954		{
6955			glw::GLenum name	  = GL_TEXTURE_SWIZZLE_B;
6956			glw::GLint  value_ref = GL_BLUE;
6957			glw::GLint  value_dst = 0;
6958
6959			gl.getTextureParameteriv(texture, name, &value_dst);
6960			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6961
6962			is_ok &= CompareAndLog(value_ref, value_dst, name);
6963		}
6964
6965		{
6966			glw::GLenum name	  = GL_TEXTURE_SWIZZLE_A;
6967			glw::GLint  value_ref = GL_ALPHA;
6968			glw::GLint  value_dst = 0;
6969
6970			gl.getTextureParameteriv(texture, name, &value_dst);
6971			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6972
6973			is_ok &= CompareAndLog(value_ref, value_dst, name);
6974		}
6975
6976		{
6977			glw::GLenum name	  = GL_TEXTURE_WRAP_S;
6978			glw::GLint  value_ref = GL_REPEAT;
6979			glw::GLint  value_dst = 11;
6980
6981			gl.getTextureParameteriv(texture, name, &value_dst);
6982			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6983
6984			is_ok &= CompareAndLog(value_ref, value_dst, name);
6985		}
6986
6987		{
6988			glw::GLenum name	  = GL_TEXTURE_WRAP_T;
6989			glw::GLint  value_ref = GL_REPEAT;
6990			glw::GLint  value_dst = 11;
6991
6992			gl.getTextureParameteriv(texture, name, &value_dst);
6993			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
6994
6995			is_ok &= CompareAndLog(value_ref, value_dst, name);
6996		}
6997
6998		{
6999			glw::GLenum name	  = GL_TEXTURE_WRAP_R;
7000			glw::GLint  value_ref = GL_REPEAT;
7001			glw::GLint  value_dst = 11;
7002
7003			gl.getTextureParameteriv(texture, name, &value_dst);
7004			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");
7005
7006			is_ok &= CompareAndLog(value_ref, value_dst, name);
7007		}
7008	}
7009	catch (...)
7010	{
7011		is_ok	= false;
7012		is_error = true;
7013	}
7014
7015	/* Cleanup. */
7016	if (texture)
7017	{
7018		gl.deleteTextures(1, &texture);
7019	}
7020
7021	while (GL_NO_ERROR != gl.getError())
7022		;
7023
7024	/* Result's setup. */
7025	if (is_ok)
7026	{
7027		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
7028	}
7029	else
7030	{
7031		if (is_error)
7032		{
7033			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
7034		}
7035		else
7036		{
7037			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
7038		}
7039	}
7040
7041	return STOP;
7042}
7043
7044/** @brief Compare queried value of parameter with the expected vale.
7045 *
7046 *  @param [in] value_src           First value.
7047 *  @param [in] value_dst           Second value.
7048 *  @param [in] pname               Parameter name.
7049 *
7050 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
7051 */
7052bool DefaultsTest::CompareAndLog(glw::GLint value_ref, glw::GLint value_dst, glw::GLenum pname)
7053{
7054	if (value_ref != value_dst)
7055	{
7056		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Queried value of pname "
7057											<< glu::getTextureParameterStr(pname) << " is equal to " << value_dst
7058											<< ", however " << value_ref << " was expected. Test fails."
7059											<< tcu::TestLog::EndMessage;
7060
7061		return false;
7062	}
7063
7064	return true;
7065}
7066
7067/** @brief Compare queried value of parameter with the expected vale.
7068 *
7069 *  @param [in] value_src           First value.
7070 *  @param [in] value_dst           Second value.
7071 *  @param [in] pname               Parameter name.
7072 *
7073 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
7074 */
7075bool DefaultsTest::CompareAndLog(glw::GLuint value_ref, glw::GLuint value_dst, glw::GLenum pname)
7076{
7077	if (value_ref != value_dst)
7078	{
7079		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Queried value of pname "
7080											<< glu::getTextureParameterStr(pname) << " is equal to " << value_dst
7081											<< ", however " << value_ref << " was expected. Test fails."
7082											<< tcu::TestLog::EndMessage;
7083
7084		return false;
7085	}
7086
7087	return true;
7088}
7089
7090/** @brief Compare queried value of parameter with the expected vale.
7091 *
7092 *  @param [in] value_src           First value.
7093 *  @param [in] value_dst           Second value.
7094 *  @param [in] pname               Parameter name.
7095 *
7096 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
7097 */
7098bool DefaultsTest::CompareAndLog(glw::GLfloat value_ref, glw::GLfloat value_dst, glw::GLenum pname)
7099{
7100	if (de::abs(value_ref - value_dst) > 0.0125 /* Precision */)
7101	{
7102		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Queried value of pname "
7103											<< glu::getTextureParameterStr(pname) << " is equal to " << value_dst
7104											<< ", however " << value_ref << " was expected. Test fails."
7105											<< tcu::TestLog::EndMessage;
7106
7107		return false;
7108	}
7109
7110	return true;
7111}
7112
7113/** @brief Compare queried value of parameter with the expected vale.
7114 *
7115 *  @param [in] value_src           First value.
7116 *  @param [in] value_dst           Second value.
7117 *  @param [in] pname               Parameter name.
7118 *
7119 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
7120 */
7121bool DefaultsTest::CompareAndLog(glw::GLint value_ref[4], glw::GLint value_dst[4], glw::GLenum pname)
7122{
7123	if ((value_ref[0] != value_dst[0]) || (value_ref[1] != value_dst[1]) || (value_ref[2] != value_dst[2]) ||
7124		(value_ref[3] != value_dst[3]))
7125	{
7126		m_context.getTestContext().getLog()
7127			<< tcu::TestLog::Message << "Queried value of pname " << glu::getTextureParameterStr(pname)
7128			<< " is equal to [" << value_dst[0] << ", " << value_dst[1] << ", " << value_dst[2] << ", " << value_dst[3]
7129			<< "], however " << value_ref[0] << ", " << value_ref[1] << ", " << value_ref[2] << ", " << value_ref[3]
7130			<< "] was expected. Test fails." << tcu::TestLog::EndMessage;
7131
7132		return false;
7133	}
7134
7135	return true;
7136}
7137
7138/** @brief Compare queried value of parameter with the expected vale.
7139 *
7140 *  @param [in] value_src           First value.
7141 *  @param [in] value_dst           Second value.
7142 *  @param [in] pname               Parameter name.
7143 *
7144 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
7145 */
7146bool DefaultsTest::CompareAndLog(glw::GLuint value_ref[4], glw::GLuint value_dst[4], glw::GLenum pname)
7147{
7148	if ((value_ref[0] != value_dst[0]) || (value_ref[1] != value_dst[1]) || (value_ref[2] != value_dst[2]) ||
7149		(value_ref[3] != value_dst[3]))
7150	{
7151		m_context.getTestContext().getLog()
7152			<< tcu::TestLog::Message << "Queried value of pname " << glu::getTextureParameterStr(pname)
7153			<< " is equal to [" << value_dst[0] << ", " << value_dst[1] << ", " << value_dst[2] << ", " << value_dst[3]
7154			<< "], however " << value_ref[0] << ", " << value_ref[1] << ", " << value_ref[2] << ", " << value_ref[3]
7155			<< "] was expected. Test fails." << tcu::TestLog::EndMessage;
7156
7157		return false;
7158	}
7159
7160	return true;
7161}
7162
7163/** @brief Compare queried value of parameter with the expected vale.
7164 *
7165 *  @param [in] value_src           First value.
7166 *  @param [in] value_dst           Second value.
7167 *  @param [in] pname               Parameter name.
7168 *
7169 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
7170 */
7171bool DefaultsTest::CompareAndLog(glw::GLfloat value_ref[4], glw::GLfloat value_dst[4], glw::GLenum pname)
7172{
7173	if ((de::abs(value_ref[0] - value_dst[0]) > 0.0125 /* Precision */) ||
7174		(de::abs(value_ref[1] - value_dst[1]) > 0.0125 /* Precision */) ||
7175		(de::abs(value_ref[2] - value_dst[2]) > 0.0125 /* Precision */) ||
7176		(de::abs(value_ref[3] - value_dst[3]) > 0.0125 /* Precision */))
7177	{
7178		m_context.getTestContext().getLog()
7179			<< tcu::TestLog::Message << "Queried value of pname " << glu::getTextureParameterStr(pname)
7180			<< " is equal to [" << value_dst[0] << ", " << value_dst[1] << ", " << value_dst[2] << ", " << value_dst[3]
7181			<< "], however " << value_ref[0] << ", " << value_ref[1] << ", " << value_ref[2] << ", " << value_ref[3]
7182			<< "] was expected. Test fails." << tcu::TestLog::EndMessage;
7183
7184		return false;
7185	}
7186
7187	return true;
7188}
7189
7190/******************************** Generate Mipmap Test Implementation   ********************************/
7191
7192/** @brief Generate Mipmap Test constructor.
7193 *
7194 *  @param [in] context     OpenGL context.
7195 */
7196GenerateMipmapTest::GenerateMipmapTest(deqp::Context& context)
7197	: deqp::TestCase(context, "textures_generate_mipmaps", "Textures Generate Mipmap Test")
7198{
7199	/* Intentionally left blank. */
7200}
7201
7202/** @brief Generate Mipmap Test cases.
7203 *
7204 *  @return Iteration result.
7205 */
7206tcu::TestNode::IterateResult GenerateMipmapTest::iterate()
7207{
7208	/* Shortcut for GL functionality. */
7209	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7210
7211	/* Get context setup. */
7212	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
7213	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
7214
7215	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
7216	{
7217		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
7218
7219		return STOP;
7220	}
7221
7222	/* Running tests. */
7223	bool is_ok	= true;
7224	bool is_error = false;
7225
7226	/* Texture and cpu results storage. */
7227	glw::GLuint   texture = 0;
7228	glw::GLubyte* result  = DE_NULL;
7229
7230	try
7231	{
7232		/* Prepare texture. */
7233		gl.genTextures(1, &texture);
7234		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
7235
7236		gl.bindTexture(GL_TEXTURE_1D, texture);
7237		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
7238
7239		gl.texImage1D(GL_TEXTURE_1D, 0, GL_R8, s_texture_width, 0, GL_RED, GL_UNSIGNED_BYTE, s_texture_data);
7240		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");
7241
7242		/* Generate mipmaps with tested function. */
7243		gl.generateTextureMipmap(texture);
7244
7245		glw::GLenum error = GL_NO_ERROR;
7246
7247		if (GL_NO_ERROR != (error = gl.getError()))
7248		{
7249			m_context.getTestContext().getLog()
7250				<< tcu::TestLog::Message << "GenerateTextureMipmap unexpectedly generated error "
7251				<< glu::getErrorStr(error) << ". Test fails." << tcu::TestLog::EndMessage;
7252
7253			is_ok = false;
7254		}
7255
7256		/* Continue only if mipmaps has been generated. */
7257		if (is_ok)
7258		{
7259			result = new glw::GLubyte[s_texture_width];
7260
7261			if (DE_NULL == result)
7262			{
7263				throw 0;
7264			}
7265
7266			/* For each mipmap. */
7267			for (glw::GLuint i = 0, j = s_texture_width;
7268				 i < s_texture_width_log - 1 /* Do not test single pixel mipmap. */; ++i, j /= 2)
7269			{
7270				/* Check mipmap size. */
7271				glw::GLint mipmap_size = 0;
7272
7273				gl.getTexLevelParameteriv(GL_TEXTURE_1D, i, GL_TEXTURE_WIDTH, &mipmap_size);
7274				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
7275
7276				if (mipmap_size != (glw::GLint)j)
7277				{
7278					m_context.getTestContext().getLog()
7279						<< tcu::TestLog::Message
7280						<< "GenerateTextureMipmap unexpectedly generated mipmap with improper size. Mipmap size is "
7281						<< mipmap_size << ", but " << j << " was expected. Test fails." << tcu::TestLog::EndMessage;
7282
7283					is_ok = false;
7284
7285					break;
7286				}
7287
7288				/* Fetch data. */
7289				gl.getTexImage(GL_TEXTURE_1D, i, GL_RED, GL_UNSIGNED_BYTE, result);
7290				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexImage has failed");
7291
7292				/* Make comparison. */
7293				for (glw::GLuint k = 0; k < j - 1; ++k)
7294				{
7295					if (((glw::GLint)result[k + 1]) - ((glw::GLint)result[k]) < 0)
7296					{
7297						m_context.getTestContext().getLog() << tcu::TestLog::Message
7298															<< "GenerateTextureMipmap unexpectedly generated improper "
7299															   "mipmap (not descending). Test fails."
7300															<< tcu::TestLog::EndMessage;
7301
7302						is_ok = false;
7303
7304						break;
7305					}
7306				}
7307			}
7308		}
7309	}
7310	catch (...)
7311	{
7312		is_ok	= false;
7313		is_error = true;
7314	}
7315
7316	/* Cleanup. */
7317	if (texture)
7318	{
7319		gl.deleteTextures(1, &texture);
7320	}
7321
7322	if (DE_NULL != result)
7323	{
7324		delete[] result;
7325	}
7326
7327	while (GL_NO_ERROR != gl.getError())
7328		;
7329
7330	/* Result's setup. */
7331	if (is_ok)
7332	{
7333		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
7334	}
7335	else
7336	{
7337		if (is_error)
7338		{
7339			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
7340		}
7341		else
7342		{
7343			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
7344		}
7345	}
7346
7347	return STOP;
7348}
7349
7350/** Reference data. */
7351const glw::GLubyte GenerateMipmapTest::s_texture_data[] = {
7352	0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,
7353	22,  23,  24,  25,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,
7354	44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,  64,  65,
7355	66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,  86,  87,
7356	88,  89,  90,  91,  92,  93,  94,  95,  96,  97,  98,  99,  100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
7357	110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131,
7358	132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153,
7359	154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
7360	176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197,
7361	198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
7362	220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241,
7363	242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
7364};
7365
7366/** Reference data parameters. */
7367const glw::GLuint GenerateMipmapTest::s_texture_width	 = 256;
7368const glw::GLuint GenerateMipmapTest::s_texture_width_log = 8;
7369
7370/******************************** Bind Unit Test Implementation   ********************************/
7371
7372/** @brief Bind Unit Test constructor.
7373 *
7374 *  @param [in] context     OpenGL context.
7375 */
7376BindUnitTest::BindUnitTest(deqp::Context& context)
7377	: deqp::TestCase(context, "textures_bind_unit", "Textures Bind Unit Test")
7378	, m_po(0)
7379	, m_fbo(0)
7380	, m_rbo(0)
7381	, m_vao(0)
7382	, m_result(DE_NULL)
7383{
7384	m_to[0] = 0;
7385	m_to[1] = 0;
7386	m_to[2] = 0;
7387	m_to[3] = 0;
7388}
7389
7390/** @brief Bind Unit Test cases.
7391 *
7392 *  @return Iteration result.
7393 */
7394tcu::TestNode::IterateResult BindUnitTest::iterate()
7395{
7396	/* Get context setup. */
7397	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
7398	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
7399
7400	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
7401	{
7402		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
7403
7404		return STOP;
7405	}
7406
7407	/* Running tests. */
7408	bool is_ok	= true;
7409	bool is_error = false;
7410
7411	try
7412	{
7413		CreateProgram();
7414		CreateTextures();
7415		CreateFrambuffer();
7416		CreateVertexArray();
7417		is_ok &= Draw();
7418		is_ok &= Check();
7419	}
7420	catch (...)
7421	{
7422		is_ok	= false;
7423		is_error = true;
7424	}
7425
7426	/* Cleanup. */
7427	CleanAll();
7428
7429	/* Result's setup. */
7430	if (is_ok)
7431	{
7432		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
7433	}
7434	else
7435	{
7436		if (is_error)
7437		{
7438			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
7439		}
7440		else
7441		{
7442			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
7443		}
7444	}
7445
7446	return STOP;
7447}
7448
7449/** @brief Create test program.
7450 */
7451void BindUnitTest::CreateProgram()
7452{
7453	/* Shortcut for GL functionality */
7454	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7455
7456	struct Shader
7457	{
7458		glw::GLchar const* source;
7459		glw::GLenum const  type;
7460		glw::GLuint		   id;
7461	} shader[] = { { s_vertex_shader, GL_VERTEX_SHADER, 0 }, { s_fragment_shader, GL_FRAGMENT_SHADER, 0 } };
7462
7463	glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);
7464
7465	try
7466	{
7467		/* Create program. */
7468		m_po = gl.createProgram();
7469		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");
7470
7471		/* Shader compilation. */
7472
7473		for (glw::GLuint i = 0; i < shader_count; ++i)
7474		{
7475			if (DE_NULL != shader[i].source)
7476			{
7477				shader[i].id = gl.createShader(shader[i].type);
7478
7479				GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");
7480
7481				gl.attachShader(m_po, shader[i].id);
7482
7483				GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");
7484
7485				gl.shaderSource(shader[i].id, 1, &shader[i].source, NULL);
7486
7487				GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");
7488
7489				gl.compileShader(shader[i].id);
7490
7491				GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");
7492
7493				glw::GLint status = GL_FALSE;
7494
7495				gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
7496				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
7497
7498				if (GL_FALSE == status)
7499				{
7500					glw::GLint log_size = 0;
7501					gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
7502					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
7503
7504					glw::GLchar* log_text = new glw::GLchar[log_size];
7505
7506					gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);
7507
7508					m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation has failed.\n"
7509														<< "Shader type: " << glu::getShaderTypeStr(shader[i].type)
7510														<< "\n"
7511														<< "Shader compilation error log:\n"
7512														<< log_text << "\n"
7513														<< "Shader source code:\n"
7514														<< shader[i].source << "\n"
7515														<< tcu::TestLog::EndMessage;
7516
7517					delete[] log_text;
7518
7519					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");
7520
7521					throw 0;
7522				}
7523			}
7524		}
7525
7526		/* Link. */
7527		gl.linkProgram(m_po);
7528
7529		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
7530
7531		glw::GLint status = GL_FALSE;
7532
7533		gl.getProgramiv(m_po, GL_LINK_STATUS, &status);
7534
7535		if (GL_TRUE == status)
7536		{
7537			for (glw::GLuint i = 0; i < shader_count; ++i)
7538			{
7539				if (shader[i].id)
7540				{
7541					gl.detachShader(m_po, shader[i].id);
7542
7543					GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
7544				}
7545			}
7546		}
7547		else
7548		{
7549			glw::GLint log_size = 0;
7550
7551			gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);
7552
7553			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");
7554
7555			glw::GLchar* log_text = new glw::GLchar[log_size];
7556
7557			gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);
7558
7559			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
7560												<< log_text << "\n"
7561												<< tcu::TestLog::EndMessage;
7562
7563			delete[] log_text;
7564
7565			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");
7566
7567			throw 0;
7568		}
7569	}
7570	catch (...)
7571	{
7572		if (m_po)
7573		{
7574			gl.deleteProgram(m_po);
7575
7576			m_po = 0;
7577		}
7578	}
7579
7580	for (glw::GLuint i = 0; i < shader_count; ++i)
7581	{
7582		if (0 != shader[i].id)
7583		{
7584			gl.deleteShader(shader[i].id);
7585
7586			shader[i].id = 0;
7587		}
7588	}
7589
7590	if (0 == m_po)
7591	{
7592		throw 0;
7593	}
7594}
7595
7596/** @brief Create texture.
7597 */
7598void BindUnitTest::CreateTextures()
7599{
7600	/* Shortcut for GL functionality. */
7601	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7602
7603	/* Prepare texture. */
7604	gl.genTextures(4, m_to);
7605	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
7606
7607	/* Setup pixel sotre modes.*/
7608	gl.pixelStorei(GL_UNPACK_ALIGNMENT, sizeof(glw::GLubyte));
7609	GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed");
7610
7611	gl.pixelStorei(GL_PACK_ALIGNMENT, sizeof(glw::GLubyte));
7612	GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed");
7613
7614	/* Red texture. */
7615	gl.bindTexture(GL_TEXTURE_2D, m_to[0]);
7616	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
7617
7618	gl.texImage2D(GL_TEXTURE_2D, 0, GL_R8, s_texture_width, s_texture_height, 0, GL_RED, GL_UNSIGNED_BYTE,
7619				  s_texture_data_r);
7620	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");
7621
7622	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7623	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7624	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri call failed.");
7625
7626	/* Green texture. */
7627	gl.bindTexture(GL_TEXTURE_2D, m_to[1]);
7628	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
7629
7630	gl.texImage2D(GL_TEXTURE_2D, 0, GL_R8, s_texture_width, s_texture_height, 0, GL_RED, GL_UNSIGNED_BYTE,
7631				  s_texture_data_g);
7632	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");
7633
7634	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7635	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7636	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri call failed.");
7637
7638	/* Blue texture. */
7639	gl.bindTexture(GL_TEXTURE_2D, m_to[2]);
7640	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
7641
7642	gl.texImage2D(GL_TEXTURE_2D, 0, GL_R8, s_texture_width, s_texture_height, 0, GL_RED, GL_UNSIGNED_BYTE,
7643				  s_texture_data_b);
7644	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");
7645
7646	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7647	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7648	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri call failed.");
7649
7650	/* Alpha texture. */
7651	gl.bindTexture(GL_TEXTURE_2D, m_to[3]);
7652	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
7653
7654	gl.texImage2D(GL_TEXTURE_2D, 0, GL_R8, s_texture_width, s_texture_height, 0, GL_RED, GL_UNSIGNED_BYTE,
7655				  s_texture_data_a);
7656	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");
7657
7658	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7659	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7660	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri call failed.");
7661}
7662
7663/** @brief Create framebuffer.
7664 */
7665void BindUnitTest::CreateFrambuffer()
7666{
7667	/* Shortcut for GL functionality. */
7668	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7669
7670	/* Prepare framebuffer. */
7671	gl.genFramebuffers(1, &m_fbo);
7672	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
7673
7674	gl.genRenderbuffers(1, &m_rbo);
7675	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
7676
7677	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
7678	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
7679
7680	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo);
7681	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
7682
7683	gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, s_texture_width, s_texture_height);
7684	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed.");
7685
7686	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo);
7687	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed.");
7688
7689	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
7690	{
7691		throw 0;
7692	}
7693
7694	gl.viewport(0, 0, s_texture_width, s_texture_height);
7695	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
7696
7697	/* Clear framebuffer's content. */
7698	gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f);
7699	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");
7700
7701	gl.clear(GL_COLOR_BUFFER_BIT);
7702	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed.");
7703}
7704
7705/** @brief Create vertex array object.
7706 */
7707void BindUnitTest::CreateVertexArray()
7708{
7709	/* Shortcut for GL functionality. */
7710	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7711
7712	gl.genVertexArrays(1, &m_vao);
7713	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call has failed.");
7714
7715	gl.bindVertexArray(m_vao);
7716	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call has failed.");
7717}
7718
7719bool BindUnitTest::Draw()
7720{
7721	/* Shortcut for GL functionality. */
7722	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7723
7724	/* Setup program. */
7725	gl.useProgram(m_po);
7726	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call has failed.");
7727
7728	/* Bind textures to proper units and setup program's samplers. */
7729	for (glw::GLuint i = 0; i < 4; ++i)
7730	{
7731		/* Tested binding funcion. */
7732		gl.bindTextureUnit(i, m_to[i]);
7733
7734		/* Check for errors. */
7735		glw::GLenum error = GL_NO_ERROR;
7736
7737		if (GL_NO_ERROR != (error = gl.getError()))
7738		{
7739			m_context.getTestContext().getLog()
7740				<< tcu::TestLog::Message << "BindTextureUnit unexpectedly generated error " << glu::getErrorStr(error)
7741				<< " when binding texture " << m_to[i] << " to texture unit " << i << ". Test fails."
7742				<< tcu::TestLog::EndMessage;
7743
7744			return false;
7745		}
7746
7747		/* Sampler setup. */
7748		gl.uniform1i(gl.getUniformLocation(m_po, s_fragment_shader_samplers[i]), i);
7749		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation or glUniform1i call has failed.");
7750	}
7751
7752	/* Draw call. */
7753	gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
7754	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call has failed.");
7755
7756	return true;
7757}
7758
7759/** @brief Compare results with reference.
7760 *
7761 *  @return True if equal, false otherwise.
7762 */
7763bool BindUnitTest::Check()
7764{
7765	/* Shortcut for GL functionality. */
7766	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7767
7768	/* Setup storage for results. */
7769	m_result = new glw::GLubyte[s_texture_count_rgba];
7770
7771	/* Setup pixel sotre modes.*/
7772	gl.pixelStorei(GL_UNPACK_ALIGNMENT, sizeof(glw::GLubyte));
7773	GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed");
7774
7775	gl.pixelStorei(GL_PACK_ALIGNMENT, sizeof(glw::GLubyte));
7776	GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed");
7777
7778	/* Query framebuffer's image. */
7779	gl.readPixels(0, 0, s_texture_width, s_texture_height, GL_RGBA, GL_UNSIGNED_BYTE, m_result);
7780	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call has failed.");
7781
7782	/* Compare values with reference. */
7783	for (glw::GLuint i = 0; i < s_texture_count_rgba; ++i)
7784	{
7785		if (s_texture_data_rgba[i] != m_result[i])
7786		{
7787			m_context.getTestContext().getLog()
7788				<< tcu::TestLog::Message << "Framebuffer data " << DataToString(s_texture_count_rgba, m_result)
7789				<< " does not match the reference values " << DataToString(s_texture_count_rgba, s_texture_data_rgba)
7790				<< "." << tcu::TestLog::EndMessage;
7791
7792			return false;
7793		}
7794	}
7795
7796	return true;
7797}
7798
7799/** @brief Clean GL objects, test variables and GL errors.
7800 */
7801void BindUnitTest::CleanAll()
7802{
7803	/* Shortcut for GL functionality. */
7804	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7805
7806	/* Release GL objects. */
7807	if (m_po)
7808	{
7809		gl.useProgram(0);
7810
7811		gl.deleteProgram(m_po);
7812
7813		m_po = 0;
7814	}
7815
7816	if (m_to[0] || m_to[1] || m_to[2] || m_to[3])
7817	{
7818		gl.deleteTextures(4, m_to);
7819
7820		m_to[0] = 0;
7821		m_to[1] = 0;
7822		m_to[2] = 0;
7823		m_to[3] = 0;
7824	}
7825
7826	if (m_fbo)
7827	{
7828		gl.deleteFramebuffers(1, &m_fbo);
7829
7830		m_fbo = 0;
7831	}
7832
7833	if (m_rbo)
7834	{
7835		gl.deleteRenderbuffers(1, &m_rbo);
7836
7837		m_rbo = 0;
7838	}
7839
7840	/* Release heap. */
7841	if (DE_NULL != m_result)
7842	{
7843		delete[] m_result;
7844	}
7845
7846	/* Erros clean-up. */
7847	while (GL_NO_ERROR != gl.getError())
7848		;
7849}
7850
7851/** @brief Convert raw data into string for logging purposes.
7852 *
7853 *  @param [in] count      Count of the data.
7854 *  @param [in] data       Raw data.
7855 *
7856 *  @return String representation of data.
7857 */
7858std::string BindUnitTest::DataToString(glw::GLuint count, const glw::GLubyte data[])
7859{
7860	std::string data_str = "[";
7861
7862	for (glw::GLuint i = 0; i < count; ++i)
7863	{
7864		std::stringstream int_sstream;
7865
7866		int_sstream << unsigned(data[i]);
7867
7868		data_str.append(int_sstream.str());
7869
7870		if (i + 1 < count)
7871		{
7872			data_str.append(", ");
7873		}
7874		else
7875		{
7876			data_str.append("]");
7877		}
7878	}
7879
7880	return data_str;
7881}
7882
7883/** Reference data and parameters. */
7884const glw::GLubyte BindUnitTest::s_texture_data_r[]	= { 0, 4, 8, 12, 16, 20 };
7885const glw::GLubyte BindUnitTest::s_texture_data_g[]	= { 1, 5, 9, 13, 17, 21 };
7886const glw::GLubyte BindUnitTest::s_texture_data_b[]	= { 2, 6, 10, 14, 18, 22 };
7887const glw::GLubyte BindUnitTest::s_texture_data_a[]	= { 3, 7, 11, 15, 19, 23 };
7888const glw::GLubyte BindUnitTest::s_texture_data_rgba[] = { 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11,
7889														   12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 };
7890const glw::GLuint BindUnitTest::s_texture_width		 = 2;
7891const glw::GLuint BindUnitTest::s_texture_height	 = 3;
7892const glw::GLuint BindUnitTest::s_texture_count_rgba = sizeof(s_texture_data_rgba) / sizeof(s_texture_data_rgba[0]);
7893
7894/* Vertex shader source code. */
7895const glw::GLchar* BindUnitTest::s_vertex_shader = "#version 450\n"
7896												   "\n"
7897												   "void main()\n"
7898												   "{\n"
7899												   "    switch(gl_VertexID)\n"
7900												   "    {\n"
7901												   "        case 0:\n"
7902												   "            gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
7903												   "            break;\n"
7904												   "        case 1:\n"
7905												   "            gl_Position = vec4( 1.0, 1.0, 0.0, 1.0);\n"
7906												   "            break;\n"
7907												   "        case 2:\n"
7908												   "            gl_Position = vec4(-1.0,-1.0, 0.0, 1.0);\n"
7909												   "            break;\n"
7910												   "        case 3:\n"
7911												   "            gl_Position = vec4( 1.0,-1.0, 0.0, 1.0);\n"
7912												   "            break;\n"
7913												   "    }\n"
7914												   "}\n";
7915
7916/* Fragment shader source program. */
7917const glw::GLchar* BindUnitTest::s_fragment_shader =
7918	"#version 450\n"
7919	"\n"
7920	"layout(pixel_center_integer) in vec4 gl_FragCoord;\n"
7921	"\n"
7922	"uniform sampler2D texture_input_r;\n"
7923	"uniform sampler2D texture_input_g;\n"
7924	"uniform sampler2D texture_input_b;\n"
7925	"uniform sampler2D texture_input_a;\n"
7926	"\n"
7927	"out     vec4      color_output;\n"
7928	"\n"
7929	"void main()\n"
7930	"{\n"
7931	"    color_output = vec4(texelFetch(texture_input_r, ivec2(gl_FragCoord.xy), 0).r,\n"
7932	"                        texelFetch(texture_input_g, ivec2(gl_FragCoord.xy), 0).r,\n"
7933	"                        texelFetch(texture_input_b, ivec2(gl_FragCoord.xy), 0).r,\n"
7934	"                        texelFetch(texture_input_a, ivec2(gl_FragCoord.xy), 0).r);\n"
7935	"}\n";
7936
7937const glw::GLchar* BindUnitTest::s_fragment_shader_samplers[4] = { "texture_input_r", "texture_input_g",
7938																   "texture_input_b", "texture_input_a" };
7939
7940/******************************** Get Image Test Implementation   ********************************/
7941
7942/** @brief Get Image Test constructor.
7943 *
7944 *  @param [in] context     OpenGL context.
7945 */
7946GetImageTest::GetImageTest(deqp::Context& context)
7947	: deqp::TestCase(context, "textures_get_image", "Textures Get Image Test")
7948{
7949	/* Intentionally left blank */
7950}
7951
7952/** Reference data. */
7953const glw::GLubyte GetImageTest::s_texture_data[] = { 0x0,  0x0,  0x0,  0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3,
7954													  0xff, 0xff, 0xff, 0xff, 0xff, 0x88, 0x0,  0x15, 0xff, 0xed, 0x1c,
7955													  0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0,  0xff, 0xc8,
7956													  0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff,
7957													  0xb5, 0xe6, 0x1d, 0xff, 0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc,
7958													  0xff, 0x0,  0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff };
7959
7960/** Reference data (compressed). */
7961const glw::GLubyte GetImageTest::s_texture_data_compressed[] = { 0x90, 0x2b, 0x8f, 0x0f, 0xfe, 0x0f, 0x98, 0x99,
7962																 0x99, 0x99, 0x59, 0x8f, 0x8c, 0xa6, 0xb7, 0x71 };
7963
7964/** Reference data parameters. */
7965const glw::GLuint GetImageTest::s_texture_width			  = 4;
7966const glw::GLuint GetImageTest::s_texture_height		  = 4;
7967const glw::GLuint GetImageTest::s_texture_size			  = sizeof(s_texture_data);
7968const glw::GLuint GetImageTest::s_texture_size_compressed = sizeof(s_texture_data_compressed);
7969const glw::GLuint GetImageTest::s_texture_count			  = s_texture_size / sizeof(s_texture_data[0]);
7970const glw::GLuint GetImageTest::s_texture_count_compressed =
7971	s_texture_size_compressed / sizeof(s_texture_data_compressed[0]);
7972
7973/** @brief Get Image Test cases.
7974 *
7975 *  @return Iteration result.
7976 */
7977tcu::TestNode::IterateResult GetImageTest::iterate()
7978{
7979	/* Shortcut for GL functionality. */
7980	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7981
7982	/* Get context setup. */
7983	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
7984	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
7985
7986	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
7987	{
7988		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
7989
7990		return STOP;
7991	}
7992
7993	/* Running tests. */
7994	bool is_ok	= true;
7995	bool is_error = false;
7996
7997	/* Objects. */
7998	glw::GLuint  texture									   = 0;
7999	glw::GLubyte result[s_texture_count]					   = {};
8000	glw::GLubyte result_compressed[s_texture_count_compressed] = {};
8001
8002	try
8003	{
8004		/* Uncompressed case. */
8005		{
8006			/* Texture initiation. */
8007			gl.genTextures(1, &texture);
8008			GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
8009
8010			gl.bindTexture(GL_TEXTURE_2D, texture);
8011			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
8012
8013			gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, s_texture_width, s_texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
8014						  s_texture_data);
8015			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");
8016
8017			/* Quering image with tested function. */
8018			gl.getTextureImage(texture, 0, GL_RGBA, GL_UNSIGNED_BYTE, sizeof(result), result);
8019
8020			/* Check for errors. */
8021			glw::GLenum error = GL_NO_ERROR;
8022
8023			if (GL_NO_ERROR != (error = gl.getError()))
8024			{
8025				m_context.getTestContext().getLog()
8026					<< tcu::TestLog::Message << "GetTextureImage unexpectedly generated error "
8027					<< glu::getErrorStr(error) << ". Test fails." << tcu::TestLog::EndMessage;
8028
8029				is_ok = false;
8030			}
8031			else
8032			{
8033				/* No error, so compare images. */
8034				for (glw::GLuint i = 0; i < s_texture_count; ++i)
8035				{
8036					if (s_texture_data[i] != result[i])
8037					{
8038						m_context.getTestContext().getLog() << tcu::TestLog::Message << "GetTextureImage returned "
8039															<< DataToString(s_texture_count, result) << ", but "
8040															<< DataToString(s_texture_count, s_texture_data)
8041															<< " was expected. Test fails." << tcu::TestLog::EndMessage;
8042
8043						is_ok = false;
8044
8045						break;
8046					}
8047				}
8048			}
8049		}
8050
8051		/* Clean up texture .*/
8052		gl.deleteTextures(1, &texture);
8053		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
8054
8055		texture = 0;
8056
8057		/* Compressed case. */
8058		{
8059			/* Texture initiation. */
8060			gl.genTextures(1, &texture);
8061			GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
8062
8063			gl.bindTexture(GL_TEXTURE_2D, texture);
8064			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
8065
8066			gl.compressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_BPTC_UNORM, s_texture_width, s_texture_height,
8067									0, s_texture_size_compressed, s_texture_data_compressed);
8068			GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage2D has failed");
8069
8070			/* Quering image with tested function. */
8071			gl.getCompressedTextureImage(texture, 0, s_texture_count_compressed * sizeof(result_compressed[0]),
8072										 result_compressed);
8073
8074			/* Check for errors. */
8075			glw::GLenum error = GL_NO_ERROR;
8076
8077			if (GL_NO_ERROR != (error = gl.getError()))
8078			{
8079				m_context.getTestContext().getLog()
8080					<< tcu::TestLog::Message << "GetCompressedTextureImage unexpectedly generated error "
8081					<< glu::getErrorStr(error) << ". Test fails." << tcu::TestLog::EndMessage;
8082
8083				is_ok = false;
8084			}
8085			else
8086			{
8087				/* No error, so compare images. */
8088				for (glw::GLuint i = 0; i < s_texture_count_compressed; ++i)
8089				{
8090					if (s_texture_data_compressed[i] != result_compressed[i])
8091					{
8092						m_context.getTestContext().getLog()
8093							<< tcu::TestLog::Message << "GetCompressedTextureImage returned "
8094							<< DataToString(s_texture_count_compressed, result_compressed) << ", but "
8095							<< DataToString(s_texture_count_compressed, s_texture_data_compressed)
8096							<< " was expected. Test fails." << tcu::TestLog::EndMessage;
8097
8098						is_ok = false;
8099
8100						break;
8101					}
8102				}
8103			}
8104		}
8105	}
8106	catch (...)
8107	{
8108		is_ok	= false;
8109		is_error = true;
8110	}
8111
8112	/* Cleanup. */
8113	if (texture)
8114	{
8115		gl.deleteTextures(1, &texture);
8116	}
8117
8118	/* Result's setup. */
8119	if (is_ok)
8120	{
8121		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
8122	}
8123	else
8124	{
8125		if (is_error)
8126		{
8127			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
8128		}
8129		else
8130		{
8131			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
8132		}
8133	}
8134
8135	return STOP;
8136}
8137
8138/** @brief Convert raw data into string for logging purposes.
8139 *
8140 *  @param [in] count      Count of the data.
8141 *  @param [in] data       Raw data.
8142 *
8143 *  @return String representation of data.
8144 */
8145std::string GetImageTest::DataToString(glw::GLuint count, const glw::GLubyte data[])
8146{
8147	std::string data_str = "[";
8148
8149	for (glw::GLuint i = 0; i < count; ++i)
8150	{
8151		std::stringstream int_sstream;
8152
8153		int_sstream << unsigned(data[i]);
8154
8155		data_str.append(int_sstream.str());
8156
8157		if (i + 1 < count)
8158		{
8159			data_str.append(", ");
8160		}
8161		else
8162		{
8163			data_str.append("]");
8164		}
8165	}
8166
8167	return data_str;
8168}
8169
8170/******************************** Get Level Parameter Test Implementation   ********************************/
8171
8172/** @brief Get Level Parameter Test constructor.
8173 *
8174 *  @param [in] context     OpenGL context.
8175 */
8176GetLevelParameterTest::GetLevelParameterTest(deqp::Context& context)
8177	: deqp::TestCase(context, "textures_get_level_parameter", "Textures Get Level Parameter Test")
8178{
8179	/* Intentionally left blank */
8180}
8181
8182/** Reference data. */
8183const glw::GLubyte GetLevelParameterTest::s_texture_data[] = {
8184	0x0,  0x0,  0x0,  0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
8185	0x88, 0x0,  0x15, 0xff, 0xed, 0x1c, 0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0,  0xff,
8186	0xc8, 0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0xff,
8187	0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc, 0xff, 0x0,  0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff,
8188
8189	0x0,  0x0,  0x0,  0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
8190	0x88, 0x0,  0x15, 0xff, 0xed, 0x1c, 0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0,  0xff,
8191	0xc8, 0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0xff,
8192	0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc, 0xff, 0x0,  0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff,
8193
8194	0x0,  0x0,  0x0,  0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
8195	0x88, 0x0,  0x15, 0xff, 0xed, 0x1c, 0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0,  0xff,
8196	0xc8, 0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0xff,
8197	0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc, 0xff, 0x0,  0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff,
8198
8199	0x0,  0x0,  0x0,  0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
8200	0x88, 0x0,  0x15, 0xff, 0xed, 0x1c, 0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0,  0xff,
8201	0xc8, 0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0xff,
8202	0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc, 0xff, 0x0,  0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff
8203};
8204
8205/** Reference data parameters. */
8206const glw::GLuint GetLevelParameterTest::s_texture_width  = 4;
8207const glw::GLuint GetLevelParameterTest::s_texture_height = 4;
8208const glw::GLuint GetLevelParameterTest::s_texture_depth  = 4;
8209
8210/** @brief Get Level Parameter Test cases.
8211 *
8212 *  @return Iteration result.
8213 */
8214tcu::TestNode::IterateResult GetLevelParameterTest::iterate()
8215{
8216	/* Shortcut for GL functionality. */
8217	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8218
8219	/* Get context setup. */
8220	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
8221	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
8222
8223	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
8224	{
8225		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
8226
8227		return STOP;
8228	}
8229
8230	/* Running tests. */
8231	bool is_ok	= true;
8232	bool is_error = false;
8233
8234	/* Objects. */
8235	glw::GLuint texture = 0;
8236
8237	try
8238	{
8239		/* Texture initiation. */
8240		gl.genTextures(1, &texture);
8241		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
8242
8243		gl.bindTexture(GL_TEXTURE_3D, texture);
8244		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
8245
8246		gl.texImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, s_texture_width, s_texture_height, s_texture_depth, 0, GL_RGBA,
8247					  GL_UNSIGNED_BYTE, s_texture_data);
8248		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");
8249
8250		gl.texImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, s_texture_width / 2, s_texture_height / 2, s_texture_depth / 2, 0,
8251					  GL_RGBA, GL_UNSIGNED_BYTE, s_texture_data);
8252		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");
8253
8254		static const glw::GLenum pnames[] = {
8255			GL_TEXTURE_WIDTH,	  GL_TEXTURE_HEIGHT,	 GL_TEXTURE_DEPTH,		 GL_TEXTURE_INTERNAL_FORMAT,
8256			GL_TEXTURE_RED_TYPE,   GL_TEXTURE_GREEN_TYPE, GL_TEXTURE_BLUE_TYPE,  GL_TEXTURE_ALPHA_TYPE,
8257			GL_TEXTURE_DEPTH_TYPE, GL_TEXTURE_RED_SIZE,   GL_TEXTURE_GREEN_SIZE, GL_TEXTURE_BLUE_SIZE,
8258			GL_TEXTURE_ALPHA_SIZE, GL_TEXTURE_DEPTH_SIZE, GL_TEXTURE_COMPRESSED
8259		};
8260		static const glw::GLuint pnames_count = sizeof(pnames) / sizeof(pnames[0]);
8261
8262		/* Test GetTextureLevelParameteriv. */
8263		for (glw::GLuint i = 0; i < 2 /* levels */; ++i)
8264		{
8265			for (glw::GLuint j = 0; j < pnames_count; ++j)
8266			{
8267				glw::GLint result_legacy = 0;
8268				glw::GLint result_dsa	= 0;
8269
8270				/* Quering reference value. */
8271				gl.getTexLevelParameteriv(GL_TEXTURE_3D, i, pnames[j], &result_legacy);
8272				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
8273
8274				/* Quering using DSA function. */
8275				gl.getTextureLevelParameteriv(texture, i, pnames[j], &result_dsa);
8276
8277				/* Check for errors. */
8278				glw::GLenum error = GL_NO_ERROR;
8279
8280				if (GL_NO_ERROR != (error = gl.getError()))
8281				{
8282					m_context.getTestContext().getLog()
8283						<< tcu::TestLog::Message << "GetTextureLevelParameteriv unexpectedly generated error "
8284						<< glu::getErrorStr(error) << ". Test fails." << tcu::TestLog::EndMessage;
8285
8286					is_ok = false;
8287				}
8288				else
8289				{
8290					/* Compare values. */
8291					if (result_legacy != result_dsa)
8292					{
8293						m_context.getTestContext().getLog()
8294							<< tcu::TestLog::Message << "For parameter name "
8295							<< glu::getTextureLevelParameterStr(pnames[j]) << " GetTextureLevelParameteriv returned "
8296							<< result_dsa << ", but reference value (queried using GetTexLevelParameteriv) was "
8297							<< result_legacy << ". Test fails." << tcu::TestLog::EndMessage;
8298
8299						is_ok = false;
8300					}
8301				}
8302			}
8303		}
8304
8305		/* Test GetTextureLevelParameterfv. */
8306		for (glw::GLuint i = 0; i < 2 /* levels */; ++i)
8307		{
8308			for (glw::GLuint j = 0; j < pnames_count; ++j)
8309			{
8310				glw::GLfloat result_legacy = 0.f;
8311				glw::GLfloat result_dsa	= 0.f;
8312
8313				/* Quering reference value. */
8314				gl.getTexLevelParameterfv(GL_TEXTURE_3D, i, pnames[j], &result_legacy);
8315				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameterfv has failed");
8316
8317				/* Quering using DSA function. */
8318				gl.getTextureLevelParameterfv(texture, i, pnames[j], &result_dsa);
8319
8320				/* Check for errors. */
8321				glw::GLenum error = GL_NO_ERROR;
8322
8323				if (GL_NO_ERROR != (error = gl.getError()))
8324				{
8325					m_context.getTestContext().getLog()
8326						<< tcu::TestLog::Message << "GetTextureLevelParameterfv unexpectedly generated error "
8327						<< glu::getErrorStr(error) << ". Test fails." << tcu::TestLog::EndMessage;
8328
8329					is_ok = false;
8330				}
8331				else
8332				{
8333					/* Compare values. */
8334					if (de::abs(result_legacy - result_dsa) > 0.125 /* Precision. */)
8335					{
8336						m_context.getTestContext().getLog()
8337							<< tcu::TestLog::Message << "For parameter name "
8338							<< glu::getTextureLevelParameterStr(pnames[j]) << " GetTextureLevelParameterfv returned "
8339							<< result_dsa << ", but reference value (queried using GetTexLevelParameterfv) was "
8340							<< result_legacy << ". Test fails." << tcu::TestLog::EndMessage;
8341
8342						is_ok = false;
8343					}
8344				}
8345			}
8346		}
8347	}
8348	catch (...)
8349	{
8350		is_ok	= false;
8351		is_error = true;
8352	}
8353
8354	/* Cleanup. */
8355	if (texture)
8356	{
8357		gl.deleteTextures(1, &texture);
8358	}
8359
8360	while (GL_NO_ERROR != gl.getError())
8361		;
8362
8363	/* Result's setup. */
8364	if (is_ok)
8365	{
8366		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
8367	}
8368	else
8369	{
8370		if (is_error)
8371		{
8372			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
8373		}
8374		else
8375		{
8376			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
8377		}
8378	}
8379
8380	return STOP;
8381}
8382
8383/*********************************** Errors Utility Class *****************************************************/
8384
8385/** @brief Check for errors and log.
8386 *
8387 *  @param [in] context             Test's context.
8388 *  @param [in] expected_error      Expected error value.
8389 *  @param [in] function_name       Name of the function (to be logged).
8390 *  @param [in] log                 Log message.
8391 *
8392 *  @return True if error is equal to expected, false otherwise.
8393 */
8394bool ErrorsUtilities::CheckErrorAndLog(deqp::Context& context, glw::GLuint expected_error,
8395									   const glw::GLchar* function_name, const glw::GLchar* log)
8396{
8397	/* Shortcut for GL functionality. */
8398	const glw::Functions& gl = context.getRenderContext().getFunctions();
8399
8400	/* Check error. */
8401	glw::GLenum error = GL_NO_ERROR;
8402
8403	if (expected_error != (error = gl.getError()))
8404	{
8405		context.getTestContext().getLog() << tcu::TestLog::Message << function_name << " generated error "
8406										  << glu::getErrorStr(error) << " but, " << glu::getErrorStr(expected_error)
8407										  << " was expected if " << log << tcu::TestLog::EndMessage;
8408
8409		return false;
8410	}
8411
8412	return true;
8413}
8414
8415/******************************** Creation Errors Test Implementation   ********************************/
8416
8417/** @brief Creation Errors Test constructor.
8418 *
8419 *  @param [in] context     OpenGL context.
8420 */
8421CreationErrorsTest::CreationErrorsTest(deqp::Context& context)
8422	: deqp::TestCase(context, "textures_creation_errors", "Texture Objects Creation Errors Test")
8423{
8424	/* Intentionally left blank. */
8425}
8426
8427/** @brief Iterate Creation Errors Test cases.
8428 *
8429 *  @return Iteration result.
8430 */
8431tcu::TestNode::IterateResult CreationErrorsTest::iterate()
8432{
8433	/* Shortcut for GL functionality. */
8434	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8435
8436	/* Get context setup. */
8437	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
8438	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
8439
8440	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
8441	{
8442		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
8443
8444		return STOP;
8445	}
8446
8447	/* Running tests. */
8448	bool is_ok	= true;
8449	bool is_error = false;
8450
8451	/* Textures' objects */
8452	glw::GLuint texture = 0;
8453
8454	try
8455	{
8456		/* Not a target test. */
8457		gl.createTextures(NotATarget(), 1, &texture);
8458		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glCreateTextures",
8459								  "target is not one of the allowable values.");
8460
8461		if (texture)
8462		{
8463			gl.deleteTextures(1, &texture);
8464
8465			texture = 0;
8466		}
8467
8468		/* Negative number of textures. */
8469		gl.createTextures(GL_TEXTURE_2D, -1, &texture);
8470		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCreateTextures", "n is negative.");
8471	}
8472	catch (...)
8473	{
8474		is_ok	= false;
8475		is_error = true;
8476	}
8477
8478	/* Cleanup. */
8479	if (texture)
8480	{
8481		gl.deleteTextures(1, &texture);
8482	}
8483
8484	/* Errors clean up. */
8485	while (gl.getError())
8486		;
8487
8488	/* Result's setup. */
8489	if (is_ok)
8490	{
8491		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
8492	}
8493	else
8494	{
8495		if (is_error)
8496		{
8497			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
8498		}
8499		else
8500		{
8501			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
8502		}
8503	}
8504
8505	return STOP;
8506}
8507
8508/** @brief Function retruns enum which is not a texture target.
8509 */
8510glw::GLenum CreationErrorsTest::NotATarget()
8511{
8512	static const glw::GLenum texture_targets[] = { GL_TEXTURE_1D,
8513												   GL_TEXTURE_2D,
8514												   GL_TEXTURE_3D,
8515												   GL_TEXTURE_1D_ARRAY,
8516												   GL_TEXTURE_2D_ARRAY,
8517												   GL_TEXTURE_RECTANGLE,
8518												   GL_TEXTURE_CUBE_MAP,
8519												   GL_TEXTURE_CUBE_MAP_ARRAY,
8520												   GL_TEXTURE_BUFFER,
8521												   GL_TEXTURE_2D_MULTISAMPLE,
8522												   GL_TEXTURE_2D_MULTISAMPLE_ARRAY };
8523
8524	glw::GLenum not_a_target = 0;
8525	bool		is_target	= true;
8526
8527	while (is_target)
8528	{
8529		not_a_target++;
8530
8531		is_target = false;
8532
8533		for (glw::GLuint i = 0; i < sizeof(texture_targets) / sizeof(texture_targets[0]); ++i)
8534		{
8535			if (texture_targets[i] == not_a_target)
8536			{
8537				is_target = true;
8538				break;
8539			}
8540		}
8541	}
8542
8543	return not_a_target;
8544}
8545
8546/******************************** Texture Buffer Errors Test Implementation   ********************************/
8547
8548/** @brief Texture Buffer Errors Test constructor.
8549 *
8550 *  @param [in] context     OpenGL context.
8551 */
8552BufferErrorsTest::BufferErrorsTest(deqp::Context& context)
8553	: deqp::TestCase(context, "textures_buffer_errors", "Texture Buffer Errors Test")
8554{
8555	/* Intentionally left blank. */
8556}
8557
8558/** @brief Iterate Texture Buffer Errors Test cases.
8559 *
8560 *  @return Iteration result.
8561 */
8562tcu::TestNode::IterateResult BufferErrorsTest::iterate()
8563{
8564	/* Shortcut for GL functionality. */
8565	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8566
8567	/* Get context setup. */
8568	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
8569	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
8570
8571	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
8572	{
8573		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
8574
8575		return STOP;
8576	}
8577
8578	/* Running tests. */
8579	bool is_ok	= true;
8580	bool is_error = false;
8581
8582	/* Textures' objects */
8583	glw::GLuint texture_buffer = 0;
8584	glw::GLuint texture_1D	 = 0;
8585	glw::GLuint buffer		   = 0;
8586
8587	static const glw::GLubyte data[4]   = { 1, 2, 3, 4 };
8588	static const glw::GLuint  data_size = sizeof(data);
8589
8590	try
8591	{
8592		/* Auxiliary objects setup. */
8593		gl.createTextures(GL_TEXTURE_BUFFER, 1, &texture_buffer);
8594		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
8595
8596		gl.createTextures(GL_TEXTURE_1D, 1, &texture_1D);
8597		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
8598
8599		gl.createBuffers(1, &buffer);
8600		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers has failed");
8601
8602		gl.namedBufferData(buffer, data_size, data, GL_STATIC_COPY);
8603		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData has failed");
8604
8605		/*  Check that INVALID_OPERATION is generated by glTextureBuffer if texture
8606		 is not the name of an existing texture object. */
8607		{
8608			glw::GLuint not_a_texture = 0;
8609
8610			while (gl.isTexture(++not_a_texture))
8611				;
8612			GLU_EXPECT_NO_ERROR(gl.getError(), "glIsTexture has failed");
8613
8614			gl.textureBuffer(not_a_texture, GL_RGBA8, buffer);
8615
8616			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureBuffer",
8617									  "texture is not the name of an existing texture object.");
8618		}
8619
8620		/*  Check that INVALID_ENUM is generated by glTextureBuffer if the effective
8621		 target of texture is not TEXTURE_BUFFER. */
8622		{
8623			gl.textureBuffer(texture_1D, GL_RGBA8, buffer);
8624
8625			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureBuffer",
8626									  "the effective target of texture is not TEXTURE_BUFFER.");
8627		}
8628
8629		/*  Check that INVALID_ENUM is generated if internalformat is not one of the
8630		 sized internal formats described above. */
8631		{
8632			gl.textureBuffer(texture_buffer, GL_COMPRESSED_SIGNED_RED_RGTC1, buffer);
8633
8634			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureBuffer",
8635									  "internalformat is not one of the sized internal formats described above..");
8636		}
8637
8638		/*  Check that INVALID_OPERATION is generated if buffer is not zero and is
8639		 not the name of an existing buffer object. */
8640		{
8641			glw::GLuint not_a_buffer = 0;
8642
8643			while (gl.isBuffer(++not_a_buffer))
8644				;
8645			GLU_EXPECT_NO_ERROR(gl.getError(), "glIsBuffer has failed");
8646
8647			gl.textureBuffer(texture_buffer, GL_RGBA8, not_a_buffer);
8648
8649			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureBuffer",
8650									  "buffer is not zero and is not the name of an existing buffer object.");
8651		}
8652	}
8653	catch (...)
8654	{
8655		is_ok	= false;
8656		is_error = true;
8657	}
8658
8659	/* Cleanup. */
8660	if (texture_1D)
8661	{
8662		gl.deleteTextures(1, &texture_1D);
8663	}
8664
8665	if (texture_buffer)
8666	{
8667		gl.deleteTextures(1, &texture_buffer);
8668	}
8669
8670	if (buffer)
8671	{
8672		gl.deleteBuffers(1, &buffer);
8673	}
8674
8675	/* Errors clean up. */
8676	while (gl.getError())
8677		;
8678
8679	/* Result's setup. */
8680	if (is_ok)
8681	{
8682		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
8683	}
8684	else
8685	{
8686		if (is_error)
8687		{
8688			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
8689		}
8690		else
8691		{
8692			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
8693		}
8694	}
8695
8696	return STOP;
8697}
8698
8699/******************************** Texture Buffer Range Errors Test Implementation   ********************************/
8700
8701/** @brief Texture Buffer Range Errors Test constructor.
8702 *
8703 *  @param [in] context     OpenGL context.
8704 */
8705BufferRangeErrorsTest::BufferRangeErrorsTest(deqp::Context& context)
8706	: deqp::TestCase(context, "textures_buffer_range_errors", "Texture Buffer Range Errors Test")
8707{
8708	/* Intentionally left blank. */
8709}
8710
8711/** @brief Iterate Texture Buffer Range Errors Test cases.
8712 *
8713 *  @return Iteration result.
8714 */
8715tcu::TestNode::IterateResult BufferRangeErrorsTest::iterate()
8716{
8717	/* Shortcut for GL functionality. */
8718	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8719
8720	/* Get context setup. */
8721	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
8722	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
8723
8724	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
8725	{
8726		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
8727
8728		return STOP;
8729	}
8730
8731	/* Running tests. */
8732	bool is_ok	= true;
8733	bool is_error = false;
8734
8735	/* Textures' objects */
8736	glw::GLuint texture_buffer = 0;
8737	glw::GLuint texture_1D	 = 0;
8738	glw::GLuint buffer		   = 0;
8739
8740	static const glw::GLubyte data[4]   = { 1, 2, 3, 4 };
8741	static const glw::GLuint  data_size = sizeof(data);
8742
8743	try
8744	{
8745		/* Auxiliary objects setup. */
8746		gl.createTextures(GL_TEXTURE_BUFFER, 1, &texture_buffer);
8747		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
8748
8749		gl.createTextures(GL_TEXTURE_1D, 1, &texture_1D);
8750		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
8751
8752		gl.createBuffers(1, &buffer);
8753		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers has failed");
8754
8755		gl.namedBufferData(buffer, data_size, data, GL_STATIC_COPY);
8756		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData has failed");
8757
8758		/*  Check that INVALID_OPERATION is generated by TextureBufferRange if
8759		 texture is not the name of an existing texture object.*/
8760		{
8761			glw::GLuint not_a_texture = 0;
8762
8763			while (gl.isTexture(++not_a_texture))
8764				;
8765			GLU_EXPECT_NO_ERROR(gl.getError(), "glIsTexture has failed");
8766
8767			gl.textureBufferRange(not_a_texture, GL_RGBA8, buffer, 0, data_size);
8768
8769			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureBufferRange",
8770									  "texture is not the name of an existing texture object.");
8771		}
8772
8773		/*  Check that INVALID_ENUM is generated by TextureBufferRange if the
8774		 effective target of texture is not TEXTURE_BUFFER. */
8775		{
8776			gl.textureBufferRange(texture_1D, GL_RGBA8, buffer, 0, data_size);
8777
8778			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureBufferRange",
8779									  "the effective target of texture is not TEXTURE_BUFFER.");
8780		}
8781
8782		/*  Check that INVALID_ENUM is generated by TextureBufferRange if
8783		 internalformat is not one of the sized internal formats described above. */
8784		{
8785			gl.textureBufferRange(texture_buffer, GL_COMPRESSED_SIGNED_RED_RGTC1, buffer, 0, data_size);
8786
8787			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureBufferRange",
8788									  "internalformat is not one of the supported sized internal formats.");
8789		}
8790
8791		/*  Check that INVALID_OPERATION is generated by TextureBufferRange if
8792		 buffer is not zero and is not the name of an existing buffer object. */
8793		{
8794			glw::GLuint not_a_buffer = 0;
8795
8796			while (gl.isBuffer(++not_a_buffer))
8797				;
8798			GLU_EXPECT_NO_ERROR(gl.getError(), "glIsBuffer has failed");
8799
8800			gl.textureBufferRange(texture_buffer, GL_RGBA8, not_a_buffer, 0, data_size);
8801
8802			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureBufferRange",
8803									  "buffer is not zero and is not the name of an existing buffer object.");
8804		}
8805
8806		/* Check that INVALID_VALUE is generated by TextureBufferRange if offset
8807		 is negative, if size is less than or equal to zero, or if offset + size
8808		 is greater than the value of BUFFER_SIZE for buffer. */
8809		{
8810			gl.textureBufferRange(texture_buffer, GL_RGBA8, buffer, -1, data_size);
8811
8812			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureBufferRange", "offset is negative.");
8813
8814			gl.textureBufferRange(texture_buffer, GL_RGBA8, buffer, 0, 0);
8815
8816			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureBufferRange", "size is zero.");
8817
8818			gl.textureBufferRange(texture_buffer, GL_RGBA8, buffer, 0, -1);
8819
8820			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureBufferRange", "size is negative.");
8821
8822			gl.textureBufferRange(texture_buffer, GL_RGBA8, buffer, 0, data_size * 16);
8823
8824			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureBufferRange",
8825									  "size is greater than the value of BUFFER_SIZE for buffer.");
8826		}
8827
8828		/* Check that INVALID_VALUE is generated by TextureBufferRange if offset is
8829		 not an integer multiple of the value of TEXTURE_BUFFER_OFFSET_ALIGNMENT. */
8830		{
8831			glw::GLint gl_texture_buffer_offset_alignment = 0;
8832
8833			gl.getIntegerv(GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT, &gl_texture_buffer_offset_alignment);
8834
8835			/* If alignmet is 1 we cannot do anything. Error situtation is impossible then. */
8836			if (gl_texture_buffer_offset_alignment > 1)
8837			{
8838				gl.textureBufferRange(texture_buffer, GL_RGBA8, buffer, 1, data_size - 1);
8839
8840				is_ok &= CheckErrorAndLog(
8841					m_context, GL_INVALID_VALUE, "glTextureBufferRange",
8842					"offset is not an integer multiple of the value of TEXTURE_BUFFER_OFFSET_ALIGNMENT.");
8843			}
8844		}
8845	}
8846	catch (...)
8847	{
8848		is_ok	= false;
8849		is_error = true;
8850	}
8851
8852	/* Cleanup. */
8853	if (texture_1D)
8854	{
8855		gl.deleteTextures(1, &texture_1D);
8856	}
8857
8858	if (texture_buffer)
8859	{
8860		gl.deleteTextures(1, &texture_buffer);
8861	}
8862
8863	if (buffer)
8864	{
8865		gl.deleteBuffers(1, &buffer);
8866	}
8867
8868	/* Errors clean up. */
8869	while (gl.getError())
8870		;
8871
8872	/* Result's setup. */
8873	if (is_ok)
8874	{
8875		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
8876	}
8877	else
8878	{
8879		if (is_error)
8880		{
8881			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
8882		}
8883		else
8884		{
8885			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
8886		}
8887	}
8888
8889	return STOP;
8890}
8891
8892/******************************** Texture Storage Errors Test Implementation   ********************************/
8893
8894/** @brief Texture Storage Errors Test constructor.
8895 *
8896 *  @param [in] context     OpenGL context.
8897 */
8898StorageErrorsTest::StorageErrorsTest(deqp::Context& context)
8899	: deqp::TestCase(context, "textures_storage_errors", "Texture Storage Errors Test")
8900	, m_to_1D(0)
8901	, m_to_1D_array(0)
8902	, m_to_2D(0)
8903	, m_to_2D_array(0)
8904	, m_to_3D(0)
8905	, m_to_2D_ms(0)
8906	, m_to_2D_ms_immutable(0)
8907	, m_to_3D_ms(0)
8908	, m_to_3D_ms_immutable(0)
8909	, m_to_invalid(0)
8910	, m_internalformat_invalid(0)
8911	, m_max_texture_size(1)
8912	, m_max_samples(1)
8913	, m_max_array_texture_layers(1)
8914{
8915	/* Intentionally left blank. */
8916}
8917
8918/** @brief Iterate Texture Storage Errors Test cases.
8919 *
8920 *  @return Iteration result.
8921 */
8922tcu::TestNode::IterateResult StorageErrorsTest::iterate()
8923{
8924	/* Get context setup. */
8925	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
8926	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
8927
8928	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
8929	{
8930		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
8931
8932		return STOP;
8933	}
8934
8935	/* Running tests. */
8936	bool is_ok	= true;
8937	bool is_error = false;
8938
8939	try
8940	{
8941		Prepare();
8942
8943		is_ok &= Test1D();
8944		is_ok &= Test2D();
8945		is_ok &= Test3D();
8946		is_ok &= Test2DMultisample();
8947		is_ok &= Test3DMultisample();
8948	}
8949	catch (...)
8950	{
8951		is_ok	= false;
8952		is_error = true;
8953	}
8954
8955	/* Cleanup. */
8956	Clean();
8957
8958	/* Result's setup. */
8959	if (is_ok)
8960	{
8961		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
8962	}
8963	else
8964	{
8965		if (is_error)
8966		{
8967			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
8968		}
8969		else
8970		{
8971			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
8972		}
8973	}
8974
8975	return STOP;
8976}
8977
8978/** @brief Prepare test objects.
8979 */
8980void StorageErrorsTest::Prepare()
8981{
8982	/* Shortcut for GL functionality. */
8983	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8984
8985	/* Auxiliary objects setup. */
8986
8987	/* 1D */
8988	gl.createTextures(GL_TEXTURE_1D, 1, &m_to_1D);
8989	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
8990
8991	/* 1D ARRAY */
8992	gl.createTextures(GL_TEXTURE_1D_ARRAY, 1, &m_to_1D_array);
8993	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
8994
8995	/* 2D */
8996	gl.createTextures(GL_TEXTURE_2D, 1, &m_to_2D);
8997	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
8998
8999	/* 2D ARRAY */
9000	gl.createTextures(GL_TEXTURE_2D_ARRAY, 1, &m_to_2D_array);
9001	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
9002
9003	/* 3D */
9004	gl.createTextures(GL_TEXTURE_3D, 1, &m_to_3D);
9005	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
9006
9007	/* 2D Multisample */
9008	gl.createTextures(GL_TEXTURE_2D_MULTISAMPLE, 1, &m_to_2D_ms);
9009	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
9010
9011	/* 2D Multisample with storage */
9012	gl.createTextures(GL_TEXTURE_2D_MULTISAMPLE, 1, &m_to_2D_ms_immutable);
9013	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
9014
9015	gl.textureStorage2DMultisample(m_to_2D_ms_immutable, 1, GL_R8, 16, 16, false);
9016	GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2DMultisample has failed");
9017
9018	/* 3D Multisample */
9019	gl.createTextures(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 1, &m_to_3D_ms);
9020	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
9021
9022	/* 3D Multisample with storage */
9023	gl.createTextures(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 1, &m_to_3D_ms_immutable);
9024	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
9025
9026	gl.textureStorage3DMultisample(m_to_3D_ms_immutable, 1, GL_R8, 16, 16, 16, false);
9027	GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2DMultisample has failed");
9028
9029	/* Invalid values */
9030
9031	/* invalid texture object */
9032	while (gl.isTexture(++m_to_invalid))
9033		;
9034	GLU_EXPECT_NO_ERROR(gl.getError(), "glIsTexture has failed");
9035
9036	/* invalid internal format */
9037	static const glw::GLenum all_internal_formats[] = { GL_R8,
9038														GL_R8_SNORM,
9039														GL_R16,
9040														GL_R16_SNORM,
9041														GL_RG8,
9042														GL_RG8_SNORM,
9043														GL_RG16,
9044														GL_RG16_SNORM,
9045														GL_R3_G3_B2,
9046														GL_RGB4,
9047														GL_RGB5,
9048														GL_RGB565,
9049														GL_RGB8,
9050														GL_RGB8_SNORM,
9051														GL_RGB10,
9052														GL_RGB12,
9053														GL_RGB16,
9054														GL_RGB16_SNORM,
9055														GL_RGBA2,
9056														GL_RGBA4,
9057														GL_RGB5_A1,
9058														GL_RGBA8,
9059														GL_RGBA8_SNORM,
9060														GL_RGB10_A2,
9061														GL_RGB10_A2UI,
9062														GL_RGBA12,
9063														GL_RGBA16,
9064														GL_RGBA16_SNORM,
9065														GL_SRGB8,
9066														GL_SRGB8_ALPHA8,
9067														GL_R16F,
9068														GL_RG16F,
9069														GL_RGB16F,
9070														GL_RGBA16F,
9071														GL_R32F,
9072														GL_RG32F,
9073														GL_RGB32F,
9074														GL_RGBA32F,
9075														GL_R11F_G11F_B10F,
9076														GL_RGB9_E5,
9077														GL_R8I,
9078														GL_R8UI,
9079														GL_R16I,
9080														GL_R16UI,
9081														GL_R32I,
9082														GL_R32UI,
9083														GL_RG8I,
9084														GL_RG8UI,
9085														GL_RG16I,
9086														GL_RG16UI,
9087														GL_RG32I,
9088														GL_RG32UI,
9089														GL_RGB8I,
9090														GL_RGB8UI,
9091														GL_RGB16I,
9092														GL_RGB16UI,
9093														GL_RGB32I,
9094														GL_RGB32UI,
9095														GL_RGBA8I,
9096														GL_RGBA8UI,
9097														GL_RGBA16I,
9098														GL_RGBA16UI,
9099														GL_RGBA32I,
9100														GL_RGBA32UI,
9101														GL_COMPRESSED_RED,
9102														GL_COMPRESSED_RG,
9103														GL_COMPRESSED_RGB,
9104														GL_COMPRESSED_RGBA,
9105														GL_COMPRESSED_SRGB,
9106														GL_COMPRESSED_SRGB_ALPHA,
9107														GL_COMPRESSED_RED_RGTC1,
9108														GL_COMPRESSED_SIGNED_RED_RGTC1,
9109														GL_COMPRESSED_RG_RGTC2,
9110														GL_COMPRESSED_SIGNED_RG_RGTC2,
9111														GL_COMPRESSED_RGBA_BPTC_UNORM,
9112														GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM,
9113														GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT,
9114														GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT,
9115														GL_COMPRESSED_RGB8_ETC2,
9116														GL_COMPRESSED_SRGB8_ETC2,
9117														GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
9118														GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
9119														GL_COMPRESSED_RGBA8_ETC2_EAC,
9120														GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,
9121														GL_COMPRESSED_R11_EAC,
9122														GL_COMPRESSED_SIGNED_R11_EAC,
9123														GL_COMPRESSED_RG11_EAC,
9124														GL_COMPRESSED_SIGNED_RG11_EAC,
9125														GL_DEPTH_COMPONENT16,
9126														GL_DEPTH_COMPONENT24,
9127														GL_DEPTH_COMPONENT32,
9128														GL_DEPTH_COMPONENT32F,
9129														GL_DEPTH24_STENCIL8,
9130														GL_DEPTH32F_STENCIL8,
9131														GL_STENCIL_INDEX1,
9132														GL_STENCIL_INDEX4,
9133														GL_STENCIL_INDEX8,
9134														GL_STENCIL_INDEX16 };
9135
9136	static const glw::GLuint all_internal_formats_count =
9137		sizeof(all_internal_formats) / sizeof(all_internal_formats[0]);
9138
9139	bool is_valid			 = true;
9140	m_internalformat_invalid = 0;
9141
9142	while (is_valid)
9143	{
9144		is_valid = false;
9145		m_internalformat_invalid++;
9146		for (glw::GLuint i = 0; i < all_internal_formats_count; ++i)
9147		{
9148			if (all_internal_formats[i] == m_internalformat_invalid)
9149			{
9150				is_valid = true;
9151				break;
9152			}
9153		}
9154	}
9155
9156	/* Maximum texture size.*/
9157	gl.getIntegerv(GL_MAX_TEXTURE_SIZE, &m_max_texture_size);
9158	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");
9159
9160	/* Maximum number of samples. */
9161	gl.getInternalformativ(GL_RENDERBUFFER, GL_R8, GL_SAMPLES, 1, &m_max_samples);
9162	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformativ has failed");
9163
9164	/* Maximum number of array texture layers. */
9165	gl.getIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &m_max_array_texture_layers);
9166	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");
9167}
9168
9169/** @brief Test TextureStorage1D
9170 *
9171 *  @return Test result.
9172 */
9173bool StorageErrorsTest::Test1D()
9174{
9175	/* Shortcut for GL functionality. */
9176	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9177
9178	/* Result. */
9179	bool is_ok = true;
9180
9181	/*  Check that INVALID_OPERATION is generated by TextureStorage1D if texture
9182	 is not the name of an existing texture object. */
9183	{
9184		gl.textureStorage1D(m_to_invalid, 1, GL_R8, 8);
9185		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage1D",
9186								  "texture is not the name of an existing texture object.");
9187	}
9188
9189	/*  Check that INVALID_ENUM is generated by TextureStorage1D if
9190	 internalformat is not a valid sized internal format. */
9191	{
9192		gl.textureStorage1D(m_to_1D, 1, m_internalformat_invalid, 8);
9193		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureStorage1D",
9194								  "internalformat is not a valid sized internal format.");
9195	}
9196
9197	/*  Check that INVALID_ENUM is generated by TextureStorage1D if target or
9198	 the effective target of texture is not one of the accepted targets
9199	 described above. */
9200	{
9201		gl.textureStorage1D(m_to_2D, 1, GL_R8, 8);
9202		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage1D",
9203								  "the effective target of texture is not one of the accepted targets.");
9204	}
9205
9206	/*  Check that INVALID_VALUE is generated by TextureStorage1D if width or
9207	 levels are less than 1. */
9208	{
9209		gl.textureStorage1D(m_to_1D, 0, GL_R8, 8);
9210		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage1D", "levels is less than 1.");
9211
9212		gl.textureStorage1D(m_to_1D, 1, GL_R8, 0);
9213		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage1D", "width is less than 1.");
9214	}
9215
9216	/*  Check that INVALID_OPERATION is generated by TextureStorage1D if levels
9217	 is greater than log2(width)+1. */
9218	{
9219		gl.textureStorage1D(m_to_1D, 8, GL_R8, 8);
9220		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage1D",
9221								  "levels is greater than log2(width)+1.");
9222	}
9223
9224	return is_ok;
9225}
9226
9227/** @brief Test TextureStorage2D
9228 *
9229 *  @return Test result.
9230 */
9231bool StorageErrorsTest::Test2D()
9232{
9233	/* Shortcut for GL functionality. */
9234	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9235
9236	/* Result. */
9237	bool is_ok = true;
9238
9239	/*  Check that INVALID_OPERATION is generated by TextureStorage2D if
9240	 texture is not the name of an existing texture object. */
9241	{
9242		gl.textureStorage2D(m_to_invalid, 1, GL_R8, 8, 8);
9243		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage2D",
9244								  "texture is not the name of an existing texture object.");
9245	}
9246
9247	/*  Check that INVALID_ENUM is generated by TextureStorage2D if
9248	 internalformat is not a valid sized internal format. */
9249	{
9250		gl.textureStorage2D(m_to_2D, 1, m_internalformat_invalid, 8, 8);
9251		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureStorage2D",
9252								  "internalformat is not a valid sized internal format.");
9253	}
9254
9255	/*  Check that INVALID_ENUM is generated by TextureStorage2D if target or
9256	 the effective target of texture is not one of the accepted targets
9257	 described above. */
9258	{
9259		gl.textureStorage2D(m_to_1D, 1, GL_R8, 8, 8);
9260		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage2D",
9261								  "the effective target of texture is not one of the accepted targets.");
9262	}
9263
9264	/*  Check that INVALID_VALUE is generated by TextureStorage2D if width,
9265	 height or levels are less than 1. */
9266	{
9267		gl.textureStorage2D(m_to_2D, 0, GL_R8, 8, 8);
9268		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage2D", "levels is less than 1.");
9269
9270		gl.textureStorage2D(m_to_2D, 1, GL_R8, 0, 8);
9271		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage2D", "width is less than 1.");
9272
9273		gl.textureStorage2D(m_to_2D, 1, GL_R8, 8, 0);
9274		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage2D", "height is less than 1.");
9275	}
9276
9277	/* Check that INVALID_OPERATION is generated by TextureStorage2D if target
9278	 is TEXTURE_1D_ARRAY or PROXY_TEXTURE_1D_ARRAY and levels is greater than
9279	 log2(width)+1. */
9280	{
9281		gl.textureStorage2D(m_to_1D_array, 8, GL_R8, 8, 8);
9282		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage2D",
9283								  "target is TEXTURE_1D_ARRAY and levels is greater than log2(width)+1.");
9284	}
9285
9286	/*  Check that INVALID_OPERATION is generated by TextureStorage2D if target
9287	 is not TEXTURE_1D_ARRAY or PROXY_TEXTURE_1D_ARRAY and levels is greater
9288	 than log2(max(width, height))+1.  */
9289	{
9290		gl.textureStorage2D(m_to_2D, 8, GL_R8, 8, 8);
9291		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage2D",
9292								  "target is TEXTURE_2D and levels is greater than log2(max(width, height))+1.");
9293	}
9294
9295	return is_ok;
9296}
9297
9298/** @brief Test TextureStorage3D
9299 *
9300 *  @return Test result.
9301 */
9302bool StorageErrorsTest::Test3D()
9303{
9304	/* Shortcut for GL functionality. */
9305	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9306
9307	/* Result. */
9308	bool is_ok = true;
9309
9310	/*  Check that INVALID_OPERATION is generated by TextureStorage3D if texture
9311	 is not the name of an existing texture object. */
9312	{
9313		gl.textureStorage3D(m_to_invalid, 1, GL_R8, 8, 8, 8);
9314		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage3D",
9315								  "texture is not the name of an existing texture object.");
9316	}
9317
9318	/*  Check that INVALID_ENUM is generated by TextureStorage3D if
9319	 internalformat is not a valid sized internal format. */
9320	{
9321		gl.textureStorage3D(m_to_3D, 1, m_internalformat_invalid, 8, 8, 8);
9322		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureStorage3D",
9323								  "internalformat is not a valid sized internal format.");
9324	}
9325
9326	/*  Check that INVALID_ENUM is generated by TextureStorage3D if target or
9327	 the effective target of texture is not one of the accepted targets
9328	 described above. */
9329	{
9330		gl.textureStorage3D(m_to_1D, 1, GL_R8, 8, 8, 8);
9331		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage3D",
9332								  "the effective target of texture is not one of the accepted targets.");
9333	}
9334
9335	/*  Check that INVALID_VALUE is generated by TextureStorage3D if width,
9336	 height, depth or levels are less than 1. */
9337	{
9338		gl.textureStorage3D(m_to_3D, 0, GL_R8, 8, 8, 8);
9339		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3D", "levels is less than 1.");
9340
9341		gl.textureStorage3D(m_to_3D, 1, GL_R8, 0, 8, 8);
9342		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3D", "width is less than 1.");
9343
9344		gl.textureStorage3D(m_to_3D, 1, GL_R8, 8, 0, 8);
9345		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3D", "height is less than 1.");
9346
9347		gl.textureStorage3D(m_to_3D, 1, GL_R8, 8, 8, 0);
9348		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3D", "depth is less than 1.");
9349	}
9350
9351	/* Check that INVALID_OPERATION is generated by TextureStorage3D if target
9352	 is TEXTURE_3D or PROXY_TEXTURE_3D and levels is greater than
9353	 log2(max(width, height, depth))+1. */
9354	{
9355		gl.textureStorage3D(m_to_3D, 8, GL_R8, 8, 8, 8);
9356		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage3D",
9357								  "target is TEXTURE_3D and levels is greater than log2(max(width, height, depth))+1.");
9358	}
9359
9360	/*  Check that INVALID_OPERATION is generated by TextureStorage3D if target
9361	 is TEXTURE_2D_ARRAY, PROXY_TEXTURE_2D_ARRAY, TEXURE_CUBE_ARRAY,
9362	 or PROXY_TEXTURE_CUBE_MAP_ARRAY and levels is greater than
9363	 log2(max(width, height))+1.  */
9364	{
9365		gl.textureStorage3D(m_to_2D_array, 6, GL_R8, 8, 8, 256);
9366		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage3D",
9367								  "target is TEXTURE_2D_ARRAY and levels is greater than log2(max(width, height))+1.");
9368	}
9369
9370	return is_ok;
9371}
9372
9373/** @brief Test TextureStorage2DMultisample
9374 *
9375 *  @return Test result.
9376 */
9377bool StorageErrorsTest::Test2DMultisample()
9378{
9379	/* Shortcut for GL functionality. */
9380	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9381
9382	/* Result. */
9383	bool is_ok = true;
9384
9385	/*  Check that INVALID_OPERATION is generated by TextureStorage2DMultisample
9386	 if texture is not the name of an existing texture object. */
9387	{
9388		gl.textureStorage2DMultisample(m_to_invalid, 1, GL_R8, 8, 8, false);
9389		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage2DMultisample",
9390								  "texture is not the name of an existing texture object.");
9391	}
9392
9393	/*  Check that INVALID_ENUM is generated by TextureStorage2DMultisample if
9394	 internalformat is not a valid color-renderable, depth-renderable or
9395	 stencil-renderable format. */
9396	{
9397		gl.textureStorage2DMultisample(m_to_2D_ms, 1, m_internalformat_invalid, 8, 8, false);
9398		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureStorage2DMultisample",
9399								  "internalformat is not a valid sized internal format.");
9400	}
9401
9402	/*  Check that INVALID_OPERATION is generated by TextureStorage2DMultisample if
9403	 target or the effective target of texture is not one of the accepted
9404	 targets described above. */
9405	{
9406		gl.textureStorage2DMultisample(m_to_1D, 1, GL_R8, 8, 8, false);
9407		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage2DMultisample",
9408								  "the effective target of texture is not one of the accepted targets.");
9409	}
9410
9411	/* Check that INVALID_VALUE is generated by TextureStorage2DMultisample if
9412	 width or height are less than 1 or greater than the value of
9413	 MAX_TEXTURE_SIZE. */
9414	{
9415		gl.textureStorage2DMultisample(m_to_2D_ms, 1, GL_R8, 0, 8, false);
9416		is_ok &=
9417			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage2DMultisample", "width is less than 1.");
9418
9419		gl.textureStorage2DMultisample(m_to_2D_ms, 1, GL_R8, 8, 0, false);
9420		is_ok &=
9421			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage2DMultisample", "height is less than 1.");
9422
9423		gl.textureStorage2DMultisample(m_to_2D_ms, 1, GL_R8, m_max_texture_size * 2, 8, false);
9424		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage2DMultisample",
9425								  "width is greater than the value of MAX_TEXTURE_SIZE.");
9426
9427		gl.textureStorage2DMultisample(m_to_2D_ms, 1, GL_R8, 8, m_max_texture_size * 2, false);
9428		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage2DMultisample",
9429								  "height is greater than the value of MAX_TEXTURE_SIZE.");
9430	}
9431
9432	/* Check that INVALID_OPERATION is generated by TextureStorage2DMultisample if
9433	 samples is greater than the value of MAX_SAMPLES. */
9434	{
9435		gl.textureStorage2DMultisample(m_to_2D_ms, m_max_samples * 2, GL_R8, 8, 8, false);
9436		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage2DMultisample",
9437								  "samples is greater than the value of MAX_SAMPLES.");
9438	}
9439
9440	/* Check that INVALID_OPERATION is generated by TextureStorage2DMultisample
9441	 if the value of TEXTURE_IMMUTABLE_FORMAT for the texture bound to target
9442	 is not FALSE. */
9443	{
9444		gl.textureStorage2DMultisample(m_to_2D_ms_immutable, 1, GL_R8, 8, 8, false);
9445		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage2DMultisample",
9446								  "samples is greater than the value of MAX_SAMPLES.");
9447	}
9448
9449	return is_ok;
9450}
9451
9452/** @brief Test TextureStorage3DMultisample
9453 *
9454 *  @return Test result.
9455 */
9456bool StorageErrorsTest::Test3DMultisample()
9457{
9458	/* Shortcut for GL functionality. */
9459	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9460
9461	/* Result. */
9462	bool is_ok = true;
9463
9464	/*  Check that INVALID_OPERATION is generated by TextureStorage3DMultisample
9465	 if texture is not the name of an existing texture object. */
9466	{
9467		gl.textureStorage3DMultisample(m_to_invalid, 1, GL_R8, 8, 8, 8, false);
9468		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage3DMultisample",
9469								  "texture is not the name of an existing texture object.");
9470	}
9471
9472	/*  Check that INVALID_ENUM is generated by TextureStorage3DMultisample if
9473	 internalformat is not a valid color-renderable, depth-renderable or
9474	 stencil-renderable format. */
9475	{
9476		gl.textureStorage3DMultisample(m_to_3D_ms, 1, m_internalformat_invalid, 8, 8, 8, false);
9477		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureStorage3DMultisample",
9478								  "internalformat is not a valid sized internal format.");
9479	}
9480
9481	/*  Check that INVALID_OPERATION is generated by TextureStorage3DMultisample if
9482	 target or the effective target of texture is not one of the accepted
9483	 targets described above. */
9484	{
9485		gl.textureStorage3DMultisample(m_to_1D, 1, GL_R8, 8, 8, 8, false);
9486		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage3DMultisample",
9487								  "the effective target of texture is not one of the accepted targets.");
9488	}
9489
9490	/* Check that INVALID_VALUE is generated by TextureStorage3DMultisample if
9491	 width or height are less than 1 or greater than the value of
9492	 MAX_TEXTURE_SIZE. */
9493	{
9494		gl.textureStorage3DMultisample(m_to_3D_ms, 1, GL_R8, 0, 8, 8, false);
9495		is_ok &=
9496			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3DMultisample", "width is less than 1.");
9497
9498		gl.textureStorage3DMultisample(m_to_3D_ms, 1, GL_R8, 8, 0, 8, false);
9499		is_ok &=
9500			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3DMultisample", "height is less than 1.");
9501
9502		gl.textureStorage3DMultisample(m_to_3D_ms, 1, GL_R8, m_max_texture_size * 2, 8, 8, false);
9503		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3DMultisample",
9504								  "width is greater than the value of MAX_TEXTURE_SIZE.");
9505
9506		gl.textureStorage3DMultisample(m_to_3D_ms, 1, GL_R8, 8, m_max_texture_size * 2, 8, false);
9507		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3DMultisample",
9508								  "height is greater than the value of MAX_TEXTURE_SIZE.");
9509	}
9510
9511	/* Check that INVALID_VALUE is generated by TextureStorage3DMultisample if
9512	 depth is less than 1 or greater than the value of
9513	 MAX_ARRAY_TEXTURE_LAYERS. */
9514	{
9515		gl.textureStorage3DMultisample(m_to_3D_ms, 1, GL_R8, 8, 8, 0, false);
9516		is_ok &=
9517			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3DMultisample", "depth is less than 1.");
9518
9519		gl.textureStorage3DMultisample(m_to_3D_ms, 1, GL_R8, 8, 8, m_max_array_texture_layers * 2, false);
9520		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3DMultisample",
9521								  "depth is greater than the value of MAX_ARRAY_TEXTURE_LAYERS.");
9522	}
9523
9524	/* Check that INVALID_VALUE is generated by TextureStorage3DMultisample if
9525	 samples is greater than the maximum number of samples reported for GL_R8 */
9526	{
9527		gl.textureStorage3DMultisample(m_to_3D_ms, m_max_samples * 2, GL_R8, 8, 8, 8, false);
9528		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage3DMultisample",
9529								  "samples is greater than the value of MAX_SAMPLES.");
9530	}
9531
9532	/* Check that INVALID_OPERATION is generated by TextureStorage3DMultisample
9533	 if the value of TEXTURE_IMMUTABLE_FORMAT for the texture bound to target
9534	 is not FALSE. */
9535	{
9536		gl.textureStorage3DMultisample(m_to_3D_ms_immutable, 1, GL_R8, 8, 8, 8, false);
9537		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage3DMultisample",
9538								  "samples is greater than the value of MAX_SAMPLES.");
9539	}
9540
9541	return is_ok;
9542}
9543
9544/** @brief Clean GL objects, test variables and GL errors.
9545 */
9546void StorageErrorsTest::Clean()
9547{
9548	/* Shortcut for GL functionality. */
9549	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9550
9551	/* Cleanup. */
9552	if (m_to_1D)
9553	{
9554		gl.deleteTextures(1, &m_to_1D);
9555
9556		m_to_1D = 0;
9557	}
9558
9559	if (m_to_1D_array)
9560	{
9561		gl.deleteTextures(1, &m_to_1D_array);
9562
9563		m_to_1D_array = 0;
9564	}
9565
9566	if (m_to_2D)
9567	{
9568		gl.deleteTextures(1, &m_to_2D);
9569
9570		m_to_2D = 0;
9571	}
9572
9573	if (m_to_2D_array)
9574	{
9575		gl.deleteTextures(1, &m_to_2D_array);
9576
9577		m_to_2D_array = 0;
9578	}
9579
9580	if (m_to_3D)
9581	{
9582		gl.deleteTextures(1, &m_to_3D);
9583
9584		m_to_3D = 0;
9585	}
9586
9587	if (m_to_2D_ms)
9588	{
9589		gl.deleteTextures(1, &m_to_2D_ms);
9590
9591		m_to_2D_ms = 0;
9592	}
9593
9594	if (m_to_2D_ms_immutable)
9595	{
9596		gl.deleteTextures(1, &m_to_2D_ms_immutable);
9597
9598		m_to_2D_ms_immutable = 0;
9599	}
9600
9601	if (m_to_3D_ms)
9602	{
9603		gl.deleteTextures(1, &m_to_3D_ms);
9604
9605		m_to_3D_ms = 0;
9606	}
9607
9608	if (m_to_3D_ms_immutable)
9609	{
9610		gl.deleteTextures(1, &m_to_3D_ms_immutable);
9611
9612		m_to_3D_ms_immutable = 0;
9613	}
9614
9615	m_to_invalid			   = 0;
9616	m_internalformat_invalid   = 0;
9617	m_max_texture_size		   = 1;
9618	m_max_samples			   = 1;
9619	m_max_array_texture_layers = 1;
9620
9621	while (GL_NO_ERROR != gl.getError())
9622		;
9623}
9624
9625/******************************** Texture SubImage Errors Test Implementation   ********************************/
9626
9627/** @brief Texture SubImage Errors Test constructor.
9628 *
9629 *  @param [in] context     OpenGL context.
9630 */
9631SubImageErrorsTest::SubImageErrorsTest(deqp::Context& context)
9632	: deqp::TestCase(context, "textures_subimage_errors", "Texture SubImage Errors Test")
9633	, m_to_1D_empty(0)
9634	, m_to_2D_empty(0)
9635	, m_to_3D_empty(0)
9636	, m_to_1D(0)
9637	, m_to_2D(0)
9638	, m_to_3D(0)
9639	, m_to_1D_compressed(0)
9640	, m_to_2D_compressed(0)
9641	, m_to_3D_compressed(0)
9642	, m_to_rectangle_compressed(0)
9643	, m_to_invalid(0)
9644	, m_bo(0)
9645	, m_format_invalid(0)
9646	, m_type_invalid(0)
9647	, m_max_texture_size(1)
9648	, m_reference_compressed_1D(DE_NULL)
9649	, m_reference_compressed_2D(DE_NULL)
9650	, m_reference_compressed_3D(DE_NULL)
9651	, m_reference_compressed_rectangle(DE_NULL)
9652	, m_reference_compressed_1D_size(0)
9653	, m_reference_compressed_2D_size(0)
9654	, m_reference_compressed_3D_size(0)
9655	, m_reference_compressed_rectangle_size(0)
9656	, m_reference_compressed_1D_format(0)
9657	, m_reference_compressed_2D_format(0)
9658	, m_reference_compressed_3D_format(0)
9659	, m_reference_compressed_rectangle_format(0)
9660	, m_not_matching_compressed_1D_format(0)
9661	, m_not_matching_compressed_1D_size(0)
9662	, m_not_matching_compressed_2D_format(0)
9663	, m_not_matching_compressed_2D_size(0)
9664	, m_not_matching_compressed_3D_format(0)
9665	, m_not_matching_compressed_3D_size(0)
9666{
9667	/* Intentionally left blank. */
9668}
9669
9670/** @brief Iterate Texture SubImage Errors Test cases.
9671 *
9672 *  @return Iteration result.
9673 */
9674tcu::TestNode::IterateResult SubImageErrorsTest::iterate()
9675{
9676	/* Get context setup. */
9677	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
9678	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
9679
9680	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
9681	{
9682		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
9683
9684		return STOP;
9685	}
9686
9687	/* Running tests. */
9688	bool is_ok	= true;
9689	bool is_error = false;
9690
9691	try
9692	{
9693		Prepare();
9694
9695		is_ok &= Test1D();
9696		is_ok &= Test2D();
9697		is_ok &= Test3D();
9698		is_ok &= Test1DCompressed();
9699		is_ok &= Test2DCompressed();
9700		is_ok &= Test3DCompressed();
9701	}
9702	catch (...)
9703	{
9704		is_ok	= false;
9705		is_error = true;
9706	}
9707
9708	/* Cleanup. */
9709	Clean();
9710
9711	/* Result's setup. */
9712	if (is_ok)
9713	{
9714		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
9715	}
9716	else
9717	{
9718		if (is_error)
9719		{
9720			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
9721		}
9722		else
9723		{
9724			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
9725		}
9726	}
9727
9728	return STOP;
9729}
9730
9731/** @brief Prepare test's objects.
9732 */
9733void SubImageErrorsTest::Prepare()
9734{
9735	/* Shortcut for GL functionality. */
9736	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9737
9738	/* Auxiliary objects setup. */
9739
9740	/* 1D */
9741	gl.createTextures(GL_TEXTURE_1D, 1, &m_to_1D_empty);
9742	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
9743
9744	/* 2D */
9745	gl.createTextures(GL_TEXTURE_2D, 1, &m_to_2D_empty);
9746	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
9747
9748	/* 3D */
9749	gl.createTextures(GL_TEXTURE_3D, 1, &m_to_3D_empty);
9750	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
9751
9752	/* 1D */
9753	gl.createTextures(GL_TEXTURE_1D, 1, &m_to_1D);
9754	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
9755
9756	gl.bindTexture(GL_TEXTURE_1D, m_to_1D);
9757	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
9758
9759	gl.texImage1D(GL_TEXTURE_1D, 0, s_reference_internalformat, s_reference_width, 0, s_reference_format,
9760				  GL_UNSIGNED_BYTE, s_reference);
9761	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");
9762
9763	/* 2D */
9764	gl.createTextures(GL_TEXTURE_2D, 1, &m_to_2D);
9765	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
9766
9767	gl.bindTexture(GL_TEXTURE_2D, m_to_2D);
9768	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
9769
9770	gl.texImage2D(GL_TEXTURE_2D, 0, s_reference_internalformat, s_reference_width, s_reference_height, 0,
9771				  s_reference_format, GL_UNSIGNED_BYTE, s_reference);
9772	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");
9773
9774	/* 3D */
9775	gl.createTextures(GL_TEXTURE_3D, 1, &m_to_3D);
9776	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
9777
9778	gl.bindTexture(GL_TEXTURE_3D, m_to_3D);
9779	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
9780
9781	gl.texImage3D(GL_TEXTURE_3D, 0, s_reference_internalformat, s_reference_width, s_reference_height,
9782				  s_reference_depth, 0, s_reference_format, GL_UNSIGNED_BYTE, s_reference);
9783	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");
9784
9785	/* 1D Compressed */
9786	gl.createTextures(GL_TEXTURE_1D, 1, &m_to_1D_compressed);
9787	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
9788
9789	gl.bindTexture(GL_TEXTURE_1D, m_to_1D_compressed);
9790	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
9791
9792	gl.texImage1D(GL_TEXTURE_1D, 0, s_reference_internalformat_compressed, s_reference_width, 0, s_reference_format,
9793				  GL_UNSIGNED_BYTE, s_reference);
9794	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");
9795
9796	glw::GLint is_compressed = 0;
9797
9798	gl.getTexLevelParameteriv(GL_TEXTURE_1D, 0, GL_TEXTURE_COMPRESSED, &is_compressed);
9799	GLU_EXPECT_NO_ERROR(gl.getError(), "glTetTexLevelParameteriv has failed");
9800
9801	if (is_compressed)
9802	{
9803		gl.getTexLevelParameteriv(GL_TEXTURE_1D, 0, GL_TEXTURE_INTERNAL_FORMAT, &m_reference_compressed_1D_format);
9804		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
9805
9806		m_reference_compressed_1D_size = 0;
9807
9808		gl.getTexLevelParameteriv(GL_TEXTURE_1D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &m_reference_compressed_1D_size);
9809		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
9810
9811		if (m_reference_compressed_1D_size)
9812		{
9813			m_reference_compressed_1D = new glw::GLubyte[m_reference_compressed_1D_size];
9814
9815			gl.getCompressedTexImage(GL_TEXTURE_1D, 0, m_reference_compressed_1D);
9816			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");
9817		}
9818	}
9819
9820	/* 2D Compressed */
9821	gl.createTextures(GL_TEXTURE_2D, 1, &m_to_2D_compressed);
9822	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
9823
9824	gl.bindTexture(GL_TEXTURE_2D, m_to_2D_compressed);
9825	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
9826
9827	gl.texImage2D(GL_TEXTURE_2D, 0, s_reference_internalformat_compressed, s_reference_width, s_reference_height, 0,
9828				  s_reference_format, GL_UNSIGNED_BYTE, s_reference);
9829	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");
9830
9831	is_compressed = 0;
9832
9833	gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED, &is_compressed);
9834	GLU_EXPECT_NO_ERROR(gl.getError(), "glTetTexLevelParameteriv has failed");
9835
9836	if (is_compressed)
9837	{
9838		gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &m_reference_compressed_2D_format);
9839		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
9840
9841		m_reference_compressed_2D_size = 0;
9842
9843		gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &m_reference_compressed_2D_size);
9844		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
9845
9846		if (m_reference_compressed_2D_size)
9847		{
9848			m_reference_compressed_2D = new glw::GLubyte[m_reference_compressed_2D_size];
9849
9850			gl.getCompressedTexImage(GL_TEXTURE_2D, 0, m_reference_compressed_2D);
9851			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");
9852		}
9853	}
9854
9855	/* 3D Compressed */
9856	gl.createTextures(GL_TEXTURE_2D_ARRAY, 1, &m_to_3D_compressed);
9857	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
9858
9859	gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_to_3D_compressed);
9860	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
9861
9862	gl.texImage3D(GL_TEXTURE_2D_ARRAY, 0, s_reference_internalformat_compressed, s_reference_width, s_reference_height,
9863				  s_reference_depth, 0, s_reference_format, GL_UNSIGNED_BYTE, s_reference);
9864	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage3D has failed");
9865
9866	is_compressed = 0;
9867
9868	gl.getTexLevelParameteriv(GL_TEXTURE_2D_ARRAY, 0, GL_TEXTURE_COMPRESSED, &is_compressed);
9869	GLU_EXPECT_NO_ERROR(gl.getError(), "glTetTexLevelParameteriv has failed");
9870
9871	if (is_compressed)
9872	{
9873		gl.getTexLevelParameteriv(GL_TEXTURE_2D_ARRAY, 0, GL_TEXTURE_INTERNAL_FORMAT,
9874								  &m_reference_compressed_3D_format);
9875		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
9876
9877		m_reference_compressed_3D_size = 0;
9878
9879		gl.getTexLevelParameteriv(GL_TEXTURE_2D_ARRAY, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE,
9880								  &m_reference_compressed_3D_size);
9881		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
9882
9883		if (m_reference_compressed_3D_size)
9884		{
9885			m_reference_compressed_3D = new glw::GLubyte[m_reference_compressed_3D_size];
9886
9887			gl.getCompressedTexImage(GL_TEXTURE_2D_ARRAY, 0, m_reference_compressed_3D);
9888			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");
9889		}
9890	}
9891
9892	/* RECTANGLE Compressed */
9893	gl.createTextures(GL_TEXTURE_RECTANGLE, 1, &m_to_rectangle_compressed);
9894	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
9895
9896	gl.bindTexture(GL_TEXTURE_RECTANGLE, m_to_rectangle_compressed);
9897	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
9898
9899	gl.texImage2D(GL_TEXTURE_RECTANGLE, 0, s_reference_internalformat_compressed, s_reference_width, s_reference_height,
9900				  0, s_reference_format, GL_UNSIGNED_BYTE, s_reference);
9901	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");
9902
9903	is_compressed = 0;
9904
9905	gl.getTexLevelParameteriv(GL_TEXTURE_RECTANGLE, 0, GL_TEXTURE_COMPRESSED, &is_compressed);
9906	GLU_EXPECT_NO_ERROR(gl.getError(), "glTetTexLevelParameteriv has failed");
9907
9908	if (is_compressed)
9909	{
9910		gl.getTexLevelParameteriv(GL_TEXTURE_RECTANGLE, 0, GL_TEXTURE_INTERNAL_FORMAT,
9911								  &m_reference_compressed_rectangle_format);
9912		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
9913
9914		m_reference_compressed_rectangle_size = 0;
9915
9916		gl.getTexLevelParameteriv(GL_TEXTURE_RECTANGLE, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE,
9917								  &m_reference_compressed_rectangle_size);
9918		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
9919
9920		if (m_reference_compressed_rectangle_size)
9921		{
9922			m_reference_compressed_rectangle = new glw::GLubyte[m_reference_compressed_rectangle_size];
9923
9924			gl.getCompressedTexImage(GL_TEXTURE_RECTANGLE, 0, m_reference_compressed_rectangle);
9925			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");
9926		}
9927	}
9928
9929	/* Buffer object */
9930	gl.createBuffers(1, &m_bo);
9931	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers has failed");
9932
9933	gl.namedBufferData(m_bo, s_reference_size, s_reference, GL_STATIC_COPY);
9934	GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData has failed");
9935
9936	/* Invalid values */
9937
9938	/* invalid texture object */
9939	while (gl.isTexture(++m_to_invalid))
9940		;
9941	GLU_EXPECT_NO_ERROR(gl.getError(), "glIsTexture has failed");
9942
9943	/* invalid internal format */
9944	static const glw::GLenum all_formats[] = { GL_STENCIL_INDEX,
9945											   GL_DEPTH_COMPONENT,
9946											   GL_DEPTH_STENCIL,
9947											   GL_RED,
9948											   GL_GREEN,
9949											   GL_BLUE,
9950											   GL_RG,
9951											   GL_RGB,
9952											   GL_RGBA,
9953											   GL_BGR,
9954											   GL_BGRA,
9955											   GL_RED_INTEGER,
9956											   GL_GREEN_INTEGER,
9957											   GL_BLUE_INTEGER,
9958											   GL_RG_INTEGER,
9959											   GL_RGB_INTEGER,
9960											   GL_RGBA_INTEGER,
9961											   GL_BGR_INTEGER,
9962											   GL_BGRA_INTEGER };
9963
9964	static const glw::GLuint all_internal_formats_count = sizeof(all_formats) / sizeof(all_formats[0]);
9965
9966	bool is_valid	= true;
9967	m_format_invalid = 0;
9968
9969	while (is_valid)
9970	{
9971		is_valid = false;
9972		m_format_invalid++;
9973		for (glw::GLuint i = 0; i < all_internal_formats_count; ++i)
9974		{
9975			if (all_formats[i] == m_format_invalid)
9976			{
9977				is_valid = true;
9978				break;
9979			}
9980		}
9981	}
9982
9983	/* Invalid type. */
9984	static const glw::GLenum all_types[] = { GL_UNSIGNED_BYTE,
9985											 GL_BYTE,
9986											 GL_UNSIGNED_SHORT,
9987											 GL_SHORT,
9988											 GL_UNSIGNED_INT,
9989											 GL_INT,
9990											 GL_HALF_FLOAT,
9991											 GL_FLOAT,
9992											 GL_UNSIGNED_BYTE_3_3_2,
9993											 GL_UNSIGNED_BYTE_2_3_3_REV,
9994											 GL_UNSIGNED_SHORT_5_6_5,
9995											 GL_UNSIGNED_SHORT_5_6_5_REV,
9996											 GL_UNSIGNED_SHORT_4_4_4_4,
9997											 GL_UNSIGNED_SHORT_4_4_4_4_REV,
9998											 GL_UNSIGNED_SHORT_5_5_5_1,
9999											 GL_UNSIGNED_SHORT_1_5_5_5_REV,
10000											 GL_UNSIGNED_INT_8_8_8_8,
10001											 GL_UNSIGNED_INT_8_8_8_8_REV,
10002											 GL_UNSIGNED_INT_10_10_10_2,
10003											 GL_UNSIGNED_INT_2_10_10_10_REV,
10004											 GL_UNSIGNED_INT_24_8,
10005											 GL_UNSIGNED_INT_10F_11F_11F_REV,
10006											 GL_UNSIGNED_INT_5_9_9_9_REV,
10007											 GL_FLOAT_32_UNSIGNED_INT_24_8_REV };
10008
10009	static const glw::GLuint all_types_count = sizeof(all_types) / sizeof(all_types[0]);
10010
10011	is_valid	   = true;
10012	m_type_invalid = 0;
10013
10014	while (is_valid)
10015	{
10016		is_valid = false;
10017		m_type_invalid++;
10018		for (glw::GLuint i = 0; i < all_types_count; ++i)
10019		{
10020			if (all_types[i] == m_type_invalid)
10021			{
10022				is_valid = true;
10023				break;
10024			}
10025		}
10026	}
10027
10028	/* Maximum texture size.*/
10029	gl.getIntegerv(GL_MAX_TEXTURE_SIZE, &m_max_texture_size);
10030	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");
10031
10032	glw::GLenum not_matching_format					   = GL_RED;
10033	glw::GLenum not_matching_internalformat_compressed = GL_COMPRESSED_RED;
10034
10035	/* 1D Compressed with a non matching format. We need to do all the allocation to get the correct image size */
10036	glw::GLuint to_1D_compressed_not_matching;
10037
10038	gl.createTextures(GL_TEXTURE_1D, 1, &to_1D_compressed_not_matching);
10039	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
10040
10041	gl.bindTexture(GL_TEXTURE_1D, to_1D_compressed_not_matching);
10042	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
10043
10044	gl.texImage1D(GL_TEXTURE_1D, 0, not_matching_internalformat_compressed, s_reference_width, 0, s_reference_format,
10045				  GL_UNSIGNED_BYTE, s_reference);
10046	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");
10047
10048	is_compressed = 0;
10049
10050	gl.getTexLevelParameteriv(GL_TEXTURE_1D, 0, GL_TEXTURE_COMPRESSED, &is_compressed);
10051	GLU_EXPECT_NO_ERROR(gl.getError(), "glTetTexLevelParameteriv has failed");
10052
10053	if (is_compressed)
10054	{
10055		gl.getTexLevelParameteriv(GL_TEXTURE_1D, 0, GL_TEXTURE_INTERNAL_FORMAT, &m_not_matching_compressed_1D_format);
10056		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
10057
10058		m_not_matching_compressed_1D_size = 0;
10059
10060		gl.getTexLevelParameteriv(GL_TEXTURE_1D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE,
10061								  &m_not_matching_compressed_1D_size);
10062		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
10063	}
10064
10065	gl.deleteTextures(1, &to_1D_compressed_not_matching);
10066	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
10067
10068	/* 2D Compressed with a non matching format. We need to do all the allocation to get the correct image size */
10069	glw::GLuint to_2D_compressed_not_matching;
10070
10071	gl.createTextures(GL_TEXTURE_2D, 1, &to_2D_compressed_not_matching);
10072	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
10073
10074	gl.bindTexture(GL_TEXTURE_2D, to_2D_compressed_not_matching);
10075	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
10076
10077	gl.texImage2D(GL_TEXTURE_2D, 0, not_matching_internalformat_compressed, s_reference_width, s_reference_height, 0,
10078				  not_matching_format, GL_UNSIGNED_BYTE, s_reference);
10079	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");
10080
10081	is_compressed = 0;
10082
10083	gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED, &is_compressed);
10084	GLU_EXPECT_NO_ERROR(gl.getError(), "glTetTexLevelParameteriv has failed");
10085
10086	if (is_compressed)
10087	{
10088		gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &m_not_matching_compressed_2D_format);
10089		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
10090
10091		m_not_matching_compressed_2D_size = 0;
10092
10093		gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE,
10094								  &m_not_matching_compressed_2D_size);
10095		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
10096	}
10097
10098	gl.deleteTextures(1, &to_2D_compressed_not_matching);
10099	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
10100
10101	/* 3D Compressed with a non matching format. We need to do all the allocation to get the correct image size */
10102	glw::GLuint to_3D_compressed_not_matching;
10103
10104	gl.createTextures(GL_TEXTURE_3D, 1, &to_3D_compressed_not_matching);
10105	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
10106
10107	gl.bindTexture(GL_TEXTURE_3D, to_3D_compressed_not_matching);
10108	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
10109
10110	gl.texImage3D(GL_TEXTURE_3D, 0, not_matching_internalformat_compressed, s_reference_width, s_reference_height,
10111				  s_reference_depth, 0, not_matching_format, GL_UNSIGNED_BYTE, s_reference);
10112	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage3D has failed");
10113
10114	is_compressed = 0;
10115
10116	gl.getTexLevelParameteriv(GL_TEXTURE_3D, 0, GL_TEXTURE_COMPRESSED, &is_compressed);
10117	GLU_EXPECT_NO_ERROR(gl.getError(), "glTetTexLevelParameteriv has failed");
10118
10119	if (is_compressed)
10120	{
10121		gl.getTexLevelParameteriv(GL_TEXTURE_3D, 0, GL_TEXTURE_INTERNAL_FORMAT, &m_not_matching_compressed_3D_format);
10122		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
10123
10124		m_not_matching_compressed_3D_size = 0;
10125
10126		gl.getTexLevelParameteriv(GL_TEXTURE_3D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE,
10127								  &m_not_matching_compressed_3D_size);
10128		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
10129	}
10130
10131	gl.deleteTextures(1, &to_3D_compressed_not_matching);
10132	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
10133}
10134
10135/** @brief Test (negative) of TextureSubImage1D
10136 *
10137 *  @return Test result.
10138 */
10139bool SubImageErrorsTest::Test1D()
10140{
10141	/* Shortcut for GL functionality. */
10142	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
10143
10144	/* Result. */
10145	bool is_ok = true;
10146
10147	/* Check that INVALID_OPERATION is generated by TextureSubImage1D if
10148	 texture is not the name of an existing texture object. */
10149	{
10150		gl.textureSubImage1D(m_to_invalid, 0, 0, s_reference_width, s_reference_format, s_reference_type, s_reference);
10151		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
10152								  "texture is not the name of an existing texture object.");
10153	}
10154
10155	/* Check that INVALID_ENUM is generated by TextureSubImage1D if format is
10156	 not an accepted format constant. */
10157	{
10158		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, m_format_invalid, s_reference_type, s_reference);
10159		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureSubImage1D",
10160								  "format is not an accepted format constant.");
10161	}
10162
10163	/* Check that INVALID_ENUM is generated by TextureSubImage1D if type is not
10164	 an accepted type constant. */
10165	{
10166		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, m_type_invalid, s_reference);
10167		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureSubImage1D",
10168								  "type is not an accepted type constant.");
10169	}
10170
10171	/* Check that INVALID_VALUE is generated by TextureSubImage1D if level is
10172	 less than 0. */
10173	{
10174		gl.textureSubImage1D(m_to_1D, -1, 0, s_reference_width, s_reference_format, s_reference_type, s_reference);
10175		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage1D", "level is less than 0.");
10176	}
10177
10178	/* Check that INVALID_VALUE may be generated by TextureSubImage1D if level
10179	 is greater than log2 max, where max is the returned value of
10180	 MAX_TEXTURE_SIZE. */
10181	{
10182		gl.textureSubImage1D(m_to_1D, m_max_texture_size, 0, s_reference_width, s_reference_format, s_reference_type,
10183							 s_reference);
10184		is_ok &=
10185			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage1D",
10186							 "level is greater than log2 max, where max is the returned value of MAX_TEXTURE_SIZE.");
10187	}
10188
10189	/* Check that INVALID_VALUE is generated by TextureSubImage1D if
10190	 xoffset<-b, or if (xoffset+width)>(w-b), where w is the TEXTURE_WIDTH,
10191	 and b is the width of the TEXTURE_BORDER of the texture image being
10192	 modified. Note that w includes twice the border width. */
10193	{
10194		gl.textureSubImage1D(m_to_1D, 0, -1, s_reference_width, s_reference_format, s_reference_type, s_reference);
10195		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage1D",
10196								  "xoffset<-b, where b is the width of the TEXTURE_BORDER.");
10197
10198		gl.textureSubImage1D(m_to_1D, 0, 1, s_reference_width + 1, s_reference_format, s_reference_type, s_reference);
10199		is_ok &= CheckErrorAndLog(
10200			m_context, GL_INVALID_VALUE, "glTextureSubImage1D",
10201			"(xoffset+width)>(w-b), where w is the TEXTURE_WIDTH, b is the width of the TEXTURE_BORDER.");
10202	}
10203
10204	/*Check that INVALID_VALUE is generated by TextureSubImage1D if width is less than 0. */
10205	{
10206#ifndef TURN_OFF_SUB_IMAGE_ERRORS_TEST_OF_NEGATIVE_WIDTH_HEIGHT_OR_DEPTH
10207		gl.textureSubImage1D(m_to_1D, 0, 0, -1, s_reference_format, s_reference_type, s_reference);
10208		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage1D", "width is less than 0.");
10209#endif
10210	}
10211
10212	/* Check that INVALID_OPERATION is generated by TextureSubImage1D if type
10213	 is one of UNSIGNED_BYTE_3_3_2, UNSIGNED_BYTE_2_3_3_REV,
10214	 UNSIGNED_SHORT_5_6_5, or UNSIGNED_SHORT_5_6_5_REV and format is not RGB. */
10215	{
10216		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_BYTE_3_3_2, s_reference);
10217		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
10218								  "type is UNSIGNED_BYTE_3_3_2 and format is not RGB.");
10219
10220		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_BYTE_2_3_3_REV,
10221							 s_reference);
10222		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
10223								  "type is UNSIGNED_BYTE_2_3_3_REV and format is not RGB.");
10224
10225		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_SHORT_5_6_5,
10226							 s_reference);
10227		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
10228								  "type is UNSIGNED_SHORT_5_6_5 and format is not RGB.");
10229
10230		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_SHORT_5_6_5_REV,
10231							 s_reference);
10232		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
10233								  "type is UNSIGNED_SHORT_5_6_5_REV and format is not RGB.");
10234	}
10235
10236	/* Check that INVALID_OPERATION is generated by TextureSubImage1D if type
10237	 is one of UNSIGNED_SHORT_4_4_4_4, UNSIGNED_SHORT_4_4_4_4_REV,
10238	 UNSIGNED_SHORT_5_5_5_1, UNSIGNED_SHORT_1_5_5_5_REV,
10239	 UNSIGNED_INT_8_8_8_8, UNSIGNED_INT_8_8_8_8_REV, UNSIGNED_INT_10_10_10_2,
10240	 or UNSIGNED_INT_2_10_10_10_REV and format is neither RGBA nor BGRA. */
10241	{
10242		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_SHORT_4_4_4_4,
10243							 s_reference);
10244		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
10245								  "type is UNSIGNED_SHORT_4_4_4_4 and format is neither RGBA nor BGRA.");
10246
10247		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_SHORT_4_4_4_4_REV,
10248							 s_reference);
10249		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
10250								  "type is UNSIGNED_SHORT_4_4_4_4_REV and format is neither RGBA nor BGRA.");
10251
10252		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_SHORT_5_5_5_1,
10253							 s_reference);
10254		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
10255								  "type is UNSIGNED_SHORT_5_5_5_1 and format is neither RGBA nor BGRA.");
10256
10257		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_SHORT_1_5_5_5_REV,
10258							 s_reference);
10259		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
10260								  "type is UNSIGNED_SHORT_1_5_5_5_REV and format is neither RGBA nor BGRA.");
10261
10262		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_INT_8_8_8_8,
10263							 s_reference);
10264		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
10265								  "type is UNSIGNED_INT_8_8_8_8 and format is neither RGBA nor BGRA.");
10266
10267		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_INT_8_8_8_8_REV,
10268							 s_reference);
10269		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
10270								  "type is UNSIGNED_INT_8_8_8_8_REV and format is neither RGBA nor BGRA.");
10271
10272		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_INT_10_10_10_2,
10273							 s_reference);
10274		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
10275								  "type is UNSIGNED_INT_10_10_10_2 and format is neither RGBA nor BGRA.");
10276
10277		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_INT_2_10_10_10_REV,
10278							 s_reference);
10279		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
10280								  "type is UNSIGNED_INT_2_10_10_10_REV and format is neither RGBA nor BGRA.");
10281	}
10282
10283	/* Check that INVALID_OPERATION is generated by TextureSubImage1D if a
10284	 non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target
10285	 and the buffer object's data store is currently mapped. */
10286	{
10287		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
10288		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10289
10290		gl.mapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE);
10291
10292		if (GL_NO_ERROR == gl.getError())
10293		{
10294			gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, s_reference_type, NULL);
10295			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
10296									  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and "
10297									  "the buffer object's data store is currently mapped.");
10298
10299			gl.unmapBuffer(GL_PIXEL_UNPACK_BUFFER);
10300			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10301
10302			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
10303			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10304		}
10305	}
10306
10307	/* Check that INVALID_OPERATION is generated by TextureSubImage1D if a
10308	 non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target
10309	 and the data would be unpacked from the buffer object such that the
10310	 memory reads required would exceed the data store size. */
10311	{
10312		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
10313		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10314
10315		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, s_reference_type,
10316							 glu::BufferOffsetAsPointer(s_reference_size * 2));
10317		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
10318								  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and the "
10319								  "data would be unpacked from the buffer object such that the memory reads required "
10320								  "would exceed the data store size.");
10321
10322		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
10323		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10324	}
10325
10326	/* Check that INVALID_OPERATION is generated by TextureSubImage1D if a
10327	 non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target
10328	 and pixels is not evenly divisible into the number of bytes needed to
10329	 store in memory a datum indicated by type. */
10330	{
10331		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
10332		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10333
10334		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, s_reference_type,
10335							 glu::BufferOffsetAsPointer(1));
10336		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
10337								  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and pixels "
10338								  "is not evenly divisible into the number of bytes needed to store in memory a datum "
10339								  "indicated by type.");
10340
10341		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
10342		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10343	}
10344
10345	return is_ok;
10346}
10347
10348/** @brief Test (negative) of TextureSubImage2D
10349 *
10350 *  @return Test result.
10351 */
10352bool SubImageErrorsTest::Test2D()
10353{
10354	/* Shortcut for GL functionality. */
10355	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
10356
10357	/* Result. */
10358	bool is_ok = true;
10359
10360	/* Check that INVALID_OPERATION is generated by TextureSubImage2D if
10361	 texture is not the name of an existing texture object. */
10362	{
10363		gl.textureSubImage2D(m_to_invalid, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
10364							 s_reference_type, s_reference);
10365		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
10366								  "texture is not the name of an existing texture object.");
10367	}
10368
10369	/* Check that INVALID_ENUM is generated by TextureSubImage2D if format is
10370	 not an accepted format constant. */
10371	{
10372		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, m_format_invalid,
10373							 s_reference_type, s_reference);
10374		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureSubImage2D",
10375								  "format is not an accepted format constant.");
10376	}
10377
10378	/* Check that INVALID_ENUM is generated by TextureSubImage2D if type is not
10379	 an accepted type constant. */
10380	{
10381		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
10382							 m_type_invalid, s_reference);
10383		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureSubImage2D",
10384								  "type is not an accepted type constant.");
10385	}
10386
10387	/* Check that INVALID_VALUE is generated by TextureSubImage2D if level is
10388	 less than 0. */
10389	{
10390		gl.textureSubImage2D(m_to_2D, -1, 0, 0, s_reference_width, s_reference_height, s_reference_format,
10391							 s_reference_type, s_reference);
10392		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage2D", "level is less than 0.");
10393	}
10394
10395	/* Check that INVALID_VALUE may be generated by TextureSubImage2D if level
10396	 is greater than log2 max, where max is the returned value of
10397	 MAX_TEXTURE_SIZE. */
10398	{
10399		gl.textureSubImage2D(m_to_2D, m_max_texture_size, 0, 0, s_reference_width, s_reference_height,
10400							 s_reference_format, s_reference_type, s_reference);
10401		is_ok &=
10402			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage2D",
10403							 "level is greater than log2 max, where max is the returned value of MAX_TEXTURE_SIZE.");
10404	}
10405
10406	/* Check that INVALID_VALUE may be generated by TextureSubImage2D if level
10407	 is greater than log2 max, where max is the returned value of
10408	 MAX_TEXTURE_SIZE.
10409	 Check that INVALID_VALUE is generated by TextureSubImage2D if
10410	 xoffset<-b, (xoffset+width)>(w-b), yoffset<-b, or
10411	 (yoffset+height)>(h-b), where w is the TEXTURE_WIDTH, h is the
10412	 TEXTURE_HEIGHT, and b is the border width of the texture image being
10413	 modified. Note that w and h include twice the border width. */
10414	{
10415		gl.textureSubImage2D(m_to_2D, 0, -1, 0, s_reference_width, s_reference_height, s_reference_format,
10416							 s_reference_type, s_reference);
10417		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage2D",
10418								  "xoffset<-b, where b is the width of the TEXTURE_BORDER.");
10419
10420		gl.textureSubImage2D(m_to_2D, 0, 1, 0, s_reference_width + 1, s_reference_height, s_reference_format,
10421							 s_reference_type, s_reference);
10422		is_ok &= CheckErrorAndLog(
10423			m_context, GL_INVALID_VALUE, "glTextureSubImage2D",
10424			"(xoffset+width)>(w-b), where w is the TEXTURE_WIDTH, b is the width of the TEXTURE_BORDER.");
10425
10426		gl.textureSubImage2D(m_to_2D, 0, 0, -1, s_reference_width, s_reference_height, s_reference_format,
10427							 s_reference_type, s_reference);
10428		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage2D",
10429								  "yoffset<-b, where b is the height of the TEXTURE_BORDER.");
10430
10431		gl.textureSubImage2D(m_to_2D, 0, 0, 1, s_reference_width + 1, s_reference_height, s_reference_format,
10432							 s_reference_type, s_reference);
10433		is_ok &= CheckErrorAndLog(
10434			m_context, GL_INVALID_VALUE, "glTextureSubImage2D",
10435			"(yoffset+height)>(h-b), where h is the TEXTURE_HEIGHT, b is the width of the TEXTURE_BORDER.");
10436	}
10437
10438	/*Check that INVALID_VALUE is generated by TextureSubImage2D if width or height is less than 0. */
10439	{
10440#ifndef TURN_OFF_SUB_IMAGE_ERRORS_TEST_OF_NEGATIVE_WIDTH_HEIGHT_OR_DEPTH
10441		gl.textureSubImage2D(m_to_2D, 0, 0, 0, -1, s_reference_height, s_reference_format, s_reference_type,
10442							 s_reference);
10443		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage2D", "width is less than 0.");
10444
10445		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, -1, s_reference_format, s_reference_type,
10446							 s_reference);
10447		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage2D", "height is less than 0.");
10448#endif
10449	}
10450
10451	/* Check that INVALID_OPERATION is generated by TextureSubImage2D if type
10452	 is one of UNSIGNED_BYTE_3_3_2, UNSIGNED_BYTE_2_3_3_REV,
10453	 UNSIGNED_SHORT_5_6_5, or UNSIGNED_SHORT_5_6_5_REV and format is not RGB. */
10454	{
10455		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
10456							 GL_UNSIGNED_BYTE_3_3_2, s_reference);
10457		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
10458								  "type is UNSIGNED_BYTE_3_3_2 and format is not RGB.");
10459
10460		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
10461							 GL_UNSIGNED_BYTE_2_3_3_REV, s_reference);
10462		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
10463								  "type is UNSIGNED_BYTE_2_3_3_REV and format is not RGB.");
10464
10465		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
10466							 GL_UNSIGNED_SHORT_5_6_5, s_reference);
10467		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
10468								  "type is UNSIGNED_SHORT_5_6_5 and format is not RGB.");
10469
10470		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
10471							 GL_UNSIGNED_SHORT_5_6_5_REV, s_reference);
10472		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
10473								  "type is UNSIGNED_SHORT_5_6_5_REV and format is not RGB.");
10474	}
10475
10476	/* Check that INVALID_OPERATION is generated by TextureSubImage2D if type
10477	 is one of UNSIGNED_SHORT_4_4_4_4, UNSIGNED_SHORT_4_4_4_4_REV,
10478	 UNSIGNED_SHORT_5_5_5_1, UNSIGNED_SHORT_1_5_5_5_REV,
10479	 UNSIGNED_INT_8_8_8_8, UNSIGNED_INT_8_8_8_8_REV, UNSIGNED_INT_10_10_10_2,
10480	 or UNSIGNED_INT_2_10_10_10_REV and format is neither RGBA nor BGRA. */
10481	{
10482		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
10483							 GL_UNSIGNED_SHORT_4_4_4_4, s_reference);
10484		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
10485								  "type is UNSIGNED_SHORT_4_4_4_4 and format is neither RGBA nor BGRA.");
10486
10487		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
10488							 GL_UNSIGNED_SHORT_4_4_4_4_REV, s_reference);
10489		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
10490								  "type is UNSIGNED_SHORT_4_4_4_4_REV and format is neither RGBA nor BGRA.");
10491
10492		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
10493							 GL_UNSIGNED_SHORT_5_5_5_1, s_reference);
10494		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
10495								  "type is UNSIGNED_SHORT_5_5_5_1 and format is neither RGBA nor BGRA.");
10496
10497		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
10498							 GL_UNSIGNED_SHORT_1_5_5_5_REV, s_reference);
10499		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
10500								  "type is UNSIGNED_SHORT_1_5_5_5_REV and format is neither RGBA nor BGRA.");
10501
10502		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
10503							 GL_UNSIGNED_INT_8_8_8_8, s_reference);
10504		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
10505								  "type is UNSIGNED_INT_8_8_8_8 and format is neither RGBA nor BGRA.");
10506
10507		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
10508							 GL_UNSIGNED_INT_8_8_8_8_REV, s_reference);
10509		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
10510								  "type is UNSIGNED_INT_8_8_8_8_REV and format is neither RGBA nor BGRA.");
10511
10512		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
10513							 GL_UNSIGNED_INT_10_10_10_2, s_reference);
10514		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
10515								  "type is UNSIGNED_INT_10_10_10_2 and format is neither RGBA nor BGRA.");
10516
10517		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
10518							 GL_UNSIGNED_INT_2_10_10_10_REV, s_reference);
10519		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
10520								  "type is UNSIGNED_INT_2_10_10_10_REV and format is neither RGBA nor BGRA.");
10521	}
10522
10523	/* Check that INVALID_OPERATION is generated by TextureSubImage2D if a
10524	 non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target
10525	 and the buffer object's data store is currently mapped. */
10526	{
10527		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
10528		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10529
10530		gl.mapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE);
10531
10532		if (GL_NO_ERROR == gl.getError())
10533		{
10534			gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
10535								 s_reference_type, NULL);
10536			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
10537									  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and "
10538									  "the buffer object's data store is currently mapped.");
10539
10540			gl.unmapBuffer(GL_PIXEL_UNPACK_BUFFER);
10541			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10542
10543			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
10544			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10545		}
10546	}
10547
10548	/* Check that INVALID_OPERATION is generated by TextureSubImage2D if a
10549	 non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target
10550	 and the data would be unpacked from the buffer object such that the
10551	 memory reads required would exceed the data store size. */
10552	{
10553		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
10554		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10555
10556		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
10557							 s_reference_type, glu::BufferOffsetAsPointer(s_reference_size * 2));
10558		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
10559								  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and the "
10560								  "data would be unpacked from the buffer object such that the memory reads required "
10561								  "would exceed the data store size.");
10562
10563		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
10564		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10565	}
10566
10567	/* Check that INVALID_OPERATION is generated by TextureSubImage2D if a
10568	 non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target
10569	 and pixels is not evenly divisible into the number of bytes needed to
10570	 store in memory a datum indicated by type. */
10571	{
10572		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
10573		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10574
10575		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
10576							 s_reference_type, glu::BufferOffsetAsPointer(1));
10577		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
10578								  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and pixels "
10579								  "is not evenly divisible into the number of bytes needed to store in memory a datum "
10580								  "indicated by type.");
10581
10582		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
10583		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10584	}
10585
10586	return is_ok;
10587}
10588
10589/** @brief Test (negative) of TextureSubImage3D
10590 *
10591 *  @return Test result.
10592 */
10593bool SubImageErrorsTest::Test3D()
10594{
10595	/* Shortcut for GL functionality. */
10596	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
10597
10598	/* Result. */
10599	bool is_ok = true;
10600
10601	/* Check that INVALID_OPERATION is generated by TextureSubImage3D if
10602	 texture is not the name of an existing texture object. */
10603	{
10604		gl.textureSubImage3D(m_to_invalid, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10605							 s_reference_format, s_reference_type, s_reference);
10606		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
10607								  "texture is not the name of an existing texture object.");
10608	}
10609
10610	/* Check that INVALID_ENUM is generated by TextureSubImage3D if format is
10611	 not an accepted format constant. */
10612	{
10613		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10614							 m_format_invalid, s_reference_type, s_reference);
10615		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureSubImage3D",
10616								  "format is not an accepted format constant.");
10617	}
10618
10619	/* Check that INVALID_ENUM is generated by TextureSubImage3D if type is not
10620	 an accepted type constant. */
10621	{
10622		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10623							 s_reference_format, m_type_invalid, s_reference);
10624		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureSubImage3D",
10625								  "type is not an accepted type constant.");
10626	}
10627
10628	/* Check that INVALID_VALUE is generated by TextureSubImage3D if level is
10629	 less than 0. */
10630	{
10631		gl.textureSubImage3D(m_to_3D, -1, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10632							 s_reference_format, s_reference_type, s_reference);
10633		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage3D", "level is less than 0.");
10634	}
10635
10636	/* Check that INVALID_VALUE may be generated by TextureSubImage1D if level
10637	 is greater than log2 max, where max is the returned value of
10638	 MAX_TEXTURE_SIZE. */
10639	{
10640		gl.textureSubImage3D(m_to_3D, m_max_texture_size, 0, 0, 0, s_reference_width, s_reference_height,
10641							 s_reference_depth, s_reference_format, s_reference_type, s_reference);
10642		is_ok &=
10643			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage3D",
10644							 "level is greater than log2 max, where max is the returned value of MAX_TEXTURE_SIZE.");
10645	}
10646
10647	/* Check that INVALID_VALUE is generated by TextureSubImage3D if
10648	 xoffset<-b, (xoffset+width)>(w-b), yoffset<-b, or
10649	 (yoffset+height)>(h-b), or zoffset<-b, or (zoffset+depth)>(d-b), where w
10650	 is the TEXTURE_WIDTH, h is the TEXTURE_HEIGHT, d is the TEXTURE_DEPTH
10651	 and b is the border width of the texture image being modified. Note
10652	 that w, h, and d include twice the border width. */
10653	{
10654		gl.textureSubImage3D(m_to_3D, 0, -1, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10655							 s_reference_format, s_reference_type, s_reference);
10656		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage3D",
10657								  "xoffset<-b, where b is the width of the TEXTURE_BORDER.");
10658
10659		gl.textureSubImage3D(m_to_3D, 0, 1, 0, 0, s_reference_width + 1, s_reference_height, s_reference_depth,
10660							 s_reference_format, s_reference_type, s_reference);
10661		is_ok &= CheckErrorAndLog(
10662			m_context, GL_INVALID_VALUE, "glTextureSubImage3D",
10663			"(xoffset+width)>(w-b), where w is the TEXTURE_WIDTH, b is the width of the TEXTURE_BORDER.");
10664
10665		gl.textureSubImage3D(m_to_3D, 0, 0, -1, 0, s_reference_width, s_reference_height, s_reference_depth,
10666							 s_reference_format, s_reference_type, s_reference);
10667		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage3D",
10668								  "yoffset<-b, where b is the width of the TEXTURE_BORDER.");
10669
10670		gl.textureSubImage3D(m_to_3D, 0, 0, 1, 0, s_reference_width + 1, s_reference_height, s_reference_depth,
10671							 s_reference_format, s_reference_type, s_reference);
10672		is_ok &= CheckErrorAndLog(
10673			m_context, GL_INVALID_VALUE, "glTextureSubImage3D",
10674			"(yoffset+height)>(h-b), where h is the TEXTURE_HEIGHT, b is the width of the TEXTURE_BORDER.");
10675
10676		gl.textureSubImage3D(m_to_3D, 0, 0, 0, -1, s_reference_width, s_reference_height, s_reference_depth,
10677							 s_reference_format, s_reference_type, s_reference);
10678		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage3D",
10679								  "zoffset<-b, where b is the depth of the TEXTURE_BORDER.");
10680
10681		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 1, s_reference_width + 1, s_reference_height, s_reference_depth,
10682							 s_reference_format, s_reference_type, s_reference);
10683		is_ok &= CheckErrorAndLog(
10684			m_context, GL_INVALID_VALUE, "glTextureSubImage3D",
10685			"(zoffset+width)>(d-b), where d is the TEXTURE_DEPTH, b is the width of the TEXTURE_BORDER.");
10686	}
10687
10688	/*Check that INVALID_VALUE is generated by TextureSubImage3D if width or height or depth is less than 0. */
10689	{
10690#ifndef TURN_OFF_SUB_IMAGE_ERRORS_TEST_OF_NEGATIVE_WIDTH_HEIGHT_OR_DEPTH
10691		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, -1, s_reference_height, s_reference_depth, s_reference_format,
10692							 s_reference_type, s_reference);
10693		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage1D", "width is less than 0.");
10694
10695		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, -1, s_reference_depth, s_reference_format,
10696							 s_reference_type, s_reference);
10697		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage1D", "height is less than 0.");
10698
10699		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, -1, s_reference_format,
10700							 s_reference_type, s_reference);
10701		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage1D", "depth is less than 0.");
10702#endif
10703	}
10704
10705	/* Check that INVALID_OPERATION is generated by TextureSubImage3D if type
10706	 is one of UNSIGNED_BYTE_3_3_2, UNSIGNED_BYTE_2_3_3_REV,
10707	 UNSIGNED_SHORT_5_6_5, or UNSIGNED_SHORT_5_6_5_REV and format is not RGB. */
10708	{
10709		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10710							 s_reference_format, GL_UNSIGNED_BYTE_3_3_2, s_reference);
10711		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
10712								  "type is UNSIGNED_BYTE_3_3_2 and format is not RGB.");
10713
10714		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10715							 s_reference_format, GL_UNSIGNED_BYTE_2_3_3_REV, s_reference);
10716		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
10717								  "type is UNSIGNED_BYTE_2_3_3_REV and format is not RGB.");
10718
10719		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10720							 s_reference_format, GL_UNSIGNED_SHORT_5_6_5, s_reference);
10721		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
10722								  "type is UNSIGNED_SHORT_5_6_5 and format is not RGB.");
10723
10724		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10725							 s_reference_format, GL_UNSIGNED_SHORT_5_6_5_REV, s_reference);
10726		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
10727								  "type is UNSIGNED_SHORT_5_6_5_REV and format is not RGB.");
10728	}
10729
10730	/* Check that INVALID_OPERATION is generated by TextureSubImage3D if type
10731	 is one of UNSIGNED_SHORT_4_4_4_4, UNSIGNED_SHORT_4_4_4_4_REV,
10732	 UNSIGNED_SHORT_5_5_5_1, UNSIGNED_SHORT_1_5_5_5_REV,
10733	 UNSIGNED_INT_8_8_8_8, UNSIGNED_INT_8_8_8_8_REV, UNSIGNED_INT_10_10_10_2,
10734	 or UNSIGNED_INT_2_10_10_10_REV and format is neither RGBA nor BGRA. */
10735	{
10736		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10737							 s_reference_format, GL_UNSIGNED_SHORT_4_4_4_4, s_reference);
10738		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
10739								  "type is UNSIGNED_SHORT_4_4_4_4 and format is neither RGBA nor BGRA.");
10740
10741		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10742							 s_reference_format, GL_UNSIGNED_SHORT_4_4_4_4_REV, s_reference);
10743		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
10744								  "type is UNSIGNED_SHORT_4_4_4_4_REV and format is neither RGBA nor BGRA.");
10745
10746		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10747							 s_reference_format, GL_UNSIGNED_SHORT_5_5_5_1, s_reference);
10748		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
10749								  "type is UNSIGNED_SHORT_5_5_5_1 and format is neither RGBA nor BGRA.");
10750
10751		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10752							 s_reference_format, GL_UNSIGNED_SHORT_1_5_5_5_REV, s_reference);
10753		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
10754								  "type is UNSIGNED_SHORT_1_5_5_5_REV and format is neither RGBA nor BGRA.");
10755
10756		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10757							 s_reference_format, GL_UNSIGNED_INT_8_8_8_8, s_reference);
10758		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
10759								  "type is UNSIGNED_INT_8_8_8_8 and format is neither RGBA nor BGRA.");
10760
10761		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10762							 s_reference_format, GL_UNSIGNED_INT_8_8_8_8_REV, s_reference);
10763		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
10764								  "type is UNSIGNED_INT_8_8_8_8_REV and format is neither RGBA nor BGRA.");
10765
10766		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10767							 s_reference_format, GL_UNSIGNED_INT_10_10_10_2, s_reference);
10768		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
10769								  "type is UNSIGNED_INT_10_10_10_2 and format is neither RGBA nor BGRA.");
10770
10771		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10772							 s_reference_format, GL_UNSIGNED_INT_2_10_10_10_REV, s_reference);
10773		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
10774								  "type is UNSIGNED_INT_2_10_10_10_REV and format is neither RGBA nor BGRA.");
10775	}
10776
10777	/* Check that INVALID_OPERATION is generated by TextureSubImage3D if a
10778	 non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target
10779	 and the buffer object's data store is currently mapped. */
10780	{
10781		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
10782		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10783
10784		gl.mapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE);
10785
10786		if (GL_NO_ERROR == gl.getError())
10787		{
10788			gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10789								 s_reference_format, s_reference_type, NULL);
10790			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
10791									  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and "
10792									  "the buffer object's data store is currently mapped.");
10793
10794			gl.unmapBuffer(GL_PIXEL_UNPACK_BUFFER);
10795			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10796
10797			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
10798			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10799		}
10800	}
10801
10802	/* Check that INVALID_OPERATION is generated by TextureSubImage3D if a
10803	 non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target
10804	 and the data would be unpacked from the buffer object such that the
10805	 memory reads required would exceed the data store size. */
10806	{
10807		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
10808		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10809
10810		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10811							 s_reference_format, s_reference_type, glu::BufferOffsetAsPointer(s_reference_size * 2));
10812		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
10813								  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and the "
10814								  "data would be unpacked from the buffer object such that the memory reads required "
10815								  "would exceed the data store size.");
10816
10817		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
10818		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10819	}
10820
10821	/* Check that INVALID_OPERATION is generated by TextureSubImage3D if a
10822	 non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target
10823	 and pixels is not evenly divisible into the number of bytes needed to
10824	 store in memory a datum indicated by type. */
10825	{
10826		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
10827		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10828
10829		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
10830							 s_reference_format, s_reference_type, glu::BufferOffsetAsPointer(1));
10831		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
10832								  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and pixels "
10833								  "is not evenly divisible into the number of bytes needed to store in memory a datum "
10834								  "indicated by type.");
10835
10836		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
10837		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10838	}
10839
10840	return is_ok;
10841}
10842
10843/** @brief Test (negative) of TextureSubImage1DCompressed
10844 *
10845 *  @return Test result.
10846 */
10847bool SubImageErrorsTest::Test1DCompressed()
10848{
10849	/* Shortcut for GL functionality. */
10850	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
10851
10852	/* Result. */
10853	bool is_ok = true;
10854
10855	/* Do tests only if compressed 1D textures are supported. */
10856	if (DE_NULL != m_reference_compressed_1D)
10857	{
10858		/* Check that INVALID_OPERATION is generated by CompressedTextureSubImage1D
10859		 if texture is not the name of an existing texture object. */
10860		{
10861			gl.compressedTextureSubImage1D(m_to_invalid, 0, 0, s_reference_width, m_reference_compressed_1D_format,
10862										   m_reference_compressed_1D_size, m_reference_compressed_1D);
10863			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage1D",
10864									  "texture is not the name of an existing texture object.");
10865		}
10866
10867		/* Check that INVALID_ENUM is generated by CompressedTextureSubImage1D if
10868		 internalformat is not one of the generic compressed internal formats:
10869		 COMPRESSED_RED, COMPRESSED_RG, COMPRESSED_RGB, COMPRESSED_RGBA.
10870		 COMPRESSED_SRGB, or COMPRESSED_SRGB_ALPHA. */
10871		{
10872			/* GL_COMPRESSED_RG_RGTC2 is not 1D as specification says. */
10873			gl.compressedTextureSubImage1D(m_to_1D_compressed, 0, 0, s_reference_width, GL_COMPRESSED_RG_RGTC2,
10874										   m_reference_compressed_1D_size, m_reference_compressed_1D);
10875			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glCompressedTextureSubImage1D",
10876									  "internalformat is of the generic compressed internal formats: COMPRESSED_RED, "
10877									  "COMPRESSED_RG, COMPRESSED_RGB, COMPRESSED_RGBA. COMPRESSED_SRGB, or "
10878									  "COMPRESSED_SRGB_ALPHA.");
10879		}
10880
10881		/* Check that INVALID_OPERATION is generated if format does not match the
10882		 internal format of the texture image being modified, since these
10883		 commands do not provide for image format conversion. */
10884		{
10885			gl.compressedTextureSubImage1D(m_to_1D_compressed, 0, 0, s_reference_width,
10886										   m_not_matching_compressed_1D_format, m_not_matching_compressed_1D_size,
10887										   m_reference_compressed_1D);
10888			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage1D",
10889									  "format does not match the internal format of the texture image being modified, "
10890									  "since these commands do not provide for image format conversion.");
10891		}
10892
10893		/* Check that INVALID_VALUE is generated by CompressedTextureSubImage1D if
10894		 imageSize is not consistent with the format, dimensions, and contents of
10895		 the specified compressed image data. */
10896		{
10897			gl.compressedTextureSubImage1D(m_to_1D_compressed, 0, 0, s_reference_width,
10898										   m_reference_compressed_1D_format, m_reference_compressed_1D_size - 1,
10899										   m_reference_compressed_1D);
10900			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCompressedTextureSubImage1D",
10901									  "imageSize is not consistent with the format, dimensions, and contents of the "
10902									  "specified compressed image data.");
10903		}
10904
10905		/* Check that INVALID_OPERATION is generated by CompressedTextureSubImage1D
10906		 if a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER
10907		 target and the buffer object's data store is currently mapped. */
10908		{
10909			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
10910			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10911
10912			gl.mapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE);
10913
10914			if (GL_NO_ERROR == gl.getError())
10915			{
10916				gl.compressedTextureSubImage1D(m_to_1D_compressed, 0, 0, s_reference_width,
10917											   m_reference_compressed_1D_format, m_reference_compressed_1D_size, NULL);
10918				is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage1D",
10919										  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target "
10920										  "and the buffer object's data store is currently mapped.");
10921
10922				gl.unmapBuffer(GL_PIXEL_UNPACK_BUFFER);
10923				GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10924
10925				gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
10926				GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10927			}
10928		}
10929
10930		/* Check that INVALID_OPERATION is generated by CompressedTextureSubImage1D
10931		 if a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER
10932		 target and the data would be unpacked from the buffer object such that
10933		 the memory reads required would exceed the data store size. */
10934		{
10935			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
10936			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10937
10938			gl.compressedTextureSubImage1D(m_to_1D_compressed, 0, 0, s_reference_width,
10939										   m_reference_compressed_1D_format, m_reference_compressed_1D_size,
10940										   glu::BufferOffsetAsPointer(s_reference_size * 2));
10941			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage1D",
10942									  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and "
10943									  "the buffer object's data store is currently mapped.");
10944
10945			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
10946			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
10947		}
10948	}
10949
10950	return is_ok;
10951}
10952
10953/** @brief Test (negative) of TextureSubImage2DCompressed
10954 *
10955 *  @return Test result.
10956 */
10957bool SubImageErrorsTest::Test2DCompressed()
10958{
10959	/* Shortcut for GL functionality. */
10960	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
10961
10962	/* Result. */
10963	bool is_ok = true;
10964
10965	/* Do tests only if compressed 2D textures are supported. */
10966	if (DE_NULL != m_reference_compressed_2D)
10967	{
10968		/* Check that INVALID_OPERATION is generated by CompressedTextureSubImage2D
10969		 if texture is not the name of an existing texture object. */
10970		{
10971			gl.compressedTextureSubImage2D(m_to_invalid, 0, 0, 0, s_reference_width, s_reference_height,
10972										   m_reference_compressed_2D_format, m_reference_compressed_2D_size,
10973										   m_reference_compressed_2D);
10974			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage2D",
10975									  "texture is not the name of an existing texture object.");
10976		}
10977
10978		/* Check that INVALID_ENUM is generated by CompressedTextureSubImage2D if
10979		 internalformat is of the generic compressed internal formats:
10980		 COMPRESSED_RED, COMPRESSED_RG, COMPRESSED_RGB, COMPRESSED_RGBA.
10981		 COMPRESSED_SRGB, or COMPRESSED_SRGB_ALPHA. */
10982		{
10983			gl.compressedTextureSubImage2D(m_to_2D_compressed, 0, 0, 0, s_reference_width, s_reference_height,
10984										   GL_COMPRESSED_RG, m_reference_compressed_2D_size, m_reference_compressed_2D);
10985			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glCompressedTextureSubImage2D",
10986									  "internalformat is of the generic compressed internal formats: COMPRESSED_RED, "
10987									  "COMPRESSED_RG, COMPRESSED_RGB, COMPRESSED_RGBA. COMPRESSED_SRGB, or "
10988									  "COMPRESSED_SRGB_ALPHA.");
10989		}
10990
10991		/* Check that INVALID_OPERATION is generated if format does not match the
10992		 internal format of the texture image being modified, since these
10993		 commands do not provide for image format conversion. */
10994		{
10995			gl.compressedTextureSubImage2D(m_to_2D_compressed, 0, 0, 0, s_reference_width, s_reference_height,
10996										   m_not_matching_compressed_2D_format, m_not_matching_compressed_2D_size,
10997										   m_reference_compressed_2D);
10998			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage2D",
10999									  "format does not match the internal format of the texture image being modified, "
11000									  "since these commands do not provide for image format conversion.");
11001		}
11002
11003		/* Check that INVALID_VALUE is generated by CompressedTextureSubImage2D if
11004		 imageSize is not consistent with the format, dimensions, and contents of
11005		 the specified compressed image data. */
11006		{
11007			gl.compressedTextureSubImage2D(m_to_2D_compressed, 0, 0, 0, s_reference_width, s_reference_height,
11008										   m_reference_compressed_2D_format, m_reference_compressed_2D_size - 1,
11009										   m_reference_compressed_2D);
11010			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCompressedTextureSubImage2D",
11011									  "imageSize is not consistent with the format, dimensions, and contents of the "
11012									  "specified compressed image data.");
11013		}
11014
11015		/* Check that INVALID_OPERATION is generated by CompressedTextureSubImage2D
11016		 if a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER
11017		 target and the buffer object's data store is currently mapped. */
11018		{
11019			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
11020			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
11021
11022			gl.mapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE);
11023
11024			if (GL_NO_ERROR == gl.getError())
11025			{
11026				gl.compressedTextureSubImage2D(m_to_2D_compressed, 0, 0, 0, s_reference_width, s_reference_height,
11027											   m_reference_compressed_2D_format, m_reference_compressed_2D_size, NULL);
11028				is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage2D",
11029										  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target "
11030										  "and the buffer object's data store is currently mapped.");
11031
11032				gl.unmapBuffer(GL_PIXEL_UNPACK_BUFFER);
11033				GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
11034
11035				gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
11036				GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
11037			}
11038		}
11039
11040		/* Check that INVALID_OPERATION is generated by CompressedTextureSubImage2D
11041		 if a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER
11042		 target and the data would be unpacked from the buffer object such that
11043		 the memory reads required would exceed the data store size. */
11044		{
11045			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
11046			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
11047
11048			gl.compressedTextureSubImage2D(m_to_2D_compressed, 0, 0, 0, s_reference_width, s_reference_height,
11049										   m_reference_compressed_2D_format, m_reference_compressed_2D_size,
11050										   glu::BufferOffsetAsPointer(s_reference_size * 2));
11051			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage2D",
11052									  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and "
11053									  "the buffer object's data store is currently mapped.");
11054
11055			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
11056			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
11057		}
11058
11059		/* Check that INVALID_OPERATION is generated by CompressedTextureSubImage2D
11060		 if the effective target is TEXTURE_RECTANGLE. */
11061		if (DE_NULL !=
11062			m_reference_compressed_rectangle) /* Do test only if rectangle compressed texture is supported by the implementation. */
11063		{
11064			gl.compressedTextureSubImage2D(m_to_rectangle_compressed, 0, 0, 0, s_reference_width, s_reference_height,
11065										   m_reference_compressed_rectangle_format,
11066										   m_reference_compressed_rectangle_size, m_reference_compressed_rectangle);
11067
11068			if (m_context.getContextInfo().isExtensionSupported("GL_NV_texture_rectangle_compressed"))
11069			{
11070				is_ok &= CheckErrorAndLog(m_context, GL_NO_ERROR, "glCompressedTextureSubImage2D",
11071										  "a rectangle texture object is used with this function.");
11072			}
11073			else
11074			{
11075				is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage2D",
11076										  "a rectangle texture object is used with this function.");
11077			}
11078		}
11079	}
11080
11081	return is_ok;
11082}
11083
11084/** @brief Test (negative) of TextureSubImage3DCompressed
11085 *
11086 *  @return Test result.
11087 */
11088bool SubImageErrorsTest::Test3DCompressed()
11089{
11090	/* Shortcut for GL functionality. */
11091	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
11092
11093	/* Result. */
11094	bool is_ok = true;
11095
11096	/* Do tests only if compressed 3D textures are supported. */
11097	if (DE_NULL != m_reference_compressed_3D)
11098	{
11099		/* Check that INVALID_OPERATION is generated by CompressedTextureSubImage3D
11100		 if texture is not the name of an existing texture object. */
11101		{
11102			gl.compressedTextureSubImage3D(m_to_invalid, 0, 0, 0, 0, s_reference_width, s_reference_height,
11103										   s_reference_depth, m_reference_compressed_3D_format,
11104										   m_reference_compressed_3D_size, m_reference_compressed_3D);
11105			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage3D",
11106									  "texture is not the name of an existing texture object.");
11107		}
11108
11109		/* Check that INVALID_ENUM is generated by CompressedTextureSubImage3D if
11110		 internalformat is of the generic compressed internal formats:
11111		 COMPRESSED_RED, COMPRESSED_RG, COMPRESSED_RGB, COMPRESSED_RGBA.
11112		 COMPRESSED_SRGB, or COMPRESSED_SRGB_ALPHA. */
11113		{
11114			gl.compressedTextureSubImage3D(m_to_3D_compressed, 0, 0, 0, 0, s_reference_width, s_reference_height,
11115										   s_reference_depth, GL_COMPRESSED_RG, m_reference_compressed_3D_size,
11116										   m_reference_compressed_3D);
11117			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glCompressedTextureSubImage3D",
11118									  "internalformat is of the generic compressed internal formats: COMPRESSED_RED, "
11119									  "COMPRESSED_RG, COMPRESSED_RGB, COMPRESSED_RGBA. COMPRESSED_SRGB, or "
11120									  "COMPRESSED_SRGB_ALPHA.");
11121		}
11122
11123		/* Check that INVALID_OPERATION is generated if format does not match the
11124		 internal format of the texture image being modified, since these
11125		 commands do not provide for image format conversion. */
11126		{
11127			gl.compressedTextureSubImage3D(m_to_3D_compressed, 0, 0, 0, 0, s_reference_width, s_reference_height,
11128										   s_reference_depth, m_not_matching_compressed_3D_format,
11129										   m_not_matching_compressed_3D_size, m_reference_compressed_3D);
11130			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage3D",
11131									  "format does not match the internal format of the texture image being modified, "
11132									  "since these commands do not provide for image format conversion.");
11133		}
11134
11135		/* Check that INVALID_VALUE is generated by CompressedTextureSubImage3D if
11136		 imageSize is not consistent with the format, dimensions, and contents of
11137		 the specified compressed image data. */
11138		{
11139			gl.compressedTextureSubImage3D(m_to_3D_compressed, 0, 0, 0, 0, s_reference_width, s_reference_height,
11140										   s_reference_depth, m_reference_compressed_3D_format,
11141										   m_reference_compressed_3D_size - 1, m_reference_compressed_3D);
11142			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCompressedTextureSubImage3D",
11143									  "imageSize is not consistent with the format, dimensions, and contents of the "
11144									  "specified compressed image data.");
11145		}
11146
11147		/* Check that INVALID_OPERATION is generated by CompressedTextureSubImage3D
11148		 if a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER
11149		 target and the buffer object's data store is currently mapped. */
11150		{
11151			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
11152			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
11153
11154			gl.mapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE);
11155
11156			if (GL_NO_ERROR == gl.getError())
11157			{
11158				gl.compressedTextureSubImage3D(m_to_3D_compressed, 0, 0, 0, 0, s_reference_width, s_reference_height,
11159											   s_reference_depth, m_reference_compressed_3D_format,
11160											   m_reference_compressed_3D_size, NULL);
11161				is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage3D",
11162										  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target "
11163										  "and the buffer object's data store is currently mapped.");
11164
11165				gl.unmapBuffer(GL_PIXEL_UNPACK_BUFFER);
11166				GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
11167
11168				gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
11169				GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
11170			}
11171		}
11172
11173		/* Check that INVALID_OPERATION is generated by CompressedTextureSubImage3D
11174		 if a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER
11175		 target and the data would be unpacked from the buffer object such that
11176		 the memory reads required would exceed the data store size. */
11177		{
11178			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
11179			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
11180
11181			gl.compressedTextureSubImage3D(m_to_3D_compressed, 0, 0, 0, 0, s_reference_width, s_reference_height,
11182										   s_reference_depth, m_reference_compressed_3D_format,
11183										   m_reference_compressed_3D_size, glu::BufferOffsetAsPointer(s_reference_size * 2));
11184			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage3D",
11185									  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and "
11186									  "the buffer object's data store is currently mapped.");
11187
11188			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
11189			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
11190		}
11191	}
11192
11193	return is_ok;
11194}
11195
11196/** @brief Clean GL objects, test variables and GL errors.
11197 */
11198void SubImageErrorsTest::Clean()
11199{
11200	/* Shortcut for GL functionality. */
11201	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
11202
11203	/* Cleanup. */
11204	if (m_to_1D_empty)
11205	{
11206		gl.deleteTextures(1, &m_to_1D_empty);
11207
11208		m_to_1D_empty = 0;
11209	}
11210
11211	if (m_to_2D_empty)
11212	{
11213		gl.deleteTextures(1, &m_to_2D_empty);
11214
11215		m_to_2D_empty = 0;
11216	}
11217
11218	if (m_to_3D_empty)
11219	{
11220		gl.deleteTextures(1, &m_to_3D_empty);
11221
11222		m_to_3D_empty = 0;
11223	}
11224
11225	if (m_to_1D)
11226	{
11227		gl.deleteTextures(1, &m_to_1D);
11228
11229		m_to_1D = 0;
11230	}
11231
11232	if (m_to_2D)
11233	{
11234		gl.deleteTextures(1, &m_to_2D);
11235
11236		m_to_2D = 0;
11237	}
11238
11239	if (m_to_3D)
11240	{
11241		gl.deleteTextures(1, &m_to_3D);
11242
11243		m_to_3D = 0;
11244	}
11245
11246	if (m_to_1D_compressed)
11247	{
11248		gl.deleteTextures(1, &m_to_1D_compressed);
11249
11250		m_to_1D_compressed = 0;
11251	}
11252
11253	if (m_to_2D_compressed)
11254	{
11255		gl.deleteTextures(1, &m_to_2D_compressed);
11256
11257		m_to_2D_compressed = 0;
11258	}
11259
11260	if (m_to_3D_compressed)
11261	{
11262		gl.deleteTextures(1, &m_to_3D_compressed);
11263
11264		m_to_3D_compressed = 0;
11265	}
11266
11267	if (m_to_rectangle_compressed)
11268	{
11269		gl.deleteTextures(1, &m_to_rectangle_compressed);
11270
11271		m_to_rectangle_compressed = 0;
11272	}
11273
11274	if (m_bo)
11275	{
11276		gl.deleteBuffers(1, &m_bo);
11277
11278		m_bo = 0;
11279	}
11280
11281	m_to_invalid	   = 0;
11282	m_format_invalid   = 0;
11283	m_type_invalid	 = 0;
11284	m_max_texture_size = 1;
11285
11286	if (DE_NULL != m_reference_compressed_1D)
11287	{
11288		delete[] m_reference_compressed_1D;
11289
11290		m_reference_compressed_1D = NULL;
11291	}
11292
11293	if (DE_NULL != m_reference_compressed_2D)
11294	{
11295		delete[] m_reference_compressed_2D;
11296
11297		m_reference_compressed_2D = NULL;
11298	}
11299
11300	if (DE_NULL != m_reference_compressed_3D)
11301	{
11302		delete[] m_reference_compressed_3D;
11303
11304		m_reference_compressed_3D = NULL;
11305	}
11306
11307	if (DE_NULL != m_reference_compressed_rectangle)
11308	{
11309		delete[] m_reference_compressed_rectangle;
11310
11311		m_reference_compressed_rectangle = NULL;
11312	}
11313
11314	m_reference_compressed_1D_format		= 0;
11315	m_reference_compressed_2D_format		= 0;
11316	m_reference_compressed_3D_format		= 0;
11317	m_reference_compressed_rectangle_format = 0;
11318	m_reference_compressed_1D_size			= 0;
11319	m_reference_compressed_2D_size			= 0;
11320	m_reference_compressed_3D_size			= 0;
11321	m_reference_compressed_rectangle_size   = 0;
11322	m_not_matching_compressed_1D_format		= 0;
11323	m_not_matching_compressed_1D_size		= 0;
11324	m_not_matching_compressed_2D_format		= 0;
11325	m_not_matching_compressed_2D_size		= 0;
11326	m_not_matching_compressed_3D_format		= 0;
11327	m_not_matching_compressed_3D_size		= 0;
11328
11329	while (GL_NO_ERROR != gl.getError())
11330		;
11331}
11332
11333/** Reference data */
11334const glw::GLushort SubImageErrorsTest::s_reference[] = {
11335	0x0,  0x0,  0x0,  0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
11336	0x88, 0x0,  0x15, 0xff, 0xed, 0x1c, 0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0,  0xff,
11337	0xc8, 0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0xff,
11338	0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc, 0xff, 0x0,  0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff,
11339
11340	0x0,  0x0,  0x0,  0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
11341	0x88, 0x0,  0x15, 0xff, 0xed, 0x1c, 0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0,  0xff,
11342	0xc8, 0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0xff,
11343	0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc, 0xff, 0x0,  0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff,
11344
11345	0x0,  0x0,  0x0,  0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
11346	0x88, 0x0,  0x15, 0xff, 0xed, 0x1c, 0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0,  0xff,
11347	0xc8, 0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0xff,
11348	0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc, 0xff, 0x0,  0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff,
11349
11350	0x0,  0x0,  0x0,  0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
11351	0x88, 0x0,  0x15, 0xff, 0xed, 0x1c, 0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0,  0xff,
11352	0xc8, 0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0xff,
11353	0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc, 0xff, 0x0,  0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff
11354};
11355
11356/** Reference data parameters. */
11357const glw::GLuint SubImageErrorsTest::s_reference_size						= sizeof(s_reference);
11358const glw::GLuint SubImageErrorsTest::s_reference_width						= 4;
11359const glw::GLuint SubImageErrorsTest::s_reference_height					= 4;
11360const glw::GLuint SubImageErrorsTest::s_reference_depth						= 4;
11361const glw::GLenum SubImageErrorsTest::s_reference_internalformat			= GL_RG8;
11362const glw::GLenum SubImageErrorsTest::s_reference_internalformat_compressed = GL_COMPRESSED_RG;
11363const glw::GLenum SubImageErrorsTest::s_reference_format = GL_RG; /* !Must not be a RGB, RGBA, or BGRA */
11364const glw::GLenum SubImageErrorsTest::s_reference_type   = GL_UNSIGNED_SHORT;
11365
11366/******************************** Copy Errors Test Implementation   ********************************/
11367
11368/** @brief Copy Errors Test constructor.
11369 *
11370 *  @param [in] context     OpenGL context.
11371 */
11372CopyErrorsTest::CopyErrorsTest(deqp::Context& context)
11373	: deqp::TestCase(context, "textures_copy_errors", "Texture Copy Errors Test")
11374	, m_fbo(0)
11375	, m_fbo_ms(0)
11376	, m_fbo_incomplete(0)
11377	, m_to_src(0)
11378	, m_to_src_ms(0)
11379	, m_to_1D_dst(0)
11380	, m_to_2D_dst(0)
11381	, m_to_3D_dst(0)
11382	, m_to_invalid(0)
11383{
11384	/* Intentionally left blank. */
11385}
11386
11387/** @brief Iterate Copy Errors Test cases.
11388 *
11389 *  @return Iteration result.
11390 */
11391tcu::TestNode::IterateResult CopyErrorsTest::iterate()
11392{
11393	/* Get context setup. */
11394	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
11395	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
11396
11397	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
11398	{
11399		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
11400
11401		return STOP;
11402	}
11403
11404	/* Running tests. */
11405	bool is_ok	= true;
11406	bool is_error = false;
11407
11408	try
11409	{
11410		Prepare();
11411
11412		is_ok &= Test1D();
11413		is_ok &= Test2D();
11414		is_ok &= Test3D();
11415	}
11416	catch (...)
11417	{
11418		is_ok	= false;
11419		is_error = true;
11420	}
11421
11422	/* Cleanup. */
11423	Clean();
11424
11425	/* Result's setup. */
11426	if (is_ok)
11427	{
11428		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
11429	}
11430	else
11431	{
11432		if (is_error)
11433		{
11434			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
11435		}
11436		else
11437		{
11438			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
11439		}
11440	}
11441
11442	return STOP;
11443}
11444
11445/** @brief Prepare test's objects and values.
11446 */
11447void CopyErrorsTest::Prepare()
11448{
11449	/* Shortcut for GL functionality. */
11450	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
11451
11452	/* Auxiliary objects setup. */
11453
11454	/* Framebuffer. */
11455	gl.genFramebuffers(1, &m_fbo);
11456	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
11457
11458	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
11459	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11460
11461	gl.createTextures(GL_TEXTURE_2D, 1, &m_to_src);
11462	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
11463
11464	gl.textureStorage2D(m_to_src, 1, s_internalformat, s_width, s_height);
11465	GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2D has failed");
11466
11467	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_to_src, 0);
11468	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture1D call failed.");
11469
11470	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
11471	{
11472		throw 0;
11473	}
11474
11475	gl.viewport(0, 0, s_width, s_height);
11476	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
11477
11478	gl.clear(GL_COLOR_BUFFER_BIT);
11479	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed.");
11480
11481	/* Framebuffer Multisample. */
11482	gl.genFramebuffers(1, &m_fbo_ms);
11483	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
11484
11485	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_ms);
11486	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11487
11488	gl.createTextures(GL_TEXTURE_2D_MULTISAMPLE, 1, &m_to_src_ms);
11489	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
11490
11491	gl.textureStorage2DMultisample(m_to_src_ms, 1, s_internalformat, s_width, s_height, false);
11492	GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2DMultisample has failed");
11493
11494	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, m_to_src_ms, 0);
11495	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture1D call failed.");
11496
11497	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
11498	{
11499		throw 0;
11500	}
11501
11502	gl.viewport(0, 0, s_width, s_height);
11503	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
11504
11505	gl.clear(GL_COLOR_BUFFER_BIT);
11506	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed.");
11507
11508	/* Framebuffer Incomplete. */
11509	gl.createFramebuffers(1, &m_fbo_incomplete);
11510	GLU_EXPECT_NO_ERROR(gl.getError(), "glcreateFramebuffers call failed.");
11511
11512	/* 1D */
11513	gl.createTextures(GL_TEXTURE_1D, 1, &m_to_1D_dst);
11514	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
11515
11516	gl.textureStorage1D(m_to_1D_dst, 1, s_internalformat, s_width);
11517	GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2D has failed");
11518
11519	/* 2D */
11520	gl.createTextures(GL_TEXTURE_2D, 1, &m_to_2D_dst);
11521	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
11522
11523	gl.textureStorage2D(m_to_2D_dst, 1, s_internalformat, s_width, s_height);
11524	GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2D has failed");
11525
11526	/* 3D */
11527	gl.createTextures(GL_TEXTURE_3D, 1, &m_to_3D_dst);
11528	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
11529
11530	gl.textureStorage3D(m_to_3D_dst, 1, s_internalformat, s_width, s_height, s_depth);
11531	GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2D has failed");
11532
11533	/* invalid texture object */
11534	while (gl.isTexture(++m_to_invalid))
11535		;
11536	GLU_EXPECT_NO_ERROR(gl.getError(), "glIsTexture has failed");
11537}
11538
11539/** @brief Test (negative) of CopyTextureSubImage1D
11540 *
11541 *  @return Test result.
11542 */
11543bool CopyErrorsTest::Test1D()
11544{
11545	/* Shortcut for GL functionality. */
11546	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
11547
11548	/* Result. */
11549	bool is_ok = true;
11550
11551	/* Bind framebuffer. */
11552	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_incomplete);
11553	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11554
11555	/* Check that INVALID_FRAMEBUFFER_OPERATION is generated by
11556	 CopyTextureSubImage1D if the object bound to READ_FRAMEBUFFER_BINDING is
11557	 not framebuffer complete. */
11558	{
11559		gl.copyTextureSubImage1D(m_to_1D_dst, 0, 0, 0, 0, s_width);
11560		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_FRAMEBUFFER_OPERATION, "glCopyTextureSubImage1D",
11561								  "the object bound to READ_FRAMEBUFFER_BINDING is not framebuffer complete.");
11562	}
11563
11564	/* Bind framebuffer. */
11565	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
11566	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11567
11568	gl.readBuffer(GL_COLOR_ATTACHMENT0);
11569	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11570
11571	/* Check that INVALID_OPERATION is generated by CopyTextureSubImage1D if
11572	 texture is not the name of an existing texture object, or if the
11573	 effective target of texture is not TEXTURE_1D. */
11574	{
11575		gl.copyTextureSubImage1D(m_to_invalid, 0, 0, 0, 0, s_width);
11576		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage1D",
11577								  "texture is not the name of an existing texture object.");
11578
11579		gl.copyTextureSubImage1D(m_to_2D_dst, 0, 0, 0, 0, s_width);
11580		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage1D",
11581								  "the effective target of texture is not TEXTURE_1D.");
11582	}
11583
11584	/* Check that INVALID_VALUE is generated by CopyTextureSubImage1D if level is less than 0. */
11585	{
11586		gl.copyTextureSubImage1D(m_to_1D_dst, -1, 0, 0, 0, s_width);
11587		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage1D", "level is less than 0.");
11588	}
11589
11590	/* Check that INVALID_VALUE is generated by CopyTextureSubImage1D if
11591	 xoffset<0, or (xoffset+width)>w, where w is the TEXTURE_WIDTH of the
11592	 texture image being modified. */
11593	{
11594		gl.copyTextureSubImage1D(m_to_1D_dst, 0, -1, 0, 0, s_width);
11595		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage1D", "xoffset<0.");
11596
11597		gl.copyTextureSubImage1D(m_to_1D_dst, 0, 1, 0, 0, s_width);
11598		is_ok &=
11599			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage1D",
11600							 "(xoffset+width)>w, where w is the TEXTURE_WIDTH of the texture image being modified.");
11601	}
11602
11603	/* Check that INVALID_OPERATION is generated by CopyTextureSubImage1D if
11604	 the read buffer is NONE. */
11605	gl.readBuffer(GL_NONE);
11606	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11607
11608	{
11609		gl.copyTextureSubImage1D(m_to_1D_dst, 0, 0, 0, 0, s_width);
11610		is_ok &=
11611			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage1D", "the read buffer is NONE.");
11612	}
11613
11614	/* Bind multisample framebuffer. */
11615	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_ms);
11616	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11617
11618	gl.readBuffer(GL_COLOR_ATTACHMENT0);
11619	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11620
11621	/* Check that INVALID_OPERATION is generated by CopyTextureSubImage1D if
11622	 the effective value of SAMPLE_BUFFERS for the read
11623	 framebuffer is one. */
11624	{
11625		gl.copyTextureSubImage1D(m_to_1D_dst, 0, 0, 0, 0, s_width);
11626		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage1D",
11627								  "the effective value of SAMPLE_BUFFERS for the read framebuffer is one.");
11628	}
11629
11630	return is_ok;
11631}
11632
11633/** @brief Test (negative) of CopyTextureSubImage2D
11634 *
11635 *  @return Test result.
11636 */
11637bool CopyErrorsTest::Test2D()
11638{
11639	/* Shortcut for GL functionality. */
11640	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
11641
11642	/* Result. */
11643	bool is_ok = true;
11644
11645	/* Bind framebuffer. */
11646	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_incomplete);
11647	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11648
11649	/* Check that INVALID_FRAMEBUFFER_OPERATION is generated by
11650	 CopyTextureSubImage2D if the object bound to READ_FRAMEBUFFER_BINDING is
11651	 not framebuffer complete. */
11652	{
11653		gl.copyTextureSubImage2D(m_to_2D_dst, 0, 0, 0, 0, 0, s_width, s_height);
11654		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_FRAMEBUFFER_OPERATION, "glCopyTextureSubImage2D",
11655								  "the object bound to READ_FRAMEBUFFER_BINDING is not framebuffer complete.");
11656	}
11657
11658	/* Bind framebuffer. */
11659	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
11660	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11661
11662	gl.readBuffer(GL_COLOR_ATTACHMENT0);
11663	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11664
11665	/* Check that INVALID_OPERATION is generated by CopyTextureSubImage2D if
11666	 texture is not the name of an existing texture object, or if the
11667	 effective target of texture is not TEXTURE_2D. */
11668	{
11669		gl.copyTextureSubImage2D(m_to_invalid, 0, 0, 0, 0, 0, s_width, s_height);
11670		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage2D",
11671								  "texture is not the name of an existing texture object.");
11672
11673		gl.copyTextureSubImage2D(m_to_1D_dst, 0, 0, 0, 0, 0, s_width, s_height);
11674		is_ok &= CheckErrorAndLog(
11675			m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage2D",
11676			"the effective target of does not correspond to one of the texture targets supported by the function..");
11677	}
11678
11679	/* Check that INVALID_VALUE is generated by CopyTextureSubImage2D if level is less than 0. */
11680	{
11681		gl.copyTextureSubImage2D(m_to_2D_dst, -1, 0, 0, 0, 0, s_width, s_height);
11682		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage2D", "level is less than 0.");
11683	}
11684
11685	/* Check that INVALID_VALUE is generated by CopyTextureSubImage2D if
11686	 xoffset<0, (xoffset+width)>w, yoffset<0, or (yoffset+height)>0, where w
11687	 is the TEXTURE_WIDTH, h is the TEXTURE_HEIGHT and of the texture image
11688	 being modified. */
11689	{
11690		gl.copyTextureSubImage2D(m_to_2D_dst, 0, -1, 0, 0, 0, s_width, s_height);
11691		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage2D", "xoffset<0.");
11692
11693		gl.copyTextureSubImage2D(m_to_2D_dst, 0, 1, 0, 0, 0, s_width, s_height);
11694		is_ok &=
11695			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage2D",
11696							 "(xoffset+width)>w, where w is the TEXTURE_WIDTH of the texture image being modified.");
11697
11698		gl.copyTextureSubImage2D(m_to_2D_dst, 0, 0, -1, 0, 0, s_width, s_height);
11699		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage2D", "yoffset<0.");
11700
11701		gl.copyTextureSubImage2D(m_to_2D_dst, 0, 0, 1, 0, 0, s_width, s_height);
11702		is_ok &=
11703			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage2D",
11704							 "(yoffset+height)>h, where h is the TEXTURE_HEIGHT of the texture image being modified.");
11705	}
11706
11707	/* Check that INVALID_OPERATION is generated by CopyTextureSubImage2D if
11708	 the read buffer is NONE. */
11709	gl.readBuffer(GL_NONE);
11710	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11711
11712	{
11713		gl.copyTextureSubImage2D(m_to_2D_dst, 0, 0, 0, 0, 0, s_width, s_height);
11714		is_ok &=
11715			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage2D", "the read buffer is NONE.");
11716	}
11717
11718	/* Bind multisample framebuffer. */
11719	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_ms);
11720	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11721
11722	gl.readBuffer(GL_COLOR_ATTACHMENT0);
11723	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11724
11725	/* Check that INVALID_OPERATION is generated by CopyTextureSubImage2D if
11726	 the effective value of SAMPLE_BUFFERS for the read
11727	 framebuffer is one. */
11728	{
11729		gl.copyTextureSubImage2D(m_to_2D_dst, 0, 0, 0, 0, 0, s_width, s_height);
11730		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage2D",
11731								  "the effective value of SAMPLE_BUFFERS for the read framebuffer is one.");
11732	}
11733
11734	return is_ok;
11735}
11736
11737/** @brief Test (negative) of CopyTextureSubImage3D
11738 *
11739 *  @return Test result.
11740 */
11741bool CopyErrorsTest::Test3D()
11742{
11743	/* Shortcut for GL functionality. */
11744	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
11745
11746	/* Result. */
11747	bool is_ok = true;
11748
11749	/* Bind framebuffer. */
11750	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_incomplete);
11751	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11752
11753	/* Check that INVALID_FRAMEBUFFER_OPERATION is generated by
11754	 CopyTextureSubImage3D if the object bound to READ_FRAMEBUFFER_BINDING is
11755	 not framebuffer complete. */
11756	{
11757		gl.copyTextureSubImage3D(m_to_3D_dst, 0, 0, 0, 0, 0, 0, s_width, s_height);
11758		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_FRAMEBUFFER_OPERATION, "glCopyTextureSubImage3D",
11759								  "the object bound to READ_FRAMEBUFFER_BINDING is not framebuffer complete.");
11760	}
11761
11762	/* Bind framebuffer. */
11763	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
11764	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11765
11766	gl.readBuffer(GL_COLOR_ATTACHMENT0);
11767	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11768
11769	/* Check that INVALID_OPERATION is generated by CopyTextureSubImage3D if
11770	 texture is not the name of an existing texture object, or if the
11771	 effective target of texture is not supported by the function. */
11772	{
11773		gl.copyTextureSubImage3D(m_to_invalid, 0, 0, 0, 0, 0, 0, s_width, s_height);
11774		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage3D",
11775								  "texture is not the name of an existing texture object.");
11776
11777		gl.copyTextureSubImage3D(m_to_1D_dst, 0, 0, 0, 0, 0, 0, s_width, s_height);
11778		is_ok &= CheckErrorAndLog(
11779			m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage3D",
11780			"the effective target of does not correspond to one of the texture targets supported by the function..");
11781	}
11782
11783	/* Check that INVALID_VALUE is generated by CopyTextureSubImage3D if level is less than 0. */
11784	{
11785		gl.copyTextureSubImage3D(m_to_3D_dst, -1, 0, 0, 0, 0, 0, s_width, s_height);
11786		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage3D", "level is less than 0.");
11787	}
11788
11789	/* Check that INVALID_VALUE is generated by CopyTextureSubImage3D if
11790	 xoffset<0, (xoffset+width)>w, yoffset<0, (yoffset+height)>h, zoffset<0,
11791	 or (zoffset+1)>d, where w is the TEXTURE_WIDTH, h is the TEXTURE_HEIGHT,
11792	 d is the TEXTURE_DEPTH and of the texture image being modified. Note
11793	 that w, h, and d include twice the border width.  */
11794	{
11795		gl.copyTextureSubImage3D(m_to_3D_dst, 0, -1, 0, 0, 0, 0, s_width, s_height);
11796		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage3D", "xoffset<0.");
11797
11798		gl.copyTextureSubImage3D(m_to_3D_dst, 0, 1, 0, 0, 0, 0, s_width, s_height);
11799		is_ok &=
11800			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage3D",
11801							 "(xoffset+width)>w, where w is the TEXTURE_WIDTH of the texture image being modified.");
11802
11803		gl.copyTextureSubImage3D(m_to_3D_dst, 0, 0, -1, 0, 0, 0, s_width, s_height);
11804		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage3D", "yoffset<0.");
11805
11806		gl.copyTextureSubImage3D(m_to_3D_dst, 0, 0, 1, 0, 0, 0, s_width, s_height);
11807		is_ok &=
11808			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage3D",
11809							 "(yoffset+height)>h, where h is the TEXTURE_HEIGHT of the texture image being modified.");
11810
11811		gl.copyTextureSubImage3D(m_to_3D_dst, 0, 0, 0, -1, 0, 0, s_width, s_height);
11812		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage3D", "zoffset<0.");
11813
11814		gl.copyTextureSubImage3D(m_to_3D_dst, 0, 0, 0, s_depth + 1, 0, 0, s_width, s_height);
11815		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage3D",
11816								  "(zoffset+1)>d, where d is the TEXTURE_DEPTH of the texture image being modified.");
11817	}
11818
11819	/* Check that INVALID_OPERATION is generated by CopyTextureSubImage3D if
11820	 the read buffer is NONE. */
11821	gl.readBuffer(GL_NONE);
11822	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11823
11824	{
11825		gl.copyTextureSubImage3D(m_to_3D_dst, 0, 0, 0, 0, 0, 0, s_width, s_height);
11826		is_ok &=
11827			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage3D", "the read buffer is NONE.");
11828	}
11829
11830	/* Bind multisample framebuffer. */
11831	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_ms);
11832	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11833
11834	gl.readBuffer(GL_COLOR_ATTACHMENT0);
11835	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
11836
11837	/* Check that INVALID_OPERATION is generated by CopyTextureSubImage3D if
11838	 the effective value of SAMPLE_BUFFERS for the read
11839	 framebuffer is one. */
11840	{
11841		gl.copyTextureSubImage3D(m_to_3D_dst, 0, 0, 0, 0, 0, 0, s_width, s_height);
11842		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage3D",
11843								  "the effective value of SAMPLE_BUFFERS for the read framebuffer is one.");
11844	}
11845
11846	return is_ok;
11847}
11848
11849/** @brief Clean GL objects, test variables and GL errors.
11850 */
11851void CopyErrorsTest::Clean()
11852{
11853	/* Shortcut for GL functionality. */
11854	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
11855
11856	/* Cleanup. */
11857	if (m_fbo)
11858	{
11859		gl.deleteFramebuffers(1, &m_fbo);
11860
11861		m_fbo = 0;
11862	}
11863
11864	if (m_fbo_ms)
11865	{
11866		gl.deleteFramebuffers(1, &m_fbo_ms);
11867
11868		m_fbo_ms = 0;
11869	}
11870
11871	if (m_fbo_incomplete)
11872	{
11873		gl.deleteFramebuffers(1, &m_fbo_incomplete);
11874
11875		m_fbo_incomplete = 0;
11876	}
11877
11878	if (m_to_src)
11879	{
11880		gl.deleteTextures(1, &m_to_src);
11881
11882		m_to_src = 0;
11883	}
11884
11885	if (m_to_src_ms)
11886	{
11887		gl.deleteTextures(1, &m_to_src_ms);
11888
11889		m_to_src_ms = 0;
11890	}
11891
11892	if (m_to_1D_dst)
11893	{
11894		gl.deleteTextures(1, &m_to_1D_dst);
11895
11896		m_to_1D_dst = 0;
11897	}
11898
11899	if (m_to_2D_dst)
11900	{
11901		gl.deleteTextures(1, &m_to_2D_dst);
11902
11903		m_to_2D_dst = 0;
11904	}
11905
11906	if (m_to_3D_dst)
11907	{
11908		gl.deleteTextures(1, &m_to_3D_dst);
11909
11910		m_to_3D_dst = 0;
11911	}
11912
11913	m_to_invalid = 0;
11914
11915	while (GL_NO_ERROR != gl.getError())
11916		;
11917}
11918
11919/* Test's parameters. */
11920const glw::GLuint CopyErrorsTest::s_width		   = 4;
11921const glw::GLuint CopyErrorsTest::s_height		   = 4;
11922const glw::GLuint CopyErrorsTest::s_depth		   = 4;
11923const glw::GLuint CopyErrorsTest::s_internalformat = GL_RGBA8;
11924
11925/******************************** Parameter Setup Errors Test Implementation   ********************************/
11926
11927/** @brief Parameter Setup Errors Test constructor.
11928 *
11929 *  @param [in] context     OpenGL context.
11930 */
11931ParameterSetupErrorsTest::ParameterSetupErrorsTest(deqp::Context& context)
11932	: deqp::TestCase(context, "textures_parameter_setup_errors", "Texture Parameter Setup Errors Test")
11933	, m_to_2D(0)
11934	, m_to_2D_ms(0)
11935	, m_to_rectangle(0)
11936	, m_to_invalid(0)
11937	, m_pname_invalid(0)
11938	, m_depth_stencil_mode_invalid(0)
11939{
11940	/* Intentionally left blank. */
11941}
11942
11943/** @brief Iterate Parameter Setup Errors Test cases.
11944 *
11945 *  @return Iteration result.
11946 */
11947tcu::TestNode::IterateResult ParameterSetupErrorsTest::iterate()
11948{
11949	/* Get context setup. */
11950	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
11951	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
11952
11953	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
11954	{
11955		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
11956
11957		return STOP;
11958	}
11959
11960	/* Running tests. */
11961	bool is_ok	= true;
11962	bool is_error = false;
11963
11964	try
11965	{
11966		Prepare();
11967
11968		is_ok &= Testf();
11969		is_ok &= Testi();
11970		is_ok &= Testfv();
11971		is_ok &= Testiv();
11972		is_ok &= TestIiv();
11973		is_ok &= TestIuiv();
11974	}
11975	catch (...)
11976	{
11977		is_ok	= false;
11978		is_error = true;
11979	}
11980
11981	/* Cleanup. */
11982	Clean();
11983
11984	/* Result's setup. */
11985	if (is_ok)
11986	{
11987		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
11988	}
11989	else
11990	{
11991		if (is_error)
11992		{
11993			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
11994		}
11995		else
11996		{
11997			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
11998		}
11999	}
12000
12001	return STOP;
12002}
12003
12004/** @brief Test's preparations.
12005 */
12006void ParameterSetupErrorsTest::Prepare()
12007{
12008	/* Shortcut for GL functionality. */
12009	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
12010
12011	/* Auxiliary objects setup. */
12012
12013	/* 2D */
12014	gl.createTextures(GL_TEXTURE_2D, 1, &m_to_2D);
12015	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
12016
12017	/* 3D */
12018	gl.createTextures(GL_TEXTURE_2D_MULTISAMPLE, 1, &m_to_2D_ms);
12019	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
12020
12021	/* RECTANGLE */
12022	gl.createTextures(GL_TEXTURE_RECTANGLE, 1, &m_to_rectangle);
12023	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
12024
12025	/* Invalid texture object. */
12026	while (gl.isTexture(++m_to_invalid))
12027		;
12028	GLU_EXPECT_NO_ERROR(gl.getError(), "glIsTexture has failed");
12029
12030	/* Invalid parameter name. */
12031	glw::GLenum all_pnames[] = { GL_DEPTH_STENCIL_TEXTURE_MODE,
12032								 GL_TEXTURE_BASE_LEVEL,
12033								 GL_TEXTURE_COMPARE_FUNC,
12034								 GL_TEXTURE_COMPARE_MODE,
12035								 GL_TEXTURE_LOD_BIAS,
12036								 GL_TEXTURE_MIN_FILTER,
12037								 GL_TEXTURE_MAG_FILTER,
12038								 GL_TEXTURE_MIN_LOD,
12039								 GL_TEXTURE_MAX_LOD,
12040								 GL_TEXTURE_MAX_LEVEL,
12041								 GL_TEXTURE_SWIZZLE_R,
12042								 GL_TEXTURE_SWIZZLE_G,
12043								 GL_TEXTURE_SWIZZLE_B,
12044								 GL_TEXTURE_SWIZZLE_A,
12045								 GL_TEXTURE_WRAP_S,
12046								 GL_TEXTURE_WRAP_T,
12047								 GL_TEXTURE_WRAP_R,
12048								 GL_TEXTURE_BORDER_COLOR,
12049								 GL_TEXTURE_SWIZZLE_RGBA };
12050	glw::GLuint all_pnames_count = sizeof(all_pnames) / sizeof(all_pnames[0]);
12051
12052	bool is_valid = true;
12053
12054	while (is_valid)
12055	{
12056		is_valid = false;
12057		++m_pname_invalid;
12058
12059		for (glw::GLuint i = 0; i < all_pnames_count; ++i)
12060		{
12061			if (all_pnames[i] == m_pname_invalid)
12062			{
12063				is_valid = true;
12064
12065				break;
12066			}
12067		}
12068	}
12069
12070	/* Invalid depth stencil mode name. */
12071	glw::GLenum all_depth_stencil_modes[]	 = { GL_DEPTH_COMPONENT, GL_STENCIL_INDEX };
12072	glw::GLuint all_depth_stencil_modes_count = sizeof(all_depth_stencil_modes) / sizeof(all_depth_stencil_modes[0]);
12073
12074	is_valid = true;
12075
12076	while (is_valid)
12077	{
12078		is_valid = false;
12079		++m_depth_stencil_mode_invalid;
12080
12081		for (glw::GLuint i = 0; i < all_depth_stencil_modes_count; ++i)
12082		{
12083			if (all_depth_stencil_modes[i] == m_depth_stencil_mode_invalid)
12084			{
12085				is_valid = true;
12086
12087				break;
12088			}
12089		}
12090	}
12091}
12092
12093/** @brief Test (negative) of TextureParameterf
12094 *
12095 *  @return Test result.
12096 */
12097bool ParameterSetupErrorsTest::Testf()
12098{
12099	/* Shortcut for GL functionality. */
12100	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
12101
12102	/* Result. */
12103	bool is_ok = true;
12104
12105	/* Check that INVALID_ENUM is generated by TextureParameter* if pname is
12106	 not one of the accepted defined values. */
12107	{
12108		gl.textureParameterf(m_to_2D, m_pname_invalid, 1.f);
12109
12110		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterf",
12111								  "pname is not one of the accepted defined values.");
12112	}
12113
12114	/* Check that INVALID_ENUM is generated by TextureParameter* if params
12115	 should have a defined constant value (based on the value of pname) and
12116	 does not. */
12117	{
12118		gl.textureParameterf(m_to_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, (glw::GLfloat)m_depth_stencil_mode_invalid);
12119
12120		is_ok &=
12121			CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterf",
12122							 "params should have a defined constant value (based on the value of pname) and does not.");
12123	}
12124	/* Check that INVALID_ENUM is generated if TextureParameter{if} is called
12125	 for a non-scalar parameter (pname TEXTURE_BORDER_COLOR or
12126	 TEXTURE_SWIZZLE_RGBA). */
12127	{
12128		gl.textureParameterf(m_to_2D, GL_TEXTURE_BORDER_COLOR, 1.f);
12129
12130		is_ok &=
12131			CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterf",
12132							 "called for a non-scalar parameter (pname TEXTURE_BORDER_COLOR or TEXTURE_SWIZZLE_RGBA).");
12133	}
12134
12135	/* Check that INVALID_ENUM is generated by TextureParameter* if the
12136	 effective target is either TEXTURE_2D_MULTISAMPLE or
12137	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states. */
12138	{
12139		gl.textureParameterf(m_to_2D_ms, GL_TEXTURE_LOD_BIAS, 1.f);
12140
12141		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterf",
12142								  "the  effective target is either TEXTURE_2D_MULTISAMPLE or  "
12143								  "TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states.");
12144	}
12145
12146	/* Check that INVALID_ENUM is generated by TextureParameter* if the
12147	 effective target is TEXTURE_RECTANGLE and either of pnames
12148	 TEXTURE_WRAP_S or TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE,
12149	 MIRRORED_REPEAT or REPEAT. */
12150	{
12151		gl.textureParameterf(m_to_rectangle, GL_TEXTURE_WRAP_S, GL_MIRROR_CLAMP_TO_EDGE);
12152
12153		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterf",
12154								  "the effective target is TEXTURE_RECTANGLE and either of pnames TEXTURE_WRAP_S or "
12155								  "TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE, MIRRORED_REPEAT or REPEAT.");
12156	}
12157
12158	/* Check that INVALID_ENUM is generated by TextureParameter* if the
12159	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is
12160	 set to a value other than NEAREST or LINEAR (no mipmap filtering is
12161	 permitted). */
12162	{
12163		gl.textureParameterf(m_to_rectangle, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
12164
12165		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterf",
12166								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is set to a "
12167								  "value other than NEAREST or LINEAR (no mipmap filtering is permitted).");
12168	}
12169
12170	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
12171	 effective target is either TEXTURE_2D_MULTISAMPLE or
12172	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname TEXTURE_BASE_LEVEL is set to a
12173	 value other than zero. */
12174	{
12175		gl.textureParameterf(m_to_2D_ms, GL_TEXTURE_BASE_LEVEL, 1.f);
12176
12177		is_ok &=
12178			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterf",
12179							 "the effective target is either TEXTURE_2D_MULTISAMPLE or TEXTURE_2D_MULTISAMPLE_ARRAY, "
12180							 "and pname TEXTURE_BASE_LEVEL is set to a value other than zero.");
12181	}
12182
12183	/* Check that INVALID_OPERATION is generated by TextureParameter* if
12184	 texture is not the name of an existing texture object. */
12185	{
12186		gl.textureParameterf(m_to_invalid, GL_TEXTURE_LOD_BIAS, 1.f);
12187
12188		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterf",
12189								  "texture is not the name of an existing texture object.");
12190	}
12191
12192	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
12193	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is
12194	 set to any value other than zero. */
12195	{
12196		gl.textureParameterf(m_to_rectangle, GL_TEXTURE_BASE_LEVEL, 1.f);
12197
12198		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterf",
12199								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is set to "
12200								  "any value other than zero. ");
12201	}
12202
12203	/* Check that INVALID_VALUE is generated by TextureParameter* if pname is
12204	 TEXTURE_BASE_LEVEL or TEXTURE_MAX_LEVEL, and param or params is
12205	 negative. */
12206	{
12207		gl.textureParameterf(m_to_2D, GL_TEXTURE_BASE_LEVEL, -1.f);
12208
12209		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameterf",
12210								  "pname is TEXTURE_BASE_LEVEL and param is negative.");
12211
12212		gl.textureParameterf(m_to_2D, GL_TEXTURE_MAX_LEVEL, -1.f);
12213
12214		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameterf",
12215								  "pname is TEXTURE_MAX_LEVEL and param is negative.");
12216	}
12217
12218	return is_ok;
12219}
12220
12221/** @brief Test (negative) of TextureParameteri
12222 *
12223 *  @return Test result.
12224 */
12225bool ParameterSetupErrorsTest::Testi()
12226{
12227	/* Shortcut for GL functionality. */
12228	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
12229
12230	/* Result. */
12231	bool is_ok = true;
12232
12233	/* Check that INVALID_ENUM is generated by TextureParameter* if pname is
12234	 not one of the accepted defined values. */
12235	{
12236		gl.textureParameteri(m_to_2D, m_pname_invalid, 1);
12237
12238		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteri",
12239								  "pname is not one of the accepted defined values.");
12240	}
12241
12242	/* Check that INVALID_ENUM is generated by TextureParameter* if params
12243	 should have a defined constant value (based on the value of pname) and
12244	 does not. */
12245	{
12246		gl.textureParameteri(m_to_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, m_depth_stencil_mode_invalid);
12247
12248		is_ok &=
12249			CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteri",
12250							 "params should have a defined constant value (based on the value of pname) and does not.");
12251	}
12252	/* Check that INVALID_ENUM is generated if TextureParameter{if} is called
12253	 for a non-scalar parameter (pname TEXTURE_BORDER_COLOR or
12254	 TEXTURE_SWIZZLE_RGBA). */
12255	{
12256		gl.textureParameteri(m_to_2D, GL_TEXTURE_BORDER_COLOR, 1);
12257
12258		is_ok &=
12259			CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteri",
12260							 "called for a non-scalar parameter (pname TEXTURE_BORDER_COLOR or TEXTURE_SWIZZLE_RGBA).");
12261	}
12262
12263	/* Check that INVALID_ENUM is generated by TextureParameter* if the
12264	 effective target is either TEXTURE_2D_MULTISAMPLE or
12265	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states. */
12266	{
12267		gl.textureParameteri(m_to_2D_ms, GL_TEXTURE_LOD_BIAS, 1);
12268
12269		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameteri",
12270								  "the  effective target is either TEXTURE_2D_MULTISAMPLE or  "
12271								  "TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states.");
12272	}
12273
12274	/* Check that INVALID_ENUM is generated by TextureParameter* if the
12275	 effective target is TEXTURE_RECTANGLE and either of pnames
12276	 TEXTURE_WRAP_S or TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE,
12277	 MIRRORED_REPEAT or REPEAT. */
12278	{
12279		gl.textureParameteri(m_to_rectangle, GL_TEXTURE_WRAP_S, GL_MIRROR_CLAMP_TO_EDGE);
12280
12281		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteri",
12282								  "the effective target is TEXTURE_RECTANGLE and either of pnames TEXTURE_WRAP_S or "
12283								  "TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE, MIRRORED_REPEAT or REPEAT.");
12284	}
12285
12286	/* Check that INVALID_ENUM is generated by TextureParameter* if the
12287	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is
12288	 set to a value other than NEAREST or LINEAR (no mipmap filtering is
12289	 permitted). */
12290	{
12291		gl.textureParameteri(m_to_rectangle, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
12292
12293		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteri",
12294								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is set to a "
12295								  "value other than NEAREST or LINEAR (no mipmap filtering is permitted).");
12296	}
12297
12298	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
12299	 effective target is either TEXTURE_2D_MULTISAMPLE or
12300	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname TEXTURE_BASE_LEVEL is set to a
12301	 value other than zero. */
12302	{
12303		gl.textureParameteri(m_to_2D_ms, GL_TEXTURE_BASE_LEVEL, 1);
12304
12305		is_ok &=
12306			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameteri",
12307							 "the effective target is either TEXTURE_2D_MULTISAMPLE or TEXTURE_2D_MULTISAMPLE_ARRAY, "
12308							 "and pname TEXTURE_BASE_LEVEL is set to a value other than zero.");
12309	}
12310
12311	/* Check that INVALID_OPERATION is generated by TextureParameter* if
12312	 texture is not the name of an existing texture object. */
12313	{
12314		gl.textureParameteri(m_to_invalid, GL_TEXTURE_LOD_BIAS, 1);
12315
12316		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameteri",
12317								  "texture is not the name of an existing texture object.");
12318	}
12319
12320	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
12321	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is
12322	 set to any value other than zero. */
12323	{
12324		gl.textureParameteri(m_to_rectangle, GL_TEXTURE_BASE_LEVEL, 1);
12325
12326		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameteri",
12327								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is set to "
12328								  "any value other than zero. ");
12329	}
12330
12331	/* Check that INVALID_VALUE is generated by TextureParameter* if pname is
12332	 TEXTURE_BASE_LEVEL or TEXTURE_MAX_LEVEL, and param or params is
12333	 negative. */
12334	{
12335		gl.textureParameteri(m_to_2D, GL_TEXTURE_BASE_LEVEL, -1);
12336
12337		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameteri",
12338								  "pname is TEXTURE_BASE_LEVEL and param is negative.");
12339
12340		gl.textureParameteri(m_to_2D, GL_TEXTURE_MAX_LEVEL, -1);
12341
12342		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameteri",
12343								  "pname is TEXTURE_MAX_LEVEL and param is negative.");
12344	}
12345
12346	return is_ok;
12347}
12348
12349/** @brief Test (negative) of TextureParameterfv
12350 *
12351 *  @return Test result.
12352 */
12353bool ParameterSetupErrorsTest::Testfv()
12354{
12355	/* Shortcut for GL functionality. */
12356	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
12357
12358	/* Result. */
12359	bool is_ok = true;
12360
12361	glw::GLfloat one						= 1.f;
12362	glw::GLfloat minus_one					= -1.f;
12363	glw::GLfloat depth_stencil_mode_invalid = (glw::GLfloat)m_depth_stencil_mode_invalid;
12364	glw::GLfloat wrap_invalid				= (glw::GLfloat)GL_MIRROR_CLAMP_TO_EDGE;
12365	glw::GLfloat min_filter_invalid			= (glw::GLfloat)GL_NEAREST_MIPMAP_NEAREST;
12366
12367	/* Check that INVALID_ENUM is generated by TextureParameter* if pname is
12368	 not one of the accepted defined values. */
12369	{
12370		gl.textureParameterfv(m_to_2D, m_pname_invalid, &one);
12371
12372		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterfv",
12373								  "pname is not one of the accepted defined values.");
12374	}
12375
12376	/* Check that INVALID_ENUM is generated by TextureParameter* if params
12377	 should have a defined constant value (based on the value of pname) and
12378	 does not. */
12379	{
12380		gl.textureParameterfv(m_to_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, &depth_stencil_mode_invalid);
12381
12382		is_ok &=
12383			CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterfv",
12384							 "params should have a defined constant value (based on the value of pname) and does not.");
12385	}
12386
12387	/* Check that INVALID_ENUM is generated by TextureParameter* if the
12388	 effective target is either TEXTURE_2D_MULTISAMPLE or
12389	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states. */
12390	{
12391		gl.textureParameterfv(m_to_2D_ms, GL_TEXTURE_LOD_BIAS, &one);
12392
12393		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterfv",
12394								  "the  effective target is either TEXTURE_2D_MULTISAMPLE or  "
12395								  "TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states.");
12396	}
12397
12398	/* Check that INVALID_ENUM is generated by TextureParameter* if the
12399	 effective target is TEXTURE_RECTANGLE and either of pnames
12400	 TEXTURE_WRAP_S or TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE,
12401	 MIRRORED_REPEAT or REPEAT. */
12402	{
12403		gl.textureParameterfv(m_to_rectangle, GL_TEXTURE_WRAP_S, &wrap_invalid);
12404
12405		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterfv",
12406								  "the effective target is TEXTURE_RECTANGLE and either of pnames TEXTURE_WRAP_S or "
12407								  "TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE, MIRRORED_REPEAT or REPEAT.");
12408	}
12409
12410	/* Check that INVALID_ENUM is generated by TextureParameter* if the
12411	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is
12412	 set to a value other than NEAREST or LINEAR (no mipmap filtering is
12413	 permitted). */
12414	{
12415		gl.textureParameterfv(m_to_rectangle, GL_TEXTURE_MIN_FILTER, &min_filter_invalid);
12416
12417		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterfv",
12418								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is set to a "
12419								  "value other than NEAREST or LINEAR (no mipmap filtering is permitted).");
12420	}
12421
12422	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
12423	 effective target is either TEXTURE_2D_MULTISAMPLE or
12424	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname TEXTURE_BASE_LEVEL is set to a
12425	 value other than zero. */
12426	{
12427		gl.textureParameterfv(m_to_2D_ms, GL_TEXTURE_BASE_LEVEL, &one);
12428
12429		is_ok &=
12430			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterfv",
12431							 "the effective target is either TEXTURE_2D_MULTISAMPLE or TEXTURE_2D_MULTISAMPLE_ARRAY, "
12432							 "and pname TEXTURE_BASE_LEVEL is set to a value other than zero.");
12433	}
12434
12435	/* Check that INVALID_OPERATION is generated by TextureParameter* if
12436	 texture is not the name of an existing texture object. */
12437	{
12438		gl.textureParameterfv(m_to_invalid, GL_TEXTURE_LOD_BIAS, &one);
12439
12440		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterfv",
12441								  "texture is not the name of an existing texture object.");
12442	}
12443
12444	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
12445	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is
12446	 set to any value other than zero. */
12447	{
12448		gl.textureParameterfv(m_to_rectangle, GL_TEXTURE_BASE_LEVEL, &one);
12449
12450		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterfv",
12451								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is set to "
12452								  "any value other than zero. ");
12453	}
12454
12455	/* Check that INVALID_VALUE is generated by TextureParameter* if pname is
12456	 TEXTURE_BASE_LEVEL or TEXTURE_MAX_LEVEL, and param or params is
12457	 negative. */
12458	{
12459		gl.textureParameterfv(m_to_2D, GL_TEXTURE_BASE_LEVEL, &minus_one);
12460
12461		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameterfv",
12462								  "pname is TEXTURE_BASE_LEVEL and param is negative.");
12463
12464		gl.textureParameterfv(m_to_2D, GL_TEXTURE_MAX_LEVEL, &minus_one);
12465
12466		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameterfv",
12467								  "pname is TEXTURE_MAX_LEVEL and param is negative.");
12468	}
12469
12470	return is_ok;
12471}
12472
12473/** @brief Test (negative) of TextureParameteriv
12474 *
12475 *  @return Test result.
12476 */
12477bool ParameterSetupErrorsTest::Testiv()
12478{
12479	/* Shortcut for GL functionality. */
12480	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
12481
12482	/* Result. */
12483	bool is_ok = true;
12484
12485	glw::GLint one						  = 1;
12486	glw::GLint minus_one				  = -1;
12487	glw::GLint depth_stencil_mode_invalid = (glw::GLint)m_depth_stencil_mode_invalid;
12488	glw::GLint wrap_invalid				  = (glw::GLint)GL_MIRROR_CLAMP_TO_EDGE;
12489	glw::GLint min_filter_invalid		  = (glw::GLint)GL_NEAREST_MIPMAP_NEAREST;
12490
12491	/* Check that INVALID_ENUM is generated by TextureParameter* if pname is
12492	 not one of the accepted defined values. */
12493	{
12494		gl.textureParameteriv(m_to_2D, m_pname_invalid, &one);
12495
12496		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteriv",
12497								  "pname is not one of the accepted defined values.");
12498	}
12499
12500	/* Check that INVALID_ENUM is generated by TextureParameter* if params
12501	 should have a defined constant value (based on the value of pname) and
12502	 does not. */
12503	{
12504		gl.textureParameteriv(m_to_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, &depth_stencil_mode_invalid);
12505
12506		is_ok &=
12507			CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteriv",
12508							 "params should have a defined constant value (based on the value of pname) and does not.");
12509	}
12510
12511	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
12512	 effective target is either TEXTURE_2D_MULTISAMPLE or
12513	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states. */
12514	{
12515		gl.textureParameteriv(m_to_2D_ms, GL_TEXTURE_LOD_BIAS, &one);
12516
12517		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameteriv",
12518								  "the  effective target is either TEXTURE_2D_MULTISAMPLE or  "
12519								  "TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states.");
12520	}
12521
12522	/* Check that INVALID_ENUM is generated by TextureParameter* if the
12523	 effective target is TEXTURE_RECTANGLE and either of pnames
12524	 TEXTURE_WRAP_S or TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE,
12525	 MIRRORED_REPEAT or REPEAT. */
12526	{
12527		gl.textureParameteriv(m_to_rectangle, GL_TEXTURE_WRAP_S, &wrap_invalid);
12528
12529		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteriv",
12530								  "the effective target is TEXTURE_RECTANGLE and either of pnames TEXTURE_WRAP_S or "
12531								  "TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE, MIRRORED_REPEAT or REPEAT.");
12532	}
12533
12534	/* Check that INVALID_ENUM is generated by TextureParameter* if the
12535	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is
12536	 set to a value other than NEAREST or LINEAR (no mipmap filtering is
12537	 permitted). */
12538	{
12539		gl.textureParameteriv(m_to_rectangle, GL_TEXTURE_MIN_FILTER, &min_filter_invalid);
12540
12541		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteriv",
12542								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is set to a "
12543								  "value other than NEAREST or LINEAR (no mipmap filtering is permitted).");
12544	}
12545
12546	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
12547	 effective target is either TEXTURE_2D_MULTISAMPLE or
12548	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname TEXTURE_BASE_LEVEL is set to a
12549	 value other than zero. */
12550	{
12551		gl.textureParameteriv(m_to_2D_ms, GL_TEXTURE_BASE_LEVEL, &one);
12552
12553		is_ok &=
12554			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameteriv",
12555							 "the effective target is either TEXTURE_2D_MULTISAMPLE or TEXTURE_2D_MULTISAMPLE_ARRAY, "
12556							 "and pname TEXTURE_BASE_LEVEL is set to a value other than zero.");
12557	}
12558
12559	/* Check that INVALID_OPERATION is generated by TextureParameter* if
12560	 texture is not the name of an existing texture object. */
12561	{
12562		gl.textureParameteriv(m_to_invalid, GL_TEXTURE_LOD_BIAS, &one);
12563
12564		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameteriv",
12565								  "texture is not the name of an existing texture object.");
12566	}
12567
12568	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
12569	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is
12570	 set to any value other than zero. */
12571	{
12572		gl.textureParameteriv(m_to_rectangle, GL_TEXTURE_BASE_LEVEL, &one);
12573
12574		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameteriv",
12575								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is set to "
12576								  "any value other than zero. ");
12577	}
12578
12579	/* Check that INVALID_VALUE is generated by TextureParameter* if pname is
12580	 TEXTURE_BASE_LEVEL or TEXTURE_MAX_LEVEL, and param or params is
12581	 negative. */
12582	{
12583		gl.textureParameteriv(m_to_2D, GL_TEXTURE_BASE_LEVEL, &minus_one);
12584
12585		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameteriv",
12586								  "pname is TEXTURE_BASE_LEVEL and param is negative.");
12587
12588		gl.textureParameteriv(m_to_2D, GL_TEXTURE_MAX_LEVEL, &minus_one);
12589
12590		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameteriv",
12591								  "pname is TEXTURE_MAX_LEVEL and param is negative.");
12592	}
12593
12594	return is_ok;
12595}
12596
12597/** @brief Test (negative) of TextureParameterIiv
12598 *
12599 *  @return Test result.
12600 */
12601bool ParameterSetupErrorsTest::TestIiv()
12602{
12603	/* Shortcut for GL functionality. */
12604	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
12605
12606	/* Result. */
12607	bool is_ok = true;
12608
12609	glw::GLint one						  = 1;
12610	glw::GLint minus_one				  = -1;
12611	glw::GLint depth_stencil_mode_invalid = (glw::GLint)m_depth_stencil_mode_invalid;
12612	glw::GLint wrap_invalid				  = (glw::GLint)GL_MIRROR_CLAMP_TO_EDGE;
12613	glw::GLint min_filter_invalid		  = (glw::GLint)GL_NEAREST_MIPMAP_NEAREST;
12614
12615	/* Check that INVALID_ENUM is generated by TextureParameter* if pname is
12616	 not one of the accepted defined values. */
12617	{
12618		gl.textureParameterIiv(m_to_2D, m_pname_invalid, &one);
12619
12620		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIiv",
12621								  "pname is not one of the accepted defined values.");
12622	}
12623
12624	/* Check that INVALID_ENUM is generated by TextureParameter* if params
12625	 should have a defined constant value (based on the value of pname) and
12626	 does not. */
12627	{
12628		gl.textureParameterIiv(m_to_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, &depth_stencil_mode_invalid);
12629
12630		is_ok &=
12631			CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIiv",
12632							 "params should have a defined constant value (based on the value of pname) and does not.");
12633	}
12634
12635	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
12636	 effective target is either TEXTURE_2D_MULTISAMPLE or
12637	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states. */
12638	{
12639		gl.textureParameterIiv(m_to_2D_ms, GL_TEXTURE_LOD_BIAS, &one);
12640
12641		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterIiv",
12642								  "the  effective target is either TEXTURE_2D_MULTISAMPLE or  "
12643								  "TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states.");
12644	}
12645
12646	/* Check that INVALID_ENUM is generated by TextureParameter* if the
12647	 effective target is TEXTURE_RECTANGLE and either of pnames
12648	 TEXTURE_WRAP_S or TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE,
12649	 MIRRORED_REPEAT or REPEAT. */
12650	{
12651		gl.textureParameterIiv(m_to_rectangle, GL_TEXTURE_WRAP_S, &wrap_invalid);
12652
12653		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIiv",
12654								  "the effective target is TEXTURE_RECTANGLE and either of pnames TEXTURE_WRAP_S or "
12655								  "TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE, MIRRORED_REPEAT or REPEAT.");
12656	}
12657
12658	/* Check that INVALID_ENUM is generated by TextureParameter* if the
12659	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is
12660	 set to a value other than NEAREST or LINEAR (no mipmap filtering is
12661	 permitted). */
12662	{
12663		gl.textureParameterIiv(m_to_rectangle, GL_TEXTURE_MIN_FILTER, &min_filter_invalid);
12664
12665		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIiv",
12666								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is set to a "
12667								  "value other than NEAREST or LINEAR (no mipmap filtering is permitted).");
12668	}
12669
12670	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
12671	 effective target is either TEXTURE_2D_MULTISAMPLE or
12672	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname TEXTURE_BASE_LEVEL is set to a
12673	 value other than zero. */
12674	{
12675		gl.textureParameterIiv(m_to_2D_ms, GL_TEXTURE_BASE_LEVEL, &one);
12676
12677		is_ok &=
12678			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterIiv",
12679							 "the effective target is either TEXTURE_2D_MULTISAMPLE or TEXTURE_2D_MULTISAMPLE_ARRAY, "
12680							 "and pname TEXTURE_BASE_LEVEL is set to a value other than zero.");
12681	}
12682
12683	/* Check that INVALID_OPERATION is generated by TextureParameter* if
12684	 texture is not the name of an existing texture object. */
12685	{
12686		gl.textureParameterIiv(m_to_invalid, GL_TEXTURE_LOD_BIAS, &one);
12687
12688		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterIiv",
12689								  "texture is not the name of an existing texture object.");
12690	}
12691
12692	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
12693	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is
12694	 set to any value other than zero. */
12695	{
12696		gl.textureParameterIiv(m_to_rectangle, GL_TEXTURE_BASE_LEVEL, &one);
12697
12698		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterIiv",
12699								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is set to "
12700								  "any value other than zero. ");
12701	}
12702
12703	/* Check that INVALID_VALUE is generated by TextureParameter* if pname is
12704	 TEXTURE_BASE_LEVEL or TEXTURE_MAX_LEVEL, and param or params is
12705	 negative. */
12706	{
12707		gl.textureParameterIiv(m_to_2D, GL_TEXTURE_BASE_LEVEL, &minus_one);
12708
12709		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameterIiv",
12710								  "pname is TEXTURE_BASE_LEVEL and param is negative.");
12711
12712		gl.textureParameterIiv(m_to_2D, GL_TEXTURE_MAX_LEVEL, &minus_one);
12713
12714		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameterIiv",
12715								  "pname is TEXTURE_MAX_LEVEL and param is negative.");
12716	}
12717
12718	return is_ok;
12719}
12720
12721/** @brief Test (negative) of TextureParameterIuiv
12722 *
12723 *  @return Test result.
12724 */
12725bool ParameterSetupErrorsTest::TestIuiv()
12726{
12727	/* Shortcut for GL functionality. */
12728	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
12729
12730	/* Result. */
12731	bool is_ok = true;
12732
12733	glw::GLuint one						   = 1;
12734	glw::GLuint depth_stencil_mode_invalid = (glw::GLint)m_depth_stencil_mode_invalid;
12735	glw::GLuint wrap_invalid			   = (glw::GLint)GL_MIRROR_CLAMP_TO_EDGE;
12736	glw::GLuint min_filter_invalid		   = (glw::GLint)GL_NEAREST_MIPMAP_NEAREST;
12737
12738	/* Check that INVALID_ENUM is generated by TextureParameter* if pname is
12739	 not one of the accepted defined values. */
12740	{
12741		gl.textureParameterIuiv(m_to_2D, m_pname_invalid, &one);
12742
12743		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIuiv",
12744								  "pname is not one of the accepted defined values.");
12745	}
12746
12747	/* Check that INVALID_ENUM is generated by TextureParameter* if params
12748	 should have a defined constant value (based on the value of pname) and
12749	 does not. */
12750	{
12751		gl.textureParameterIuiv(m_to_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, &depth_stencil_mode_invalid);
12752
12753		is_ok &=
12754			CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIuiv",
12755							 "params should have a defined constant value (based on the value of pname) and does not.");
12756	}
12757
12758	/* Check that INVALID_ENUM is generated by TextureParameter* if the
12759	 effective target is either TEXTURE_2D_MULTISAMPLE or
12760	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states. */
12761	{
12762		gl.textureParameterIuiv(m_to_2D_ms, GL_TEXTURE_LOD_BIAS, &one);
12763
12764		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterIuiv",
12765								  "the  effective target is either TEXTURE_2D_MULTISAMPLE or  "
12766								  "TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states.");
12767	}
12768
12769	/* Check that INVALID_ENUM is generated by TextureParameter* if the
12770	 effective target is TEXTURE_RECTANGLE and either of pnames
12771	 TEXTURE_WRAP_S or TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE,
12772	 MIRRORED_REPEAT or REPEAT. */
12773	{
12774		gl.textureParameterIuiv(m_to_rectangle, GL_TEXTURE_WRAP_S, &wrap_invalid);
12775
12776		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIuiv",
12777								  "the effective target is TEXTURE_RECTANGLE and either of pnames TEXTURE_WRAP_S or "
12778								  "TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE, MIRRORED_REPEAT or REPEAT.");
12779	}
12780
12781	/* Check that INVALID_ENUM is generated by TextureParameter* if the
12782	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is
12783	 set to a value other than NEAREST or LINEAR (no mipmap filtering is
12784	 permitted). */
12785	{
12786		gl.textureParameterIuiv(m_to_rectangle, GL_TEXTURE_MIN_FILTER, &min_filter_invalid);
12787
12788		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIuiv",
12789								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is set to a "
12790								  "value other than NEAREST or LINEAR (no mipmap filtering is permitted).");
12791	}
12792
12793	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
12794	 effective target is either TEXTURE_2D_MULTISAMPLE or
12795	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname TEXTURE_BASE_LEVEL is set to a
12796	 value other than zero. */
12797	{
12798		gl.textureParameterIuiv(m_to_2D_ms, GL_TEXTURE_BASE_LEVEL, &one);
12799
12800		is_ok &=
12801			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterIuiv",
12802							 "the effective target is either TEXTURE_2D_MULTISAMPLE or TEXTURE_2D_MULTISAMPLE_ARRAY, "
12803							 "and pname TEXTURE_BASE_LEVEL is set to a value other than zero.");
12804	}
12805
12806	/* Check that INVALID_OPERATION is generated by TextureParameter* if
12807	 texture is not the name of an existing texture object. */
12808	{
12809		gl.textureParameterIuiv(m_to_invalid, GL_TEXTURE_LOD_BIAS, &one);
12810
12811		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterIuiv",
12812								  "texture is not the name of an existing texture object.");
12813	}
12814
12815	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
12816	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is
12817	 set to any value other than zero. */
12818	{
12819		gl.textureParameterIuiv(m_to_rectangle, GL_TEXTURE_BASE_LEVEL, &one);
12820
12821		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterIuiv",
12822								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is set to "
12823								  "any value other than zero. ");
12824	}
12825
12826	return is_ok;
12827}
12828
12829/** @brief Clean GL objects, test variables and GL errors.
12830 */
12831void ParameterSetupErrorsTest::Clean()
12832{
12833	/* Shortcut for GL functionality. */
12834	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
12835
12836	/* Cleanup. */
12837	if (m_to_2D)
12838	{
12839		gl.deleteTextures(1, &m_to_2D);
12840
12841		m_to_2D = 0;
12842	}
12843
12844	if (m_to_2D_ms)
12845	{
12846		gl.deleteTextures(1, &m_to_2D_ms);
12847
12848		m_to_2D_ms = 0;
12849	}
12850
12851	if (m_to_rectangle)
12852	{
12853		gl.deleteTextures(1, &m_to_rectangle);
12854
12855		m_to_rectangle = 0;
12856	}
12857
12858	if (m_to_invalid)
12859	{
12860		gl.deleteTextures(1, &m_to_invalid);
12861
12862		m_to_invalid = 0;
12863	}
12864
12865	m_to_invalid	= 0;
12866	m_pname_invalid = 0;
12867
12868	while (GL_NO_ERROR != gl.getError())
12869		;
12870}
12871
12872/******************************** Generate Mipmap Errors Test Implementation   ********************************/
12873
12874/** @brief Generate Mipmap Errors Test constructor.
12875 *
12876 *  @param [in] context     OpenGL context.
12877 */
12878GenerateMipmapErrorsTest::GenerateMipmapErrorsTest(deqp::Context& context)
12879	: deqp::TestCase(context, "textures_generate_mipmap_errors", "Texture Generate Mipmap Errors Test")
12880{
12881	/* Intentionally left blank. */
12882}
12883
12884/** @brief Iterate Generate Mipmap Errors Test cases.
12885 *
12886 *  @return Iteration result.
12887 */
12888tcu::TestNode::IterateResult GenerateMipmapErrorsTest::iterate()
12889{
12890	/* Shortcut for GL functionality. */
12891	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
12892
12893	/* Get context setup. */
12894	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
12895	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
12896
12897	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
12898	{
12899		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
12900
12901		return STOP;
12902	}
12903
12904	/* Running tests. */
12905	bool is_ok	= true;
12906	bool is_error = false;
12907
12908	/* Objects. */
12909	glw::GLuint texture_invalid = 0;
12910	glw::GLuint texture_cube	= 0;
12911
12912	try
12913	{
12914		/* Preparations. */
12915
12916		/* incomplete cube map */
12917		gl.genTextures(1, &texture_cube);
12918		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
12919
12920		gl.bindTexture(GL_TEXTURE_CUBE_MAP, texture_cube);
12921		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
12922
12923		gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, s_reference_internalformat, s_reference_width,
12924					  s_reference_height, 0, s_reference_format, s_reference_type, s_reference_data);
12925		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");
12926
12927		/* invalid texture */
12928		while (gl.isTexture(++texture_invalid))
12929			;
12930
12931		/* Check that INVALID_OPERATION is generated by GenerateTextureMipmap if
12932		 texture is not the name of an existing texture object. */
12933		gl.generateTextureMipmap(texture_invalid);
12934		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGenerateTextureMipmap",
12935								  "texture is not the name of an existing texture object.");
12936
12937		/* Check that INVALID_OPERATION is generated by GenerateTextureMipmap if
12938		 target is TEXTURE_CUBE_MAP or TEXTURE_CUBE_MAP_ARRAY, and the specified
12939		 texture object is not cube complete or cube array complete,
12940		 respectively. */
12941		gl.generateTextureMipmap(texture_cube);
12942		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGenerateTextureMipmap",
12943								  "target is TEXTURE_CUBE_MAP or TEXTURE_CUBE_MAP_ARRAY, and the specified texture "
12944								  "object is not cube complete or cube array complete, respectively.");
12945	}
12946	catch (...)
12947	{
12948		is_ok	= false;
12949		is_error = true;
12950	}
12951
12952	/* Cleanup. */
12953	if (texture_cube)
12954	{
12955		gl.deleteTextures(1, &texture_cube);
12956	}
12957
12958	while (GL_NO_ERROR != gl.getError())
12959		;
12960
12961	/* Result's setup. */
12962	if (is_ok)
12963	{
12964		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
12965	}
12966	else
12967	{
12968		if (is_error)
12969		{
12970			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
12971		}
12972		else
12973		{
12974			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
12975		}
12976	}
12977
12978	return STOP;
12979}
12980
12981/** Reference data. */
12982const glw::GLubyte GenerateMipmapErrorsTest::s_reference_data[] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
12983																	0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF };
12984
12985/** Reference data parameters. */
12986const glw::GLuint GenerateMipmapErrorsTest::s_reference_width		   = 4;
12987const glw::GLuint GenerateMipmapErrorsTest::s_reference_height		   = 4;
12988const glw::GLenum GenerateMipmapErrorsTest::s_reference_internalformat = GL_R8;
12989const glw::GLenum GenerateMipmapErrorsTest::s_reference_format		   = GL_RED;
12990const glw::GLenum GenerateMipmapErrorsTest::s_reference_type		   = GL_UNSIGNED_BYTE;
12991
12992/******************************** Bind Unit Errors Test Implementation   ********************************/
12993
12994/** @brief Bind Unit Errors Test constructor.
12995 *
12996 *  @param [in] context     OpenGL context.
12997 */
12998BindUnitErrorsTest::BindUnitErrorsTest(deqp::Context& context)
12999	: deqp::TestCase(context, "textures_bind_unit_errors", "Texture Bind Unit Errors Test")
13000{
13001	/* Intentionally left blank. */
13002}
13003
13004/** @brief IterateBind Unit Errors Test cases.
13005 *
13006 *  @return Iteration result.
13007 */
13008tcu::TestNode::IterateResult BindUnitErrorsTest::iterate()
13009{
13010	/* Shortcut for GL functionality. */
13011	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
13012
13013	/* Get context setup. */
13014	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
13015	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
13016
13017	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
13018	{
13019		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
13020
13021		return STOP;
13022	}
13023
13024	/* Running tests. */
13025	bool is_ok	= true;
13026	bool is_error = false;
13027
13028	/* Objects. */
13029	glw::GLuint texture_invalid = 0;
13030
13031	try
13032	{
13033		/* Prepare invalid texture */
13034		while (gl.isTexture(++texture_invalid))
13035			;
13036
13037		/* incomplete cube map */
13038
13039		/* Check that INVALID_OPERATION error is generated if texture is not zero
13040		 or the name of an existing texture object. */
13041		gl.bindTextureUnit(0, texture_invalid);
13042		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glBindTextureUnit",
13043								  "texture is not zero or the name of an existing texture object.");
13044	}
13045	catch (...)
13046	{
13047		is_ok	= false;
13048		is_error = true;
13049	}
13050
13051	/* Cleanup. */
13052	while (GL_NO_ERROR != gl.getError())
13053		;
13054
13055	/* Result's setup. */
13056	if (is_ok)
13057	{
13058		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
13059	}
13060	else
13061	{
13062		if (is_error)
13063		{
13064			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
13065		}
13066		else
13067		{
13068			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
13069		}
13070	}
13071
13072	return STOP;
13073}
13074
13075/******************************** Image Query Errors Test Implementation   ********************************/
13076
13077/** @brief Image Query Errors Test constructor.
13078 *
13079 *  @param [in] context     OpenGL context.
13080 */
13081ImageQueryErrorsTest::ImageQueryErrorsTest(deqp::Context& context)
13082	: deqp::TestCase(context, "textures_image_query_errors", "Texture Image Query Errors Test")
13083{
13084	/* Intentionally left blank. */
13085}
13086
13087/** Reference data. */
13088const glw::GLuint ImageQueryErrorsTest::s_reference_data[] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
13089															   0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF };
13090
13091/** Reference data parameters. */
13092const glw::GLuint ImageQueryErrorsTest::s_reference_width					  = 4;
13093const glw::GLuint ImageQueryErrorsTest::s_reference_height					  = 4;
13094const glw::GLuint ImageQueryErrorsTest::s_reference_size					  = sizeof(s_reference_data);
13095const glw::GLenum ImageQueryErrorsTest::s_reference_internalformat			  = GL_R8;
13096const glw::GLenum ImageQueryErrorsTest::s_reference_internalformat_int		  = GL_R8I;
13097const glw::GLenum ImageQueryErrorsTest::s_reference_internalformat_compressed = GL_COMPRESSED_RED_RGTC1;
13098const glw::GLenum ImageQueryErrorsTest::s_reference_format					  = GL_RED;
13099const glw::GLenum ImageQueryErrorsTest::s_reference_type					  = GL_UNSIGNED_INT;
13100
13101/** @brief Iterate Image Query Errors Test cases.
13102 *
13103 *  @return Iteration result.
13104 */
13105tcu::TestNode::IterateResult ImageQueryErrorsTest::iterate()
13106{
13107	/* Shortcut for GL functionality. */
13108	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
13109
13110	/* Get context setup. */
13111	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
13112	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
13113
13114	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
13115	{
13116		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
13117
13118		return STOP;
13119	}
13120
13121	/* Running tests. */
13122	bool is_ok	= true;
13123	bool is_error = false;
13124
13125	/* Objects. */
13126	glw::GLuint buffer										  = 0;
13127	glw::GLuint texture_invalid								  = 0;
13128	glw::GLuint texture_2D									  = 0;
13129	glw::GLuint texture_2D_int								  = 0;
13130	glw::GLuint texture_2D_ms								  = 0;
13131	glw::GLuint texture_2D_stencil							  = 0;
13132	glw::GLuint texture_2D_compressed						  = 0;
13133	glw::GLuint texture_cube								  = 0;
13134	glw::GLuint texture_rectangle							  = 0;
13135	glw::GLint  max_level									  = 0;
13136	char		store[s_reference_size * 6 /* for cubemap */] = {};
13137
13138	try
13139	{
13140		/* Preparations. */
13141
13142		/* Buffer. */
13143		gl.createBuffers(1, &buffer);
13144
13145		gl.namedBufferData(buffer, s_reference_size + 1, NULL, GL_STATIC_COPY);
13146		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData has failed");
13147
13148		/* 2D texture */
13149		gl.genTextures(1, &texture_2D);
13150		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
13151
13152		gl.bindTexture(GL_TEXTURE_2D, texture_2D);
13153		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
13154
13155		gl.texImage2D(GL_TEXTURE_2D, 0, s_reference_internalformat, s_reference_width, s_reference_height, 0,
13156					  s_reference_format, s_reference_type, s_reference_data);
13157		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");
13158
13159		/* 2D texture */
13160		gl.genTextures(1, &texture_2D);
13161		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
13162
13163		gl.bindTexture(GL_TEXTURE_2D, texture_2D);
13164		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
13165
13166		gl.texImage2D(GL_TEXTURE_2D, 0, s_reference_internalformat, s_reference_width, s_reference_height, 0,
13167					  s_reference_format, s_reference_type, s_reference_data);
13168		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");
13169
13170		/* incomplete cube map */
13171		gl.genTextures(1, &texture_cube);
13172		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
13173
13174		gl.bindTexture(GL_TEXTURE_CUBE_MAP, texture_cube);
13175		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
13176
13177		gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, s_reference_internalformat, s_reference_width,
13178					  s_reference_height, 0, s_reference_format, s_reference_type, s_reference_data);
13179		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");
13180
13181		/* 2D multisample */
13182		gl.createTextures(GL_TEXTURE_2D_MULTISAMPLE, 1, &texture_2D_ms);
13183		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
13184
13185		gl.textureStorage2DMultisample(texture_2D_ms, 1, s_reference_internalformat, s_reference_width,
13186									   s_reference_height, false);
13187		GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2DMultisample has failed");
13188
13189		/* 2D stencil */
13190		gl.createTextures(GL_TEXTURE_2D, 1, &texture_2D_stencil);
13191		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
13192
13193		gl.textureStorage2D(texture_2D_stencil, 1, GL_STENCIL_INDEX8, s_reference_width, s_reference_height);
13194		GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2DMultisample has failed");
13195
13196		/* 2D compressed texture  */
13197		gl.genTextures(1, &texture_2D_compressed);
13198		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
13199
13200		gl.bindTexture(GL_TEXTURE_2D, texture_2D_compressed);
13201		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
13202
13203		gl.texImage2D(GL_TEXTURE_2D, 0, s_reference_internalformat_compressed, s_reference_width, s_reference_height, 0,
13204					  s_reference_format, s_reference_type, s_reference_data);
13205		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");
13206
13207		gl.getIntegerv(GL_MAX_TEXTURE_SIZE, &max_level); /* assuming that x > log(x) */
13208		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");
13209
13210		/* Rectangle texture */
13211		gl.genTextures(1, &texture_rectangle);
13212		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
13213
13214		gl.bindTexture(GL_TEXTURE_RECTANGLE, texture_rectangle);
13215		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
13216
13217		gl.texImage2D(GL_TEXTURE_RECTANGLE, 0, s_reference_internalformat, s_reference_width, s_reference_height, 0,
13218					  s_reference_format, s_reference_type, s_reference_data);
13219		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");
13220
13221		/* invalid texture */
13222		while (gl.isTexture(++texture_invalid))
13223			;
13224
13225		/* Tests. */
13226
13227		/* Check that INVALID_OPERATION is generated by GetTextureImage functions if
13228		 resulting texture target is not an accepted value TEXTURE_1D,
13229		 TEXTURE_2D, TEXTURE_3D, TEXTURE_1D_ARRAY, TEXTURE_2D_ARRAY,
13230		 TEXTURE_CUBE_MAP_ARRAY, TEXTURE_RECTANGLE, and TEXTURE_CUBE_MAP. */
13231		gl.getTextureImage(texture_2D_ms, 0, s_reference_format, s_reference_type, s_reference_size, store);
13232		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage",
13233								  "resulting texture target is not an accepted value TEXTURE_1D, TEXTURE_2D, "
13234								  "TEXTURE_3D, TEXTURE_1D_ARRAY, TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP_ARRAY, "
13235								  "TEXTURE_RECTANGLE, and TEXTURE_CUBE_MAP.");
13236
13237		/* Check that INVALID_OPERATION is generated by GetTextureImage
13238		 if texture is not the name of an existing texture object. */
13239		gl.getTextureImage(texture_invalid, 0, s_reference_format, s_reference_type, s_reference_size, store);
13240		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage",
13241								  "texture is not the name of an existing texture object.");
13242
13243		/* Check that INVALID_OPERATION error is generated by GetTextureImage if
13244		 the effective target is TEXTURE_CUBE_MAP or TEXTURE_CUBE_MAP_ARRAY, and
13245		 the texture object is not cube complete or cube array complete,
13246		 respectively. */
13247		gl.getTextureImage(texture_cube, 0, s_reference_format, s_reference_type, s_reference_size * 6, store);
13248		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage",
13249								  "the effective target is TEXTURE_CUBE_MAP and the texture object is not cube "
13250								  "complete or cube array complete, respectively.");
13251
13252		/* Check that GL_INVALID_VALUE is generated if level is less than 0 or
13253		 larger than the maximum allowable level. */
13254		gl.getTextureImage(texture_2D, -1, s_reference_format, s_reference_type, s_reference_size, store);
13255		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetTextureImage", "level is less than 0.");
13256
13257		gl.getTextureImage(texture_2D, max_level, s_reference_format, s_reference_type, s_reference_size, store);
13258		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetTextureImage",
13259								  "level is larger than the maximum allowable level.");
13260
13261		/* Check that INVALID_VALUE error is generated if level is non-zero and the
13262		 effective target is TEXTURE_RECTANGLE. */
13263		gl.getTextureImage(texture_rectangle, 1, s_reference_format, s_reference_type, s_reference_size, store);
13264		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetTextureImage",
13265								  "level is non-zero and the effective target is TEXTURE_RECTANGLE.");
13266
13267		/* Check that INVALID_OPERATION error is generated if any of the following
13268		 mismatches between format and the internal format of the texture image
13269		 exist:
13270		 -  format is a color format (one of the formats in table 8.3 whose
13271		 target is the color buffer) and the base internal format of the
13272		 texture image is not a color format.
13273		 -  format is DEPTH_COMPONENT and the base internal format is  not
13274		 DEPTH_COMPONENT or DEPTH_STENCIL
13275		 -  format is DEPTH_STENCIL and the base internal format is not
13276		 DEPTH_STENCIL
13277		 -  format is STENCIL_INDEX and the base internal format is not
13278		 STENCIL_INDEX or DEPTH_STENCIL
13279		 -  format is one of the integer formats in table 8.3 and the internal
13280		 format of the texture image is not integer, or format is not one of
13281		 the integer formats in table 8.3 and the internal format is integer. */
13282		gl.getTextureImage(texture_2D_stencil, 0, s_reference_format /* red */, s_reference_type, s_reference_size,
13283						   store);
13284		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage",
13285								  "format is a color format (one of the formats in table 8.3 whose target is the color "
13286								  "buffer) and the base internal format of the texture image is not a color format.");
13287
13288		gl.getTextureImage(texture_2D, 0, GL_DEPTH_COMPONENT, s_reference_type, s_reference_size, store);
13289		is_ok &= CheckErrorAndLog(
13290			m_context, GL_INVALID_OPERATION, "glGetTextureImage",
13291			"format is DEPTH_COMPONENT and the base internal format is not DEPTH_COMPONENT or DEPTH_STENCIL.");
13292
13293		gl.getTextureImage(texture_2D, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, s_reference_size, store);
13294		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage",
13295								  "format is DEPTH_STENCIL and the base internal format is not DEPTH_STENCIL.");
13296
13297		gl.getTextureImage(texture_2D, 0, GL_STENCIL_INDEX, s_reference_type, s_reference_size, store);
13298		is_ok &= CheckErrorAndLog(
13299			m_context, GL_INVALID_OPERATION, "glGetTextureImage",
13300			"format is STENCIL_INDEX and the base internal format is not STENCIL_INDEX or DEPTH_STENCIL.");
13301
13302		gl.getTextureImage(texture_2D, 0, GL_RED_INTEGER, s_reference_type, s_reference_size, store);
13303		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage",
13304								  "format is one of the integer formats in table 8.3 and the internal format of the "
13305								  "texture image is not integer.");
13306
13307		gl.getTextureImage(texture_2D_int, 0, GL_RED, s_reference_type, s_reference_size, store);
13308		is_ok &= CheckErrorAndLog(
13309			m_context, GL_INVALID_OPERATION, "glGetTextureImage",
13310			"format is not one of the integer formats in table 8.3 and the internal format is integer.");
13311
13312		/* Check that INVALID_OPERATION error is generated if a pixel pack buffer
13313		 object is bound and packing the texture image into the buffer's memory
13314		 would exceed the size of the buffer. */
13315		gl.bindBuffer(GL_PIXEL_PACK_BUFFER, buffer);
13316		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
13317
13318		gl.getTextureImage(texture_2D, 0, s_reference_format, s_reference_type, s_reference_size,
13319						   glu::BufferOffsetAsPointer(1 * sizeof(GLuint)));
13320		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage",
13321								  "a pixel pack buffer object is bound and packing the texture image into the buffer's "
13322								  "memory would exceed the size of the buffer.");
13323
13324		gl.bindBuffer(GL_PIXEL_PACK_BUFFER, 0);
13325		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
13326
13327		/* Check that INVALID_OPERATION error is generated if a pixel pack buffer
13328		 object is bound and pixels is not evenly divisible by the number of
13329		 basic machine units needed to store in memory the GL data type
13330		 corresponding to type (see table 8.2). */
13331		gl.bindBuffer(GL_PIXEL_PACK_BUFFER, buffer);
13332		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
13333
13334		gl.getTextureImage(texture_2D, 0, s_reference_format, s_reference_type, s_reference_size,
13335						   glu::BufferOffsetAsPointer(1));
13336		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage",
13337								  "a pixel pack buffer object is bound and pixels is not evenly divisible by the "
13338								  "number of basic machine units needed to store in memory the GL data type "
13339								  "corresponding to type (see table 8.2).");
13340
13341		gl.bindBuffer(GL_PIXEL_PACK_BUFFER, 0);
13342		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
13343
13344		/* Check that INVALID_OPERATION error is generated by GetTextureImage if
13345		 the buffer size required to store the requested data is greater than
13346		 bufSize. */
13347		gl.getTextureImage(texture_2D, 0, s_reference_format, s_reference_type,
13348						   s_reference_size - sizeof(s_reference_data[0]), store);
13349		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage",
13350								  "the buffer size required to store the requested data is greater than bufSize.");
13351
13352		/* Check that INVALID_OPERATION is generated by GetCompressedTextureImage
13353		 if texture is not the name of an existing texture object. */
13354		gl.getCompressedTextureImage(texture_invalid, 0, s_reference_size, store);
13355		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetCompressedTextureImage",
13356								  "texture is not the name of an existing texture object.");
13357
13358		/* Check that INVALID_VALUE is generated by GetCompressedTextureImage if
13359		 level is less than zero or greater than the maximum number of LODs
13360		 permitted by the implementation. */
13361		gl.getCompressedTextureImage(texture_2D_compressed, -1, s_reference_size, store);
13362		is_ok &=
13363			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetCompressedTextureImage", "level is less than zero.");
13364
13365		gl.getCompressedTextureImage(texture_2D_compressed, max_level, s_reference_size, store);
13366		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetCompressedTextureImage",
13367								  "level is greater than the maximum number of LODs permitted by the implementation.");
13368
13369		/* Check that INVALID_OPERATION is generated if GetCompressedTextureImage
13370		 is used to retrieve a texture that is in an uncompressed internal
13371		 format. */
13372		gl.getCompressedTextureImage(texture_2D, 0, s_reference_size, store);
13373		is_ok &=
13374			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetCompressedTextureImage",
13375							 "the function is used to retrieve a texture that is in an uncompressed internal format.");
13376
13377		/* Check that INVALID_OPERATION is generated by GetCompressedTextureImage
13378		 if a non-zero buffer object name is bound to the PIXEL_PACK_BUFFER
13379		 target, the buffer storage was not initialized with BufferStorage using
13380		 MAP_PERSISTENT_BIT flag, and the buffer object's data store is currently
13381		 mapped. */
13382		gl.bindBuffer(GL_PIXEL_PACK_BUFFER, buffer);
13383		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
13384
13385		gl.mapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_WRITE);
13386
13387		if (GL_NO_ERROR == gl.getError())
13388		{
13389			gl.getCompressedTextureImage(texture_2D_compressed, 0, s_reference_size, NULL);
13390			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetCompressedTextureImage",
13391									  "a non-zero buffer object name is bound to the PIXEL_PACK_BUFFER target, the "
13392									  "buffer storage was not initialized with BufferStorage using MAP_PERSISTENT_BIT "
13393									  "flag, and the buffer object's data store is currently mapped.");
13394
13395			gl.unmapBuffer(GL_PIXEL_PACK_BUFFER);
13396			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer has failed");
13397		}
13398		else
13399		{
13400			throw 0;
13401		}
13402
13403		gl.bindBuffer(GL_PIXEL_PACK_BUFFER, 0);
13404		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
13405
13406		/* Check that INVALID_OPERATION is generated by GetCompressedTextureImage
13407		 if a non-zero buffer object name is bound to the PIXEL_PACK_BUFFER
13408		 target and the data would be packed to the buffer object such that the
13409		 memory writes required would exceed the data store size. */
13410		gl.bindBuffer(GL_PIXEL_PACK_BUFFER, buffer);
13411		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
13412
13413		gl.getCompressedTextureImage(texture_2D_compressed, 0, s_reference_size, glu::BufferOffsetAsPointer(s_reference_size - 1));
13414		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetCompressedTextureImage",
13415								  "a non-zero buffer object name is bound to the PIXEL_PACK_BUFFER target and the data "
13416								  "would be packed to the buffer object such that the memory writes required would "
13417								  "exceed the data store size.");
13418
13419		gl.bindBuffer(GL_PIXEL_PACK_BUFFER, 0);
13420		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
13421	}
13422	catch (...)
13423	{
13424		is_ok	= false;
13425		is_error = true;
13426	}
13427
13428	/* Cleanup. */
13429	if (buffer)
13430	{
13431		gl.deleteBuffers(1, &buffer);
13432	}
13433
13434	if (texture_2D)
13435	{
13436		gl.deleteTextures(1, &texture_2D);
13437	}
13438
13439	if (texture_2D_int)
13440	{
13441		gl.deleteTextures(1, &texture_2D_int);
13442	}
13443
13444	if (texture_2D_stencil)
13445	{
13446		gl.deleteTextures(1, &texture_2D_stencil);
13447	}
13448
13449	if (texture_2D_ms)
13450	{
13451		gl.deleteTextures(1, &texture_2D_ms);
13452	}
13453
13454	if (texture_2D_compressed)
13455	{
13456		gl.deleteTextures(1, &texture_2D_compressed);
13457	}
13458
13459	if (texture_cube)
13460	{
13461		gl.deleteTextures(1, &texture_cube);
13462	}
13463
13464	if (texture_rectangle)
13465	{
13466		gl.deleteTextures(1, &texture_rectangle);
13467	}
13468
13469	while (GL_NO_ERROR != gl.getError())
13470		;
13471
13472	/* Result's setup. */
13473	if (is_ok)
13474	{
13475		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
13476	}
13477	else
13478	{
13479		if (is_error)
13480		{
13481			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
13482		}
13483		else
13484		{
13485			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
13486		}
13487	}
13488
13489	return STOP;
13490}
13491
13492/******************************** Level Parameter Query Errors Test Implementation   ********************************/
13493
13494/** @brief Image Query Errors Test constructor.
13495 *
13496 *  @param [in] context     OpenGL context.
13497 */
13498LevelParameterErrorsTest::LevelParameterErrorsTest(deqp::Context& context)
13499	: deqp::TestCase(context, "textures_level_parameter_errors", "Texture Level Parameter Query Errors Test")
13500{
13501	/* Intentionally left blank. */
13502}
13503
13504/** @brief Iterate Level Parameter Query Errors Test cases.
13505 *
13506 *  @return Iteration result.
13507 */
13508tcu::TestNode::IterateResult LevelParameterErrorsTest::iterate()
13509{
13510	/* Shortcut for GL functionality. */
13511	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
13512
13513	/* Get context setup. */
13514	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
13515	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
13516
13517	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
13518	{
13519		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
13520
13521		return STOP;
13522	}
13523
13524	/* Running tests. */
13525	bool is_ok	= true;
13526	bool is_error = false;
13527
13528	/* Objects. */
13529	glw::GLuint texture_2D		= 0;
13530	glw::GLuint texture_invalid = 0;
13531	glw::GLint  max_level		= 0;
13532	glw::GLenum pname_invalid   = 0;
13533
13534	glw::GLfloat storef[4] = {};
13535	glw::GLint   storei[4] = {};
13536
13537	try
13538	{
13539		/* Preparations. */
13540
13541		/* 2D texture */
13542		gl.genTextures(1, &texture_2D);
13543		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
13544
13545		gl.bindTexture(GL_TEXTURE_2D, texture_2D);
13546		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
13547
13548		gl.texStorage2D(GL_TEXTURE_2D, 1, GL_R8, 1, 1);
13549		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");
13550
13551		/* Limits. */
13552		gl.getIntegerv(GL_MAX_TEXTURE_SIZE, &max_level); /* assuming that x > log(x) */
13553		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");
13554
13555		/* invalid texture */
13556		while (gl.isTexture(++texture_invalid))
13557			;
13558
13559		/* invalid pname */
13560		glw::GLenum all_pnames[] = { GL_TEXTURE_WIDTH,
13561									 GL_TEXTURE_HEIGHT,
13562									 GL_TEXTURE_DEPTH,
13563									 GL_TEXTURE_SAMPLES,
13564									 GL_TEXTURE_FIXED_SAMPLE_LOCATIONS,
13565									 GL_TEXTURE_INTERNAL_FORMAT,
13566									 GL_TEXTURE_RED_SIZE,
13567									 GL_TEXTURE_GREEN_SIZE,
13568									 GL_TEXTURE_BLUE_SIZE,
13569									 GL_TEXTURE_ALPHA_SIZE,
13570									 GL_TEXTURE_DEPTH_SIZE,
13571									 GL_TEXTURE_STENCIL_SIZE,
13572									 GL_TEXTURE_SHARED_SIZE,
13573									 GL_TEXTURE_RED_TYPE,
13574									 GL_TEXTURE_GREEN_TYPE,
13575									 GL_TEXTURE_BLUE_TYPE,
13576									 GL_TEXTURE_ALPHA_TYPE,
13577									 GL_TEXTURE_DEPTH_TYPE,
13578									 GL_TEXTURE_COMPRESSED,
13579									 GL_TEXTURE_COMPRESSED_IMAGE_SIZE,
13580									 GL_TEXTURE_BUFFER_DATA_STORE_BINDING,
13581									 GL_TEXTURE_BUFFER_OFFSET,
13582									 GL_TEXTURE_BUFFER_SIZE };
13583
13584		glw::GLuint all_pnames_count = sizeof(all_pnames) / sizeof(all_pnames[0]);
13585
13586		bool is_valid = true;
13587
13588		while (is_valid)
13589		{
13590			is_valid = false;
13591
13592			++pname_invalid;
13593
13594			for (glw::GLuint i = 0; i < all_pnames_count; ++i)
13595			{
13596				if (all_pnames[i] == pname_invalid)
13597				{
13598					is_valid = true;
13599
13600					break;
13601				}
13602			}
13603		}
13604
13605		/* Tests. */
13606
13607		/* Check that INVALID_OPERATION is generated by GetTextureLevelParameterfv
13608		 and GetTextureLevelParameteriv functions if texture is not the name of
13609		 an existing texture object. */
13610		gl.getTextureLevelParameterfv(texture_invalid, 0, GL_TEXTURE_WIDTH, storef);
13611		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureLevelParameterfv",
13612								  "texture is not the name of an existing texture object.");
13613
13614		gl.getTextureLevelParameteriv(texture_invalid, 0, GL_TEXTURE_WIDTH, storei);
13615		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureLevelParameteriv",
13616								  "texture is not the name of an existing texture object.");
13617
13618		/* Check that INVALID_VALUE is generated by GetTextureLevelParameter* if
13619		 level is less than 0. */
13620		gl.getTextureLevelParameterfv(texture_2D, -1, GL_TEXTURE_WIDTH, storef);
13621		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetTextureLevelParameterfv", "level is less than 0.");
13622
13623		gl.getTextureLevelParameteriv(texture_2D, -1, GL_TEXTURE_WIDTH, storei);
13624		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetTextureLevelParameteriv", "level is less than 0.");
13625
13626		/* Check that INVALID_ENUM error is generated by GetTextureLevelParameter*
13627		 if pname is not one of supported constants. */
13628		gl.getTextureLevelParameterfv(texture_2D, 0, pname_invalid, storef);
13629		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glGetTextureLevelParameterfv",
13630								  "pname is not one of supported constants.");
13631
13632		gl.getTextureLevelParameteriv(texture_2D, 0, pname_invalid, storei);
13633		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glGetTextureLevelParameteriv",
13634								  "pname is not one of supported constants.");
13635
13636		/* Check that INVALID_VALUE may be generated if level is greater than
13637		 log2 max, where max is the returned value of MAX_TEXTURE_SIZE. */
13638		gl.getTextureLevelParameterfv(texture_2D, max_level, GL_TEXTURE_WIDTH, storef);
13639		is_ok &=
13640			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetTextureLevelParameterfv",
13641							 "level is greater than log2 max, where max is the returned value of MAX_TEXTURE_SIZE.");
13642
13643		gl.getTextureLevelParameteriv(texture_2D, max_level, GL_TEXTURE_WIDTH, storei);
13644		is_ok &=
13645			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetTextureLevelParameteriv",
13646							 "level is greater than log2 max, where max is the returned value of MAX_TEXTURE_SIZE.");
13647
13648		/* Check that INVALID_OPERATION is generated by GetTextureLevelParameter*
13649		 if TEXTURE_COMPRESSED_IMAGE_SIZE is queried on texture images with an
13650		 uncompressed internal format or on proxy targets. */
13651		gl.getTextureLevelParameterfv(texture_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, storef);
13652		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureLevelParameterfv",
13653								  "TEXTURE_COMPRESSED_IMAGE_SIZE is queried on texture images with an uncompressed "
13654								  "internal format or on proxy targets.");
13655
13656		gl.getTextureLevelParameteriv(texture_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, storei);
13657		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureLevelParameteriv",
13658								  "TEXTURE_COMPRESSED_IMAGE_SIZE is queried on texture images with an uncompressed "
13659								  "internal format or on proxy targets.");
13660	}
13661	catch (...)
13662	{
13663		is_ok	= false;
13664		is_error = true;
13665	}
13666
13667	/* Cleanup. */
13668	if (texture_2D)
13669	{
13670		gl.deleteTextures(1, &texture_2D);
13671	}
13672
13673	while (GL_NO_ERROR != gl.getError())
13674		;
13675
13676	/* Result's setup. */
13677	if (is_ok)
13678	{
13679		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
13680	}
13681	else
13682	{
13683		if (is_error)
13684		{
13685			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
13686		}
13687		else
13688		{
13689			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
13690		}
13691	}
13692
13693	return STOP;
13694}
13695
13696/******************************** Parameter Query Errors Test Implementation   ********************************/
13697
13698/** @brief Parameter Query Errors Test constructor.
13699 *
13700 *  @param [in] context     OpenGL context.
13701 */
13702ParameterErrorsTest::ParameterErrorsTest(deqp::Context& context)
13703	: deqp::TestCase(context, "textures_parameter_errors", "Texture Parameter Query Errors Test")
13704{
13705	/* Intentionally left blank. */
13706}
13707
13708/** @brief Iterate Parameter Query Errors Test cases.
13709 *
13710 *  @return Iteration result.
13711 */
13712tcu::TestNode::IterateResult ParameterErrorsTest::iterate()
13713{
13714	/* Shortcut for GL functionality. */
13715	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
13716
13717	/* Get context setup. */
13718	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
13719	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
13720
13721	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
13722	{
13723		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
13724
13725		return STOP;
13726	}
13727
13728	/* Running tests. */
13729	bool is_ok	= true;
13730	bool is_error = false;
13731
13732	/* Objects. */
13733	glw::GLuint texture_2D		= 0;
13734	glw::GLuint texture_buffer  = 0;
13735	glw::GLuint texture_invalid = 0;
13736	glw::GLenum pname_invalid   = 0;
13737
13738	glw::GLfloat storef[4] = {};
13739	glw::GLint   storei[4] = {};
13740	glw::GLuint  storeu[4] = {};
13741
13742	try
13743	{
13744		/* Preparations. */
13745
13746		/* 2D texture */
13747		gl.createTextures(GL_TEXTURE_2D, 1, &texture_2D);
13748		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
13749
13750		/* Buffer texture */
13751		gl.createTextures(GL_TEXTURE_BUFFER, 1, &texture_buffer);
13752		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
13753
13754		/* invalid texture */
13755		while (gl.isTexture(++texture_invalid))
13756			;
13757
13758		/* invalid pname */
13759		glw::GLenum all_pnames[] = { GL_IMAGE_FORMAT_COMPATIBILITY_TYPE,
13760									 GL_TEXTURE_IMMUTABLE_FORMAT,
13761									 GL_TEXTURE_IMMUTABLE_LEVELS,
13762									 GL_TEXTURE_TARGET,
13763									 GL_TEXTURE_VIEW_MIN_LEVEL,
13764									 GL_TEXTURE_VIEW_NUM_LEVELS,
13765									 GL_TEXTURE_VIEW_MIN_LAYER,
13766									 GL_TEXTURE_VIEW_NUM_LAYERS,
13767									 GL_DEPTH_STENCIL_TEXTURE_MODE,
13768									 GL_DEPTH_COMPONENT,
13769									 GL_STENCIL_INDEX,
13770									 GL_TEXTURE_BASE_LEVEL,
13771									 GL_TEXTURE_BORDER_COLOR,
13772									 GL_TEXTURE_COMPARE_MODE,
13773									 GL_TEXTURE_COMPARE_FUNC,
13774									 GL_TEXTURE_LOD_BIAS,
13775									 GL_TEXTURE_MAG_FILTER,
13776									 GL_TEXTURE_MAX_LEVEL,
13777									 GL_TEXTURE_MAX_LOD,
13778									 GL_TEXTURE_MIN_FILTER,
13779									 GL_TEXTURE_MIN_LOD,
13780									 GL_TEXTURE_SWIZZLE_R,
13781									 GL_TEXTURE_SWIZZLE_G,
13782									 GL_TEXTURE_SWIZZLE_B,
13783									 GL_TEXTURE_SWIZZLE_A,
13784									 GL_TEXTURE_SWIZZLE_RGBA,
13785									 GL_TEXTURE_WRAP_S,
13786									 GL_TEXTURE_WRAP_T,
13787									 GL_TEXTURE_WRAP_R };
13788
13789		glw::GLuint all_pnames_count = sizeof(all_pnames) / sizeof(all_pnames[0]);
13790
13791		bool is_valid = true;
13792
13793		while (is_valid)
13794		{
13795			is_valid = false;
13796
13797			++pname_invalid;
13798
13799			for (glw::GLuint i = 0; i < all_pnames_count; ++i)
13800			{
13801				if (all_pnames[i] == pname_invalid)
13802				{
13803					is_valid = true;
13804
13805					break;
13806				}
13807			}
13808		}
13809
13810		/* Tests. */
13811
13812		/* Check that INVALID_ENUM is generated by glGetTextureParameter* if pname
13813		 is not an accepted value. */
13814		gl.getTextureParameterfv(texture_2D, pname_invalid, storef);
13815		is_ok &=
13816			CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glGetTextureParameterfv", "pname is not an accepted value.");
13817
13818		gl.getTextureParameterIiv(texture_2D, pname_invalid, storei);
13819		is_ok &=
13820			CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glGetTextureParameterIiv", "pname is not an accepted value.");
13821
13822		gl.getTextureParameterIuiv(texture_2D, pname_invalid, storeu);
13823		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glGetTextureParameterIuiv",
13824								  "pname is not an accepted value.");
13825
13826		gl.getTextureParameteriv(texture_2D, pname_invalid, storei);
13827		is_ok &=
13828			CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glGetTextureParameteriv", "pname is not an accepted value.");
13829
13830		/* Check that INVALID_OPERATION is generated by glGetTextureParameter* if
13831		 texture is not the name of an existing texture object. */
13832		gl.getTextureParameterfv(texture_invalid, GL_TEXTURE_TARGET, storef);
13833		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureParameterfv",
13834								  "texture is not the name of an existing texture object.");
13835
13836		gl.getTextureParameterIiv(texture_invalid, GL_TEXTURE_TARGET, storei);
13837		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureParameterIiv",
13838								  "texture is not the name of an existing texture object.");
13839
13840		gl.getTextureParameterIuiv(texture_invalid, GL_TEXTURE_TARGET, storeu);
13841		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureParameterIuiv",
13842								  "texture is not the name of an existing texture object.");
13843
13844		gl.getTextureParameteriv(texture_invalid, GL_TEXTURE_TARGET, storei);
13845		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureParameteriv",
13846								  "texture is not the name of an existing texture object.");
13847
13848		/* Check that INVALID_OPERATION error is generated if the effective target is
13849		 not one of the supported texture targets (eg. TEXTURE_BUFFER). */
13850		gl.getTextureParameterfv(texture_buffer, GL_TEXTURE_TARGET, storef);
13851		is_ok &=
13852			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureParameterfv",
13853							 "the effective target is not one of the supported texture targets (eg. TEXTURE_BUFFER).");
13854
13855		gl.getTextureParameterIiv(texture_buffer, GL_TEXTURE_TARGET, storei);
13856		is_ok &=
13857			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureParameterIiv",
13858							 "the effective target is not one of the supported texture targets (eg. TEXTURE_BUFFER).");
13859
13860		gl.getTextureParameterIuiv(texture_buffer, GL_TEXTURE_TARGET, storeu);
13861		is_ok &=
13862			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureParameterIuiv",
13863							 "the effective target is not one of the supported texture targets (eg. TEXTURE_BUFFER).");
13864
13865		gl.getTextureParameteriv(texture_buffer, GL_TEXTURE_TARGET, storei);
13866		is_ok &=
13867			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureParameteriv",
13868							 "the effective target is not one of the supported texture targets (eg. TEXTURE_BUFFER).");
13869	}
13870	catch (...)
13871	{
13872		is_ok	= false;
13873		is_error = true;
13874	}
13875
13876	/* Cleanup. */
13877	if (texture_2D)
13878	{
13879		gl.deleteTextures(1, &texture_2D);
13880	}
13881
13882	if (texture_buffer)
13883	{
13884		gl.deleteTextures(1, &texture_buffer);
13885	}
13886
13887	while (GL_NO_ERROR != gl.getError())
13888		;
13889
13890	/* Result's setup. */
13891	if (is_ok)
13892	{
13893		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
13894	}
13895	else
13896	{
13897		if (is_error)
13898		{
13899			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
13900		}
13901		else
13902		{
13903			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
13904		}
13905	}
13906
13907	return STOP;
13908}
13909
13910} /* Textures namespace. */
13911} /* DirectStateAccess namespace. */
13912} /* gl4cts namespace. */
13913