Home | History | Annotate | Download | only in gl
      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  gl3cTransformFeedback.cpp
     27  * \brief Transform Feedback Test Suite Implementation
     28  */ /*-------------------------------------------------------------------*/
     29 
     30 /* Includes. */
     31 #include "gl3cTransformFeedbackTests.hpp"
     32 #include "gluContextInfo.hpp"
     33 #include "gluDefs.hpp"
     34 #include "gluRenderContext.hpp"
     35 #include "gluStrUtil.hpp"
     36 #include "tcuTestLog.hpp"
     37 
     38 #include <algorithm>
     39 #include <climits>
     40 #include <cmath>
     41 #include <cstdlib>
     42 #include <sstream>
     43 
     44 /* Stringify macro. */
     45 #define _STR(s) STR(s)
     46 #define STR(s) #s
     47 
     48 /* Unused attribute / variable MACRO.
     49  Some methods of clesses' heirs do not need all function parameters.
     50  This triggers warnings on GCC platform. This macro will silence them.
     51  */
     52 #ifdef __GNUC__
     53 #define UNUSED __attribute__((__unused__))
     54 #else
     55 #define UNUSED
     56 #endif
     57 
     58 gl3cts::TransformFeedback::Tests::Tests(deqp::Context& context)
     59 	: TestCaseGroup(context, "transform_feedback", "Transform Feedback Test Suite")
     60 {
     61 	addChild(new TransformFeedback::APIErrors(m_context));
     62 	addChild(new TransformFeedback::LinkingErrors(m_context));
     63 	addChild(new TransformFeedback::Limits(m_context));
     64 	addChild(new TransformFeedback::CaptureVertexInterleaved(m_context, "capture_vertex_interleaved_test",
     65 															 "Transform Feedback Capture Vertex Interleaved Test"));
     66 	addChild(new TransformFeedback::CaptureGeometryInterleaved(m_context, "capture_geometry_interleaved_test",
     67 															   "Transform Feedback Capture Geometry Interleaved Test"));
     68 	addChild(new TransformFeedback::CaptureVertexSeparate(m_context, "capture_vertex_separate_test",
     69 														  "Transform Feedback Capture Vertex Separate Test"));
     70 	addChild(new TransformFeedback::CaptureGeometrySeparate(m_context, "capture_geometry_separate_test",
     71 															"Transform Feedback Capture Geometry Separate Test"));
     72 	addChild(new TransformFeedback::CheckGetXFBVarying(m_context, "get_xfb_varying",
     73 													   "Transform Feedback Varying Getters Test"));
     74 	addChild(new TransformFeedback::QueryVertexInterleaved(m_context, "query_vertex_interleaved_test",
     75 														   "Transform Feedback Query Vertex Interleaved Test"));
     76 	addChild(new TransformFeedback::QueryGeometryInterleaved(m_context, "query_geometry_interleaved_test",
     77 															 "Transform Feedback Query Geometry Interleaved Test"));
     78 	addChild(new TransformFeedback::QueryVertexSeparate(m_context, "query_vertex_separate_test",
     79 														"Transform Feedback Query Vertex Separate Test"));
     80 	addChild(new TransformFeedback::QueryGeometrySeparate(m_context, "query_geometry_separate_test",
     81 														  "Transform Feedback Query Geometry Separate Test"));
     82 	addChild(new TransformFeedback::DiscardVertex(m_context, "discard_vertex_test",
     83 												  "Transform Feedback Discard Vertex Test"));
     84 	addChild(new TransformFeedback::DiscardGeometry(m_context, "discard_geometry_test",
     85 													"Transform Feedback Discard Geometry Test"));
     86 	addChild(new TransformFeedback::DrawXFB(m_context, "draw_xfb_test", "Transform Feedback Draw Test"));
     87 	addChild(new TransformFeedback::DrawXFBFeedback(m_context, "draw_xfb_feedbackk_test",
     88 													"Transform Feedback Draw Feedback Test"));
     89 	addChild(
     90 		new TransformFeedback::DrawXFBStream(m_context, "draw_xfb_stream_test", "Transform Feedback Draw Stream Test"));
     91 	addChild(new TransformFeedback::CaptureSpecialInterleaved(m_context, "capture_special_interleaved_test",
     92 															  "Transform Feedback Capture Special Test"));
     93 	addChild(new TransformFeedback::DrawXFBInstanced(m_context, "draw_xfb_instanced_test",
     94 													 "Transform Feedback Draw Instanced Test"));
     95 	addChild(new TransformFeedback::DrawXFBStreamInstanced(m_context, "draw_xfb_stream_instanced_test",
     96 														   "Transform Feedback Draw Stream Instanced Test"));
     97 }
     98 
     99 gl3cts::TransformFeedback::Tests::~Tests(void)
    100 {
    101 }
    102 
    103 void gl3cts::TransformFeedback::Tests::init(void)
    104 {
    105 }
    106 
    107 gl3cts::TransformFeedback::APIErrors::APIErrors(deqp::Context& context)
    108 	: deqp::TestCase(context, "api_errors_test", "Transform Feedback API Errors Test")
    109 	, m_context(context)
    110 	, m_buffer_0(0)
    111 	, m_buffer_1(0)
    112 	, m_vertex_array_object(0)
    113 	, m_transform_feedback_object_0(0)
    114 	, m_transform_feedback_object_1(0)
    115 	, m_query_object(0)
    116 	, m_program_id_with_input_output(0)
    117 	, m_program_id_with_output(0)
    118 	, m_program_id_without_output(0)
    119 	, m_program_id_with_geometry_shader(0)
    120 	, m_program_id_with_tessellation_shaders(0)
    121 	, m_glBindBufferOffsetEXT(DE_NULL)
    122 	, m_glGetIntegerIndexedvEXT(DE_NULL)
    123 	, m_glGetBooleanIndexedvEXT(DE_NULL)
    124 {
    125 }
    126 
    127 gl3cts::TransformFeedback::APIErrors::~APIErrors(void)
    128 {
    129 }
    130 
    131 tcu::TestNode::IterateResult gl3cts::TransformFeedback::APIErrors::iterate(void)
    132 {
    133 	/* Functions handler */
    134 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    135 
    136 	/* Initializations. */
    137 	bool is_at_least_gl_30 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(3, 0)));
    138 	bool is_at_least_gl_40 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 0)));
    139 	bool is_at_least_gl_42 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 2)));
    140 
    141 	bool is_ext_tf_1		 = m_context.getContextInfo().isExtensionSupported("GL_EXT_transform_feedback");
    142 	bool is_arb_tf_2		 = m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback2");
    143 	bool is_arb_tf_3		 = m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback3");
    144 	bool is_arb_tf_instanced = m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback_instanced");
    145 
    146 	if (is_ext_tf_1)
    147 	{
    148 		/* Extension query. */
    149 		m_glBindBufferOffsetEXT =
    150 			(BindBufferOffsetEXT_ProcAddress)m_context.getRenderContext().getProcAddress("glBindBufferOffsetEXT");
    151 		m_glGetIntegerIndexedvEXT =
    152 			(GetIntegerIndexedvEXT_ProcAddress)m_context.getRenderContext().getProcAddress("glGetIntegerIndexedvEXT");
    153 		m_glGetBooleanIndexedvEXT =
    154 			(GetBooleanIndexedvEXT_ProcAddress)m_context.getRenderContext().getProcAddress("glGetBooleanIndexedvEXT");
    155 	}
    156 
    157 	if (is_at_least_gl_40 || is_arb_tf_2)
    158 	{
    159 		/* Create transform feedback objects. */
    160 		gl.genTransformFeedbacks(1, &m_transform_feedback_object_0);
    161 
    162 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTransformFeedbacks call failed.");
    163 	}
    164 
    165 	if (is_at_least_gl_40 || is_arb_tf_3)
    166 	{
    167 		/* Create query object. */
    168 		gl.genQueries(1, &m_query_object);
    169 
    170 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenQueries call failed.");
    171 	}
    172 
    173 	if (is_at_least_gl_42 || is_arb_tf_instanced)
    174 	{
    175 		/* Create transform feedback objects. */
    176 		gl.genTransformFeedbacks(1, &m_transform_feedback_object_1);
    177 
    178 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTransformFeedbacks call failed.");
    179 	}
    180 
    181 	/* Default result. */
    182 	bool is_ok		= true;
    183 	bool test_error = false;
    184 
    185 	/* Entities setup. */
    186 	try
    187 	{
    188 		/* VAO setup. */
    189 		gl.genVertexArrays(1, &m_vertex_array_object);
    190 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
    191 
    192 		gl.bindVertexArray(m_vertex_array_object);
    193 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
    194 
    195 		/* Buffer setup. */
    196 		gl.genBuffers(1, &m_buffer_0);
    197 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
    198 
    199 		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_buffer_0);
    200 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
    201 
    202 		gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 16, NULL, GL_STATIC_DRAW);
    203 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
    204 
    205 		gl.genBuffers(1, &m_buffer_1);
    206 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
    207 
    208 		gl.bindBuffer(GL_ARRAY_BUFFER, m_buffer_1);
    209 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
    210 
    211 		gl.bufferData(GL_ARRAY_BUFFER, m_buffer_1_size, m_buffer_1_data, GL_STATIC_DRAW);
    212 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
    213 
    214 		/* Programs setup. */
    215 
    216 		m_program_id_with_input_output = gl3cts::TransformFeedback::Utilities::buildProgram(
    217 			gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, s_vertex_shader_with_input_output,
    218 			s_fragment_shader, &m_varying_name, 1, GL_INTERLEAVED_ATTRIBS);
    219 
    220 		m_program_id_with_output = gl3cts::TransformFeedback::Utilities::buildProgram(
    221 			gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, s_vertex_shader_with_output, s_fragment_shader,
    222 			&m_varying_name, 1, GL_INTERLEAVED_ATTRIBS, true);
    223 
    224 		m_program_id_without_output = gl3cts::TransformFeedback::Utilities::buildProgram(
    225 			gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, s_vertex_shader_without_output,
    226 			s_fragment_shader, NULL, 0, GL_SEPARATE_ATTRIBS);
    227 
    228 		m_program_id_with_geometry_shader = gl3cts::TransformFeedback::Utilities::buildProgram(
    229 			gl, m_context.getTestContext().getLog(), m_geometry_shader, NULL, NULL, s_vertex_shader_without_output,
    230 			s_fragment_shader, &m_varying_name, 1, GL_INTERLEAVED_ATTRIBS);
    231 
    232 		m_program_id_with_tessellation_shaders = gl3cts::TransformFeedback::Utilities::buildProgram(
    233 			gl, m_context.getTestContext().getLog(), NULL, m_tessellation_control_shader,
    234 			m_tessellation_evaluation_shader, s_vertex_shader_without_output, s_fragment_shader, &m_varying_name, 1,
    235 			GL_INTERLEAVED_ATTRIBS);
    236 
    237 		is_ok = is_ok && m_program_id_with_input_output && m_program_id_with_output && m_program_id_without_output &&
    238 				m_program_id_with_geometry_shader && m_program_id_with_tessellation_shaders;
    239 	}
    240 	catch (...)
    241 	{
    242 		is_ok	  = false;
    243 		test_error = true;
    244 	}
    245 
    246 	/* Iterating tests. */
    247 	try
    248 	{
    249 		if (is_at_least_gl_30 || is_ext_tf_1)
    250 		{
    251 			is_ok = is_ok && testExtension1();
    252 		}
    253 
    254 		if (is_at_least_gl_40 || is_arb_tf_2)
    255 		{
    256 			is_ok = is_ok && testExtension2();
    257 		}
    258 
    259 		if (is_at_least_gl_40 || is_arb_tf_3)
    260 		{
    261 			is_ok = is_ok && testExtension3();
    262 		}
    263 
    264 		if (is_at_least_gl_42 || is_arb_tf_instanced)
    265 		{
    266 			is_ok = is_ok && testInstanced();
    267 		}
    268 	}
    269 	catch (...)
    270 	{
    271 		is_ok	  = false;
    272 		test_error = true;
    273 	}
    274 
    275 	/* Deinitialization. */
    276 	if (m_vertex_array_object)
    277 	{
    278 		gl.deleteVertexArrays(1, &m_vertex_array_object);
    279 
    280 		m_vertex_array_object = 0;
    281 	}
    282 
    283 	if (m_buffer_0)
    284 	{
    285 		gl.deleteBuffers(1, &m_buffer_0); // silently unbinds
    286 
    287 		m_buffer_0 = 0;
    288 	}
    289 
    290 	if (m_buffer_1)
    291 	{
    292 		gl.deleteBuffers(1, &m_buffer_1); // silently unbinds
    293 
    294 		m_buffer_1 = 0;
    295 	}
    296 
    297 	if (m_transform_feedback_object_0)
    298 	{
    299 		gl.deleteTransformFeedbacks(1, &m_transform_feedback_object_0);
    300 
    301 		m_transform_feedback_object_0 = 0;
    302 	}
    303 
    304 	if (m_transform_feedback_object_1)
    305 	{
    306 		gl.deleteTransformFeedbacks(1, &m_transform_feedback_object_1);
    307 
    308 		m_transform_feedback_object_1 = 0;
    309 	}
    310 
    311 	if (m_query_object)
    312 	{
    313 		gl.deleteQueries(1, &m_query_object);
    314 
    315 		m_query_object = 0;
    316 	}
    317 
    318 	if (m_program_id_with_input_output)
    319 	{
    320 		gl.deleteProgram(m_program_id_with_input_output);
    321 
    322 		m_program_id_with_input_output = 0;
    323 	}
    324 
    325 	if (m_program_id_with_output)
    326 	{
    327 		gl.deleteProgram(m_program_id_with_output);
    328 
    329 		m_program_id_with_output = 0;
    330 	}
    331 
    332 	if (m_program_id_without_output)
    333 	{
    334 		gl.deleteProgram(m_program_id_without_output);
    335 
    336 		m_program_id_without_output = 0;
    337 	}
    338 
    339 	if (m_program_id_with_geometry_shader)
    340 	{
    341 		gl.deleteProgram(m_program_id_with_geometry_shader);
    342 
    343 		m_program_id_with_geometry_shader = 0;
    344 	}
    345 
    346 	if (m_program_id_with_tessellation_shaders)
    347 	{
    348 		gl.deleteProgram(m_program_id_with_tessellation_shaders);
    349 
    350 		m_program_id_with_tessellation_shaders = 0;
    351 	}
    352 
    353 	/* Result's setup. */
    354 	if (is_ok)
    355 	{
    356 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    357 	}
    358 	else
    359 	{
    360 		if (test_error)
    361 		{
    362 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
    363 		}
    364 		else
    365 		{
    366 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
    367 		}
    368 	}
    369 
    370 	return STOP;
    371 }
    372 
    373 bool gl3cts::TransformFeedback::APIErrors::testExtension1(void)
    374 {
    375 	/* Functions handler */
    376 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    377 
    378 	/*  INVALID_VALUE is generated by BindBufferRange, BindBufferOffset and
    379 	 BindBufferBase when <index> is greater or equal to
    380 	 MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS; */
    381 
    382 	glw::GLint index_count = 0;
    383 
    384 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &index_count);
    385 
    386 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
    387 
    388 	if (index_count == 0)
    389 	{
    390 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "glGetIntegerv did not returned any value."
    391 											<< tcu::TestLog::EndMessage;
    392 		throw 0;
    393 	}
    394 
    395 	gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, index_count, m_buffer_0, 0, 16);
    396 
    397 	if (GL_INVALID_VALUE != gl.getError())
    398 	{
    399 		m_context.getTestContext().getLog() << tcu::TestLog::Message
    400 											<< "INVALID_VALUE was not generated by BindBufferRange "
    401 											   "when <index> was greater or equal to "
    402 											   "MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS."
    403 											<< tcu::TestLog::EndMessage;
    404 		return false;
    405 	}
    406 
    407 	if (DE_NULL != m_glBindBufferOffsetEXT)
    408 	{
    409 		m_glBindBufferOffsetEXT(GL_TRANSFORM_FEEDBACK_BUFFER, index_count, m_buffer_0, 0);
    410 
    411 		if (GL_INVALID_VALUE != gl.getError())
    412 		{
    413 			m_context.getTestContext().getLog() << tcu::TestLog::Message
    414 												<< "INVALID_VALUE was not generated by BindBufferOffset "
    415 												   "when <index> was greater or equal to "
    416 												   "MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS."
    417 												<< tcu::TestLog::EndMessage;
    418 			return false;
    419 		}
    420 	}
    421 
    422 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, index_count, m_buffer_0);
    423 
    424 	if (GL_INVALID_VALUE != gl.getError())
    425 	{
    426 		m_context.getTestContext().getLog() << tcu::TestLog::Message
    427 											<< "INVALID_VALUE was not generated by "
    428 											   "BindBufferBase when <index> was greater or equal to "
    429 											   "MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS."
    430 											<< tcu::TestLog::EndMessage;
    431 		return false;
    432 	}
    433 
    434 	/*  INVALID_VALUE is generated by BindBufferRange when <size> is less or equal to zero; */
    435 
    436 	gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, index_count, m_buffer_0, 0, 0);
    437 
    438 	if (GL_INVALID_VALUE != gl.getError())
    439 	{
    440 		m_context.getTestContext().getLog()
    441 			<< tcu::TestLog::Message
    442 			<< "INVALID_VALUE was not generated by BindBufferRange when <size> was less or equal to zero."
    443 			<< tcu::TestLog::EndMessage;
    444 		return false;
    445 	}
    446 
    447 	/*  INVALID_VALUE is generated by BindBufferRange and BindBufferOffset
    448 	 when <offset> is not word-aligned; */
    449 
    450 	gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, index_count, m_buffer_0, 3, 4);
    451 
    452 	if (GL_INVALID_VALUE != gl.getError())
    453 	{
    454 		m_context.getTestContext().getLog()
    455 			<< tcu::TestLog::Message
    456 			<< "INVALID_VALUE was not generated by BindBufferRange when <offset> was not word-aligned."
    457 			<< tcu::TestLog::EndMessage;
    458 		return false;
    459 	}
    460 
    461 	if (DE_NULL != m_glBindBufferOffsetEXT)
    462 	{
    463 		m_glBindBufferOffsetEXT(GL_TRANSFORM_FEEDBACK_BUFFER, index_count, m_buffer_0, 3);
    464 
    465 		if (GL_INVALID_VALUE != gl.getError())
    466 		{
    467 			m_context.getTestContext().getLog()
    468 				<< tcu::TestLog::Message
    469 				<< "INVALID_VALUE was not generated by BindBufferOffset when <offset> was not word-aligned."
    470 				<< tcu::TestLog::EndMessage;
    471 			return false;
    472 		}
    473 	}
    474 
    475 	/*  INVALID_VALUE is generated by BindBufferRange when <size> is not word-aligned; */
    476 
    477 	gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, index_count, m_buffer_0, 0, 3);
    478 
    479 	if (GL_INVALID_VALUE != gl.getError())
    480 	{
    481 		m_context.getTestContext().getLog()
    482 			<< tcu::TestLog::Message
    483 			<< "INVALID_VALUE was not generated by BindBufferRange when <size> was not word-aligned."
    484 			<< tcu::TestLog::EndMessage;
    485 		return false;
    486 	}
    487 
    488 	/*  INVALID_OPERATION is generated by BindBufferRange, BindBufferOffset and
    489 	 BindBufferBase when <target> is TRANSFORM_FEEDBACK_BUFFER and transform
    490 	 feedback is active; */
    491 
    492 	gl.useProgram(m_program_id_with_output);
    493 
    494 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
    495 
    496 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_0);
    497 
    498 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed.");
    499 
    500 	gl.beginTransformFeedback(GL_POINTS);
    501 
    502 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
    503 
    504 	gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_0, 0, 16);
    505 
    506 	if (GL_INVALID_OPERATION != gl.getError())
    507 	{
    508 		m_context.getTestContext().getLog() << tcu::TestLog::Message
    509 											<< "INVALID_OPERATION was not generated by BindBufferRange "
    510 											   "when <target> was TRANSFORM_FEEDBACK_BUFFER and transform "
    511 											   "feedback was active."
    512 											<< tcu::TestLog::EndMessage;
    513 
    514 		gl.endTransformFeedback();
    515 
    516 		return false;
    517 	}
    518 
    519 	if (DE_NULL != m_glBindBufferOffsetEXT)
    520 	{
    521 		m_glBindBufferOffsetEXT(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_0, 0);
    522 
    523 		if (GL_INVALID_OPERATION != gl.getError())
    524 		{
    525 			m_context.getTestContext().getLog() << tcu::TestLog::Message
    526 												<< "INVALID_OPERATION was not generated by BindBufferOffset "
    527 												   "when <target> was TRANSFORM_FEEDBACK_BUFFER and transform "
    528 												   "feedback was active."
    529 												<< tcu::TestLog::EndMessage;
    530 
    531 			gl.endTransformFeedback();
    532 
    533 			return false;
    534 		}
    535 	}
    536 
    537 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_0);
    538 
    539 	if (GL_INVALID_OPERATION != gl.getError())
    540 	{
    541 		m_context.getTestContext().getLog()
    542 			<< tcu::TestLog::Message << "INVALID_OPERATION was not generated by "
    543 										"BindBufferBase when <target> was TRANSFORM_FEEDBACK_BUFFER and transform "
    544 										"feedback was active."
    545 			<< tcu::TestLog::EndMessage;
    546 
    547 		gl.endTransformFeedback();
    548 
    549 		return false;
    550 	}
    551 
    552 	gl.endTransformFeedback();
    553 
    554 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
    555 
    556 	/*  INVALID_OPERATION is generated by UseProgram when transform feedback is
    557 	 active; */
    558 
    559 	gl.beginTransformFeedback(GL_POINTS);
    560 
    561 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
    562 
    563 	gl.useProgram(0);
    564 
    565 	if (GL_INVALID_OPERATION != gl.getError())
    566 	{
    567 		m_context.getTestContext().getLog()
    568 			<< tcu::TestLog::Message
    569 			<< "INVALID_OPERATION was not generated by UseProgram when transform feedback was active."
    570 			<< tcu::TestLog::EndMessage;
    571 
    572 		gl.endTransformFeedback();
    573 
    574 		return false;
    575 	}
    576 
    577 	gl.endTransformFeedback();
    578 
    579 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
    580 
    581 	/*  INVALID_OPERATION is generated by LinkProgram when <program> is currently
    582 	 active and transform feedback is active; */
    583 
    584 	gl.useProgram(m_program_id_with_output);
    585 
    586 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
    587 
    588 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_0);
    589 
    590 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed.");
    591 
    592 	gl.beginTransformFeedback(GL_POINTS);
    593 
    594 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
    595 
    596 	gl.linkProgram(m_program_id_with_output);
    597 
    598 	if (GL_INVALID_OPERATION != gl.getError())
    599 	{
    600 		m_context.getTestContext().getLog() << tcu::TestLog::Message
    601 											<< "INVALID_OPERATION was not generated by LinkProgram when <program> was "
    602 											   "currently active and transform feedback was active."
    603 											<< tcu::TestLog::EndMessage;
    604 
    605 		gl.endTransformFeedback();
    606 
    607 		return false;
    608 	}
    609 
    610 	gl.endTransformFeedback();
    611 
    612 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
    613 
    614 	/*  INVALID_OPERATION is generated by BeginTransformFeedback when transform
    615 	 feedback is active; */
    616 
    617 	gl.useProgram(m_program_id_with_output);
    618 
    619 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
    620 
    621 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_0);
    622 
    623 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed.");
    624 
    625 	gl.beginTransformFeedback(GL_POINTS);
    626 
    627 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
    628 
    629 	gl.beginTransformFeedback(GL_POINTS);
    630 
    631 	if (GL_INVALID_OPERATION != gl.getError())
    632 	{
    633 		m_context.getTestContext().getLog()
    634 			<< tcu::TestLog::Message
    635 			<< "INVALID_OPERATION was not generated by BeginTransformFeedback when transform feedback was active."
    636 			<< tcu::TestLog::EndMessage;
    637 
    638 		gl.endTransformFeedback();
    639 
    640 		return false;
    641 	}
    642 
    643 	gl.endTransformFeedback();
    644 
    645 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
    646 
    647 	/*  INVALID_OPERATION is generated by EndTransformFeedback when transform
    648 	 feedback is inactive; */
    649 
    650 	gl.endTransformFeedback();
    651 
    652 	if (GL_INVALID_OPERATION != gl.getError())
    653 	{
    654 		m_context.getTestContext().getLog()
    655 			<< tcu::TestLog::Message
    656 			<< "INVALID_OPERATION was not generated by EndTransformFeedback when transform feedback was inactive."
    657 			<< tcu::TestLog::EndMessage;
    658 
    659 		return false;
    660 	}
    661 
    662 	/*  INVALID_OPERATION is generated by draw command when generated primitives
    663 	 type does not match <primitiveMode>; */
    664 
    665 	gl.useProgram(m_program_id_with_output);
    666 
    667 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
    668 
    669 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_0);
    670 
    671 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed.");
    672 
    673 	gl.beginTransformFeedback(GL_POINTS);
    674 
    675 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
    676 
    677 	gl.drawArrays(GL_LINES, 0, 2);
    678 
    679 	if (GL_INVALID_OPERATION != gl.getError())
    680 	{
    681 		m_context.getTestContext().getLog() << tcu::TestLog::Message
    682 											<< "INVALID_OPERATION was not generated by draw command when generated "
    683 											   "primitives type does not match <primitiveMode>."
    684 											<< tcu::TestLog::EndMessage;
    685 
    686 		gl.endTransformFeedback();
    687 
    688 		return false;
    689 	}
    690 
    691 	gl.endTransformFeedback();
    692 
    693 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
    694 
    695 	/*  INVALID_OPERATION is generated by BeginTransformFeedback when any binding
    696 	 point used by XFB does not have buffer bound; */
    697 
    698 	gl.useProgram(m_program_id_with_output);
    699 
    700 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
    701 
    702 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);
    703 
    704 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed.");
    705 
    706 	gl.beginTransformFeedback(GL_POINTS);
    707 
    708 	if (GL_INVALID_OPERATION != gl.getError())
    709 	{
    710 		m_context.getTestContext().getLog() << tcu::TestLog::Message
    711 											<< "INVALID_OPERATION was not generated by BeginTransformFeedback when any "
    712 											   "binding point used by XFB does not have buffer bound."
    713 											<< tcu::TestLog::EndMessage;
    714 
    715 		return false;
    716 	}
    717 
    718 	/*  INVALID_OPERATION is generated by BeginTransformFeedback when no program
    719 	 is active; */
    720 
    721 	gl.useProgram(0);
    722 
    723 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
    724 
    725 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_0);
    726 
    727 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed.");
    728 
    729 	gl.beginTransformFeedback(GL_POINTS);
    730 
    731 	if (GL_INVALID_OPERATION != gl.getError())
    732 	{
    733 		m_context.getTestContext().getLog()
    734 			<< tcu::TestLog::Message
    735 			<< "INVALID_OPERATION was not generated by BeginTransformFeedback when no program was active."
    736 			<< tcu::TestLog::EndMessage;
    737 
    738 		gl.endTransformFeedback();
    739 
    740 		return false;
    741 	}
    742 
    743 	/*  INVALID_OPERATION is generated by BeginTransformFeedback when no variable
    744 	 are specified to be captured in the active program; */
    745 
    746 	gl.useProgram(m_program_id_without_output);
    747 
    748 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
    749 
    750 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_0);
    751 
    752 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed.");
    753 
    754 	gl.beginTransformFeedback(GL_POINTS);
    755 
    756 	if (GL_INVALID_OPERATION != gl.getError())
    757 	{
    758 		m_context.getTestContext().getLog()
    759 			<< tcu::TestLog::Message
    760 			<< "INVALID_OPERATION was not generated by BeginTransformFeedback when no variable "
    761 			   "are specified to be captured in the active program."
    762 			<< tcu::TestLog::EndMessage;
    763 
    764 		gl.endTransformFeedback();
    765 
    766 		return false;
    767 	}
    768 
    769 	/*  INVALID_VALUE is generated by TransformFeedbackVaryings when <program> is
    770 	 not id of the program object; */
    771 
    772 	unsigned short int invalid_name = 1;
    773 
    774 	while (gl.isProgram(invalid_name) || gl.isShader(invalid_name))
    775 	{
    776 		++invalid_name;
    777 
    778 		/* Make sure that this loop ends someday, bad day. */
    779 		if (invalid_name == USHRT_MAX)
    780 		{
    781 			m_context.getTestContext().getLog()
    782 				<< tcu::TestLog::Message << "Cannot find unused trnasform feedback object." << tcu::TestLog::EndMessage;
    783 			throw 0;
    784 		}
    785 	}
    786 
    787 	gl.transformFeedbackVaryings((glw::GLuint)invalid_name, 1, &m_varying_name, GL_INTERLEAVED_ATTRIBS);
    788 
    789 	if (GL_INVALID_VALUE != gl.getError())
    790 	{
    791 		m_context.getTestContext().getLog() << tcu::TestLog::Message
    792 											<< "INVALID_VALUE was not generated by TransformFeedbackVaryings when "
    793 											   "<program> was not id of the program object."
    794 											<< tcu::TestLog::EndMessage;
    795 		return false;
    796 	}
    797 
    798 	/*  INVALID_VALUE is generated by TransformFeedbackVaryings when <bufferMode>
    799 	 is SEPARATE_ATTRIBS and <count> is exceeds limits; */
    800 
    801 	glw::GLint max_separate_attribs = 0;
    802 
    803 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &max_separate_attribs);
    804 
    805 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
    806 
    807 	if (max_separate_attribs == 0)
    808 	{
    809 		m_context.getTestContext().getLog()
    810 			<< tcu::TestLog::Message << "INVALID_VALUE was not generated by TransformFeedbackVaryings when <bufferMode>"
    811 										" was SEPARATE_ATTRIBS and <count> was exceeds limits."
    812 			<< tcu::TestLog::EndMessage;
    813 		throw 0;
    814 	}
    815 
    816 	glw::GLint more_than_max_separate_attribs = max_separate_attribs + 1;
    817 
    818 	glw::GLchar** attrib = new glw::GLchar*[more_than_max_separate_attribs];
    819 
    820 	for (glw::GLint i = 0; i < more_than_max_separate_attribs; ++i)
    821 	{
    822 		std::string new_attrib = "a" + gl3cts::TransformFeedback::Utilities::itoa(i);
    823 
    824 		size_t new_attrib_size = new_attrib.size();
    825 
    826 		attrib[i] = new glw::GLchar[new_attrib_size + 1];
    827 
    828 		memset(attrib[i], 0, new_attrib_size + 1);
    829 
    830 		memcpy(attrib[i], new_attrib.c_str(), new_attrib_size);
    831 	}
    832 
    833 	gl.transformFeedbackVaryings(m_program_id_with_output, more_than_max_separate_attribs, attrib, GL_SEPARATE_ATTRIBS);
    834 
    835 	for (glw::GLint i = 0; i < more_than_max_separate_attribs; ++i)
    836 	{
    837 		delete[] attrib[i];
    838 	}
    839 
    840 	delete[] attrib;
    841 
    842 	if (GL_INVALID_VALUE != gl.getError())
    843 	{
    844 		m_context.getTestContext().getLog() << tcu::TestLog::Message
    845 											<< "INVALID_VALUE was not generated by TransformFeedbackVaryings when "
    846 											   "<bufferMode> was SEPARATE_ATTRIBS and <count> exceeded limits."
    847 											<< tcu::TestLog::EndMessage;
    848 		return false;
    849 	}
    850 
    851 	/*  INVALID_VALUE is generated by GetTransformFeedbackVarying when <index> is
    852 	 greater than or equal to TRANSFORM_FEEDBACK_VARYINGS; */
    853 
    854 	glw::GLint transform_feedback_varyings = 0;
    855 
    856 	gl.getProgramiv(m_program_id_with_output, GL_TRANSFORM_FEEDBACK_VARYINGS, &transform_feedback_varyings);
    857 
    858 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");
    859 
    860 	if (transform_feedback_varyings == 0)
    861 	{
    862 		m_context.getTestContext().getLog() << tcu::TestLog::Message
    863 											<< "glGetProgramiv failed to return GL_TRANSFORM_FEEDBACK_VARYINGS."
    864 											<< tcu::TestLog::EndMessage;
    865 		throw 0;
    866 	}
    867 
    868 	glw::GLchar tmp_buffer[256];
    869 
    870 	glw::GLsizei tmp_size = 0;
    871 
    872 	glw::GLenum tmp_type = GL_NONE;
    873 
    874 	gl.getTransformFeedbackVarying(m_program_id_with_output, transform_feedback_varyings, sizeof(tmp_buffer), NULL,
    875 								   &tmp_size, &tmp_type, tmp_buffer);
    876 
    877 	if (GL_INVALID_VALUE != gl.getError())
    878 	{
    879 		m_context.getTestContext().getLog() << tcu::TestLog::Message
    880 											<< "INVALID_VALUE was not generated by GetTransformFeedbackVarying when "
    881 											   "<index> was greater than or equal to TRANSFORM_FEEDBACK_VARYINGS."
    882 											<< tcu::TestLog::EndMessage;
    883 		return false;
    884 	}
    885 
    886 	/*  INVALID_VALUE is generated by GetIntegerIndexdv when <index> exceeds the
    887 	 limits of MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS and <param> is one of the
    888 	 following:
    889 	 * TRANSFORM_FEEDBACK_BUFFER_BINDING,
    890 	 * TRANSFORM_FEEDBACK_BUFFER_START,
    891 	 * TRANSFORM_FEEDBACK_BUFFER_SIZE; */
    892 
    893 	if (DE_NULL != m_glGetIntegerIndexedvEXT)
    894 	{
    895 		glw::GLint tmp_int_value;
    896 
    897 		m_glGetIntegerIndexedvEXT(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, more_than_max_separate_attribs, &tmp_int_value);
    898 
    899 		if (GL_INVALID_VALUE != gl.getError())
    900 		{
    901 			m_context.getTestContext().getLog()
    902 				<< tcu::TestLog::Message
    903 				<< "INVALID_VALUE was not generated by GetIntegerIndexdv when <index> exceeds the "
    904 				   "limits of MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS and <param> was "
    905 				   "TRANSFORM_FEEDBACK_BUFFER_BINDING."
    906 				<< tcu::TestLog::EndMessage;
    907 			return false;
    908 		}
    909 
    910 		m_glGetIntegerIndexedvEXT(GL_TRANSFORM_FEEDBACK_BUFFER_START, more_than_max_separate_attribs, &tmp_int_value);
    911 
    912 		if (GL_INVALID_VALUE != gl.getError())
    913 		{
    914 			m_context.getTestContext().getLog()
    915 				<< tcu::TestLog::Message
    916 				<< "INVALID_VALUE was not generated by GetIntegerIndexdv when <index> exceeds the "
    917 				   "limits of MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS and <param> was "
    918 				   "GL_TRANSFORM_FEEDBACK_BUFFER_START."
    919 				<< tcu::TestLog::EndMessage;
    920 			return false;
    921 		}
    922 
    923 		m_glGetIntegerIndexedvEXT(GL_TRANSFORM_FEEDBACK_BUFFER_SIZE, more_than_max_separate_attribs, &tmp_int_value);
    924 
    925 		if (GL_INVALID_VALUE != gl.getError())
    926 		{
    927 			m_context.getTestContext().getLog()
    928 				<< tcu::TestLog::Message
    929 				<< "INVALID_VALUE was not generated by GetIntegerIndexdv when <index> exceeds the "
    930 				   "limits of MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS and <param> was "
    931 				   "GL_TRANSFORM_FEEDBACK_BUFFER_SIZE."
    932 				<< tcu::TestLog::EndMessage;
    933 			return false;
    934 		}
    935 	}
    936 
    937 	/*  INVALID_VALUE is generated by GetBooleanIndexedv when <index> exceeds the
    938 	 limits of MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS and <param> is
    939 	 TRANSFORM_FEEDBACK_BUFFER_BINDING. */
    940 
    941 	if (DE_NULL != m_glGetBooleanIndexedvEXT)
    942 	{
    943 		glw::GLboolean tmp_bool_value;
    944 
    945 		m_glGetBooleanIndexedvEXT(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, more_than_max_separate_attribs,
    946 								  &tmp_bool_value);
    947 
    948 		if (GL_INVALID_VALUE != gl.getError())
    949 		{
    950 			m_context.getTestContext().getLog()
    951 				<< tcu::TestLog::Message
    952 				<< "INVALID_VALUE was not generated by GetBooleanIndexedv when <index> exceeds the "
    953 				   "limits of MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS and <param> was "
    954 				   "TRANSFORM_FEEDBACK_BUFFER_BINDING."
    955 				<< tcu::TestLog::EndMessage;
    956 			return false;
    957 		}
    958 	}
    959 
    960 	return true;
    961 }
    962 
    963 bool gl3cts::TransformFeedback::APIErrors::testExtension2(void)
    964 {
    965 	/* Functions handler */
    966 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    967 
    968 	/*  Bind Transform Feedback Object */
    969 	gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_transform_feedback_object_0);
    970 
    971 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedback call failed.");
    972 
    973 	/*  INVALID_OPERATION is generated by PauseTransformFeedback if current
    974 	 transform feedback is not active or paused; */
    975 
    976 	gl.pauseTransformFeedback();
    977 
    978 	if (GL_INVALID_OPERATION != gl.getError())
    979 	{
    980 		m_context.getTestContext().getLog() << tcu::TestLog::Message
    981 											<< "INVALID_OPERATION is not generated by PauseTransformFeedback if "
    982 											   "current transform feedback is not active or paused."
    983 											<< tcu::TestLog::EndMessage;
    984 
    985 		return false;
    986 	}
    987 
    988 	/*  INVALID_OPERATION is generated by ResumeTransformFeedback if current
    989 	 transform feedback is not active; */
    990 
    991 	gl.resumeTransformFeedback();
    992 
    993 	if (GL_INVALID_OPERATION != gl.getError())
    994 	{
    995 		m_context.getTestContext().getLog() << tcu::TestLog::Message
    996 											<< "INVALID_OPERATION is not generated by ResumeTransformFeedback if "
    997 											   "current transform feedback is not active."
    998 											<< tcu::TestLog::EndMessage;
    999 
   1000 		return false;
   1001 	}
   1002 
   1003 	/*  Prepare program and buffer. */
   1004 	gl.useProgram(m_program_id_with_output);
   1005 
   1006 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
   1007 
   1008 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_0);
   1009 
   1010 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed.");
   1011 
   1012 	/*  INVALID_OPERATION is generated by DrawTransformFeedback when
   1013 	 EndTransformFeedback was never called for the object named <id>. */
   1014 	gl.drawTransformFeedback(GL_POINTS, m_transform_feedback_object_0);
   1015 
   1016 	if (GL_INVALID_OPERATION != gl.getError())
   1017 	{
   1018 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1019 											<< "INVALID_OPERATION is not generated by DrawTransformFeedback when "
   1020 											   "EndTransformFeedback was never called for the object named <id>."
   1021 											<< tcu::TestLog::EndMessage;
   1022 
   1023 		return false;
   1024 	}
   1025 
   1026 	/*  Make Transform Feedback Active */
   1027 	gl.beginTransformFeedback(GL_POINTS);
   1028 
   1029 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
   1030 
   1031 	/*  INVALID_OPERATION is generated by BindTransformFeedback if current
   1032 	 transform feedback is active and not paused; */
   1033 
   1034 	gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_transform_feedback_object_0);
   1035 
   1036 	if (GL_INVALID_OPERATION != gl.getError())
   1037 	{
   1038 		gl.endTransformFeedback();
   1039 
   1040 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1041 											<< "INVALID_OPERATION is not generated by BindTransformFeedback if current "
   1042 											   "transform feedback is active and not paused."
   1043 											<< tcu::TestLog::EndMessage;
   1044 
   1045 		return false;
   1046 	}
   1047 
   1048 	/*  INVALID_OPERATION is generated by DeleteTransformFeedbacks if any of <ids>
   1049 	 is active; */
   1050 
   1051 	gl.deleteTransformFeedbacks(1, &m_transform_feedback_object_0);
   1052 
   1053 	if (GL_INVALID_OPERATION != gl.getError())
   1054 	{
   1055 		gl.endTransformFeedback();
   1056 
   1057 		m_context.getTestContext().getLog()
   1058 			<< tcu::TestLog::Message
   1059 			<< "INVALID_OPERATION is not generated by DeleteTransformFeedbacks if any of <ids> is active."
   1060 			<< tcu::TestLog::EndMessage;
   1061 
   1062 		return false;
   1063 	}
   1064 
   1065 	/*  INVALID_OPERATION is generated by ResumeTransformFeedback if current
   1066 	 transform feedback is not not paused; */
   1067 
   1068 	gl.resumeTransformFeedback();
   1069 
   1070 	if (GL_INVALID_OPERATION != gl.getError())
   1071 	{
   1072 		gl.endTransformFeedback();
   1073 
   1074 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1075 											<< "INVALID_OPERATION is not generated by ResumeTransformFeedback if "
   1076 											   "current transform feedback is not not paused."
   1077 											<< tcu::TestLog::EndMessage;
   1078 
   1079 		return false;
   1080 	}
   1081 
   1082 	/*  pause transform feedback */
   1083 
   1084 	gl.pauseTransformFeedback();
   1085 
   1086 	GLU_EXPECT_NO_ERROR(gl.getError(), "glPauseTransformFeedback call failed.");
   1087 
   1088 	/*  No error is generated by draw command when transform feedback is paused
   1089 	 and primitive modes do not match; */
   1090 
   1091 	gl.drawArrays(GL_LINES, 0, 2);
   1092 
   1093 	if (GL_NO_ERROR != gl.getError())
   1094 	{
   1095 		gl.endTransformFeedback();
   1096 
   1097 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1098 											<< "No error is not generated by draw command when transform feedback is "
   1099 											   "paused and primitive modes do not match."
   1100 											<< tcu::TestLog::EndMessage;
   1101 
   1102 		return false;
   1103 	}
   1104 
   1105 	/*  INVALID_OPERATION is generated by LinkProgram when <program> is used by
   1106 	 some transform feedback object that is currently not active; */
   1107 
   1108 	gl.linkProgram(m_program_id_with_output);
   1109 
   1110 	if (GL_INVALID_OPERATION != gl.getError())
   1111 	{
   1112 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1113 											<< "INVALID_OPERATION was not generated by LinkProgram when <program> was "
   1114 											   "used by some transform feedback object that is currently not active."
   1115 											<< tcu::TestLog::EndMessage;
   1116 
   1117 		gl.endTransformFeedback();
   1118 
   1119 		return false;
   1120 	}
   1121 
   1122 	/*  No error is generated by UseProgram when transform feedback is paused; */
   1123 
   1124 	gl.useProgram(0);
   1125 
   1126 	if (GL_NO_ERROR != gl.getError())
   1127 	{
   1128 		gl.endTransformFeedback();
   1129 
   1130 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1131 											<< "glUseProgram unexpectedly failed when transform feedback is paused."
   1132 											<< tcu::TestLog::EndMessage;
   1133 
   1134 		return false;
   1135 	}
   1136 
   1137 	gl.useProgram(m_program_id_with_output);
   1138 
   1139 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
   1140 
   1141 	/*  End Transform Feedback and make draw. */
   1142 
   1143 	gl.endTransformFeedback();
   1144 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
   1145 
   1146 	/*  INVALID_VALUE is generated by DrawTransformFeedback if <id> is not name of
   1147 	 transform feedback object; */
   1148 
   1149 	unsigned short int invalid_name = 1;
   1150 
   1151 	while (gl.isTransformFeedback(invalid_name))
   1152 	{
   1153 		++invalid_name;
   1154 
   1155 		/* Make sure that this loop ends someday, bad day. */
   1156 		if (invalid_name == USHRT_MAX)
   1157 		{
   1158 			m_context.getTestContext().getLog()
   1159 				<< tcu::TestLog::Message << "Cannot find unused trnasform feedback object." << tcu::TestLog::EndMessage;
   1160 			throw 0;
   1161 		}
   1162 	}
   1163 
   1164 	gl.drawTransformFeedback(GL_POINTS, (glw::GLuint)invalid_name);
   1165 
   1166 	if (GL_INVALID_VALUE != gl.getError())
   1167 	{
   1168 		gl.endTransformFeedback();
   1169 
   1170 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1171 											<< "glUseProgram unexpectedly failed when transform feedback is paused."
   1172 											<< tcu::TestLog::EndMessage;
   1173 
   1174 		return false;
   1175 	}
   1176 
   1177 	return true;
   1178 }
   1179 
   1180 bool gl3cts::TransformFeedback::APIErrors::testExtension3(void)
   1181 {
   1182 	/* Functions handler */
   1183 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1184 
   1185 	/*  INVALID_VALUE is generated by BeginQueryIndexed, EndQueryIndexed and
   1186 	 GetQueryIndexediv when <target> is TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN and
   1187 	 <index> exceeds limits of MAX_VERTEX_STREAMS
   1188 
   1189 	 INVALID_VALUE is generated by BeginQueryIndexed, EndQueryIndexed and
   1190 	 GetQueryIndexediv when <target> is PRIMITIVES_GENERATED and <index> exceeds
   1191 	 limits of MAX_VERTEX_STREAMS */
   1192 
   1193 	glw::GLint max_vertex_streams = 0;
   1194 
   1195 	gl.getIntegerv(GL_MAX_VERTEX_STREAMS, &max_vertex_streams);
   1196 
   1197 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   1198 
   1199 	if (max_vertex_streams == 0)
   1200 	{
   1201 		/* Nothing returned. */
   1202 		throw 0;
   1203 	}
   1204 
   1205 	++max_vertex_streams;
   1206 
   1207 	static const glw::GLenum  target[]	 = { GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, GL_PRIMITIVES_GENERATED };
   1208 	static const glw::GLchar* target_str[] = { STR(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN),
   1209 											   STR(GL_PRIMITIVES_GENERATED) };
   1210 	static const glw::GLuint target_count = sizeof(target) / sizeof(target[0]);
   1211 
   1212 	for (glw::GLuint i = 0; i < target_count; ++i)
   1213 	{
   1214 		gl.beginQueryIndexed(target[i], max_vertex_streams, m_query_object);
   1215 
   1216 		if (GL_INVALID_VALUE != gl.getError())
   1217 		{
   1218 			m_context.getTestContext().getLog()
   1219 				<< tcu::TestLog::Message << "INVALID_VALUE was not generated by BeginQueryIndexed, EndQueryIndexed and"
   1220 											"GetQueryIndexediv when <target> was "
   1221 				<< target_str[i] << " and "
   1222 									"<index> exceeded limits of MAX_VERTEX_STREAMS."
   1223 				<< tcu::TestLog::EndMessage;
   1224 			return false;
   1225 		}
   1226 
   1227 		gl.endQueryIndexed(target[i], max_vertex_streams);
   1228 
   1229 		if (GL_INVALID_VALUE != gl.getError())
   1230 		{
   1231 			m_context.getTestContext().getLog() << tcu::TestLog::Message
   1232 												<< "INVALID_VALUE was not generated by EndQueryIndexed "
   1233 												   "when <target> was "
   1234 												<< target_str[i] << " and "
   1235 																	"<index> exceeded limits of MAX_VERTEX_STREAMS."
   1236 												<< tcu::TestLog::EndMessage;
   1237 			return false;
   1238 		}
   1239 
   1240 		glw::GLint param = 0;
   1241 
   1242 		gl.getQueryIndexediv(target[i], max_vertex_streams, GL_QUERY_COUNTER_BITS, &param);
   1243 
   1244 		if (GL_INVALID_VALUE != gl.getError())
   1245 		{
   1246 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "INVALID_VALUE was not generated by "
   1247 																			"GetQueryIndexediv when <target> was "
   1248 												<< target_str[i] << " and "
   1249 																	"<index> exceeded limits of MAX_VERTEX_STREAMS."
   1250 												<< tcu::TestLog::EndMessage;
   1251 			return false;
   1252 		}
   1253 	}
   1254 
   1255 	/*  INVALID_OPERATION is generated by EndQueryIndexed when name of active
   1256 	 query at <index> of <target> is zero */
   1257 
   1258 	gl.endQueryIndexed(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, 0);
   1259 
   1260 	if (GL_INVALID_OPERATION != gl.getError())
   1261 	{
   1262 		m_context.getTestContext().getLog()
   1263 			<< tcu::TestLog::Message << "INVALID_OPERATION was not generated by EndQueryIndexed when name of active "
   1264 										"query at <index> of <target> is zero"
   1265 			<< tcu::TestLog::EndMessage;
   1266 		return false;
   1267 	}
   1268 
   1269 	/*  INVALID_VALUE is generated by DrawTransformFeedbackStream when <stream>
   1270 	 exceeds limits of MAX_VERTEX_STREAMS */
   1271 
   1272 	gl.drawTransformFeedbackStream(GL_POINTS, m_transform_feedback_object_0, max_vertex_streams);
   1273 
   1274 	if (GL_INVALID_VALUE != gl.getError())
   1275 	{
   1276 		m_context.getTestContext().getLog()
   1277 			<< tcu::TestLog::Message << "INVALID_VALUE was not generated by DrawTransformFeedbackStream when <stream> "
   1278 										"exceeded limits of MAX_VERTEX_STREAMS"
   1279 			<< tcu::TestLog::EndMessage;
   1280 		return false;
   1281 	}
   1282 
   1283 	/*  INVALID_OPERATION is generated by TransformFeedbackVaryings when
   1284 	 <varyings> contains any of the special names while <bufferMode> is not
   1285 	 INTERLEAVED_ATTRIBS */
   1286 
   1287 	static const glw::GLchar* tf_varying_names[] = { "gl_NextBuffer", "gl_SkipComponents1", "gl_SkipComponents2",
   1288 													 "gl_SkipComponents3", "gl_SkipComponents4" };
   1289 	static const glw::GLuint tf_varying_names_count = sizeof(tf_varying_names) / sizeof(tf_varying_names[0]);
   1290 
   1291 	for (glw::GLuint i = 0; i < tf_varying_names_count; ++i)
   1292 	{
   1293 		gl.transformFeedbackVaryings(m_program_id_with_output, 1, &tf_varying_names[i], GL_SEPARATE_ATTRIBS);
   1294 
   1295 		if (GL_INVALID_OPERATION != gl.getError())
   1296 		{
   1297 			m_context.getTestContext().getLog()
   1298 				<< tcu::TestLog::Message << "INVALID_OPERATION was not generated by TransformFeedbackVaryings when "
   1299 											"<varyings> contained any of the special names while <bufferMode> was "
   1300 											"GL_SEPARATE_ATTRIBS."
   1301 				<< tcu::TestLog::EndMessage;
   1302 			return false;
   1303 		}
   1304 	}
   1305 
   1306 	/*  INVALID_OPERATION is generated by TransformFeedbackVaryings when
   1307 	 <varyings> contains more "gl_NextBuffer" entries than allowed limit of
   1308 	 MAX_TRANSFORM_FEEDBACK_BUFFERS */
   1309 
   1310 	glw::GLint max_transform_feedback_buffers = 0;
   1311 
   1312 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers);
   1313 
   1314 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   1315 
   1316 	if (max_transform_feedback_buffers == 0)
   1317 	{
   1318 		/* Nothing returned. */
   1319 		throw 0;
   1320 	}
   1321 
   1322 	glw::GLint more_than_max_transform_feedback_buffers = max_transform_feedback_buffers + 1;
   1323 
   1324 	const glw::GLchar** tf_next_buffer_varying_names = new const glw::GLchar*[more_than_max_transform_feedback_buffers];
   1325 
   1326 	if (DE_NULL == tf_next_buffer_varying_names)
   1327 	{
   1328 		/* Allocation error. */
   1329 		throw 0;
   1330 	}
   1331 
   1332 	for (glw::GLint i = 0; i < more_than_max_transform_feedback_buffers; ++i)
   1333 	{
   1334 		tf_next_buffer_varying_names[i] = tf_varying_names[0];
   1335 	}
   1336 
   1337 	gl.transformFeedbackVaryings(m_program_id_with_output, more_than_max_transform_feedback_buffers,
   1338 								 tf_next_buffer_varying_names, GL_INTERLEAVED_ATTRIBS);
   1339 
   1340 	delete[] tf_next_buffer_varying_names;
   1341 
   1342 	if (GL_INVALID_OPERATION != gl.getError())
   1343 	{
   1344 		m_context.getTestContext().getLog()
   1345 			<< tcu::TestLog::Message << "INVALID_OPERATION was not generated by TransformFeedbackVaryings when "
   1346 										"<varyings> contained more \"gl_NextBuffer\" entries than allowed limit of "
   1347 										"MAX_TRANSFORM_FEEDBACK_BUFFER."
   1348 			<< tcu::TestLog::EndMessage;
   1349 		return false;
   1350 	}
   1351 
   1352 	return true;
   1353 }
   1354 
   1355 bool gl3cts::TransformFeedback::APIErrors::testInstanced(void)
   1356 {
   1357 	/* Functions handler */
   1358 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1359 
   1360 	/*  INVALID_ENUM is generated by DrawTransformFeedbackInstanced and
   1361 	 DrawTransformFeedbackStreamInstanced if <mode> is invalid */
   1362 
   1363 	glw::GLenum _supported_mode[] = { GL_POINTS,
   1364 									  GL_LINE_STRIP,
   1365 									  GL_LINE_LOOP,
   1366 									  GL_LINES,
   1367 									  GL_LINE_STRIP_ADJACENCY,
   1368 									  GL_LINES_ADJACENCY,
   1369 									  GL_TRIANGLE_STRIP,
   1370 									  GL_TRIANGLE_FAN,
   1371 									  GL_TRIANGLES,
   1372 									  GL_TRIANGLE_STRIP_ADJACENCY,
   1373 									  GL_TRIANGLES_ADJACENCY,
   1374 									  GL_PATCHES };
   1375 
   1376 	std::set<glw::GLenum> supported_mode(_supported_mode,
   1377 										 _supported_mode + sizeof(_supported_mode) / sizeof(_supported_mode[0]));
   1378 
   1379 	int mode = 0;
   1380 
   1381 	while (supported_mode.find(mode) != supported_mode.end())
   1382 	{
   1383 		mode++;
   1384 	}
   1385 
   1386 	gl.drawTransformFeedbackInstanced(mode, m_transform_feedback_object_0, 1);
   1387 
   1388 	if (GL_INVALID_ENUM != gl.getError())
   1389 	{
   1390 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1391 											<< "INVALID_ENUM was not generated by DrawTransformFeedbackInstanced and "
   1392 											   "DrawTransformFeedbackStreamInstanced when <mode> was invalid."
   1393 											<< tcu::TestLog::EndMessage;
   1394 		return false;
   1395 	}
   1396 
   1397 	gl.drawTransformFeedbackStreamInstanced(mode, m_transform_feedback_object_0, 0, 1);
   1398 
   1399 	if (GL_INVALID_ENUM != gl.getError())
   1400 	{
   1401 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1402 											<< "INVALID_ENUM was not generated by DrawTransformFeedbackInstanced and "
   1403 											   "DrawTransformFeedbackStreamInstanced when <mode> was invalid."
   1404 											<< tcu::TestLog::EndMessage;
   1405 		return false;
   1406 	}
   1407 
   1408 	/*  INVALID_OPERATION is generated by DrawTransformFeedbackInstanced and
   1409 	 DrawTransformFeedbackStreamInstanced if <mode> does not match geometry
   1410 	 shader */
   1411 
   1412 	gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_transform_feedback_object_0);
   1413 
   1414 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedback call failed.");
   1415 
   1416 	gl.useProgram(m_program_id_with_geometry_shader);
   1417 
   1418 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
   1419 
   1420 	gl.bindVertexArray(m_vertex_array_object);
   1421 
   1422 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   1423 
   1424 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_0);
   1425 
   1426 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   1427 
   1428 	gl.beginTransformFeedback(GL_POINTS);
   1429 
   1430 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
   1431 
   1432 	gl.drawArrays(GL_POINTS, 0, 1);
   1433 
   1434 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
   1435 
   1436 	gl.endTransformFeedback();
   1437 
   1438 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
   1439 
   1440 	gl.drawTransformFeedbackInstanced(GL_LINES, m_transform_feedback_object_0, 1);
   1441 
   1442 	if (GL_INVALID_OPERATION != gl.getError())
   1443 	{
   1444 		m_context.getTestContext().getLog()
   1445 			<< tcu::TestLog::Message << "INVALID_OPERATION was not generated by DrawTransformFeedbackInstanced and "
   1446 										"DrawTransformFeedbackStreamInstanced if <mode> did not match geometry shader."
   1447 			<< tcu::TestLog::EndMessage;
   1448 		return false;
   1449 	}
   1450 
   1451 	gl.drawTransformFeedbackStreamInstanced(GL_LINES, m_transform_feedback_object_0, 0, 1);
   1452 
   1453 	if (GL_INVALID_OPERATION != gl.getError())
   1454 	{
   1455 		m_context.getTestContext().getLog()
   1456 			<< tcu::TestLog::Message << "INVALID_OPERATION was not generated by DrawTransformFeedbackInstanced and "
   1457 										"DrawTransformFeedbackStreamInstanced if <mode> did not match geometry shader."
   1458 			<< tcu::TestLog::EndMessage;
   1459 		return false;
   1460 	}
   1461 
   1462 	/*  INVALID_OPERATION is generated by DrawTransformFeedbackInstanced and
   1463 	 DrawTransformFeedbackStreamInstanced if <mode> does not match tessellation */
   1464 
   1465 	gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_transform_feedback_object_0);
   1466 
   1467 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedback call failed.");
   1468 
   1469 	gl.useProgram(m_program_id_with_tessellation_shaders);
   1470 
   1471 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
   1472 
   1473 	gl.bindVertexArray(m_vertex_array_object);
   1474 
   1475 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   1476 
   1477 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_0);
   1478 
   1479 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   1480 
   1481 	gl.beginTransformFeedback(GL_LINES);
   1482 
   1483 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
   1484 
   1485 	gl.drawArrays(GL_PATCHES, 0, 2);
   1486 
   1487 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
   1488 
   1489 	gl.endTransformFeedback();
   1490 
   1491 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
   1492 
   1493 	gl.drawTransformFeedbackInstanced(GL_POINTS, m_transform_feedback_object_0, 1);
   1494 
   1495 	if (GL_INVALID_OPERATION != gl.getError())
   1496 	{
   1497 		m_context.getTestContext().getLog()
   1498 			<< tcu::TestLog::Message << "INVALID_OPERATION was not generated by DrawTransformFeedbackInstanced and "
   1499 										"DrawTransformFeedbackStreamInstanced if <mode> did not match geometry shader."
   1500 			<< tcu::TestLog::EndMessage;
   1501 		return false;
   1502 	}
   1503 
   1504 	gl.drawTransformFeedbackStreamInstanced(GL_POINTS, m_transform_feedback_object_0, 0, 1);
   1505 
   1506 	if (GL_INVALID_OPERATION != gl.getError())
   1507 	{
   1508 		m_context.getTestContext().getLog()
   1509 			<< tcu::TestLog::Message << "INVALID_OPERATION was not generated by DrawTransformFeedbackInstanced and "
   1510 										"DrawTransformFeedbackStreamInstanced if <mode> did not match geometry shader."
   1511 			<< tcu::TestLog::EndMessage;
   1512 		return false;
   1513 	}
   1514 
   1515 	/*  INVALID_VALUE is generated by DrawTransformFeedbackStreamInstanced if
   1516 	 <stream> is greater than or equal to MAX_VERTEX_STREAMS */
   1517 
   1518 	glw::GLint max_vertex_streams = 0;
   1519 
   1520 	gl.getIntegerv(GL_MAX_VERTEX_STREAMS, &max_vertex_streams);
   1521 
   1522 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   1523 
   1524 	if (max_vertex_streams == 0)
   1525 	{
   1526 		/* Failed to query GL_MAX_VERTEX_STREAMS. */
   1527 		throw 0;
   1528 	}
   1529 
   1530 	glw::GLint more_than_max_vertex_streams = max_vertex_streams + 1;
   1531 
   1532 	gl.drawTransformFeedbackStreamInstanced(GL_PATCHES, m_transform_feedback_object_0, more_than_max_vertex_streams, 1);
   1533 
   1534 	if (GL_INVALID_VALUE != gl.getError())
   1535 	{
   1536 		m_context.getTestContext().getLog()
   1537 			<< tcu::TestLog::Message << "INVALID_OPERATION was not generated by DrawTransformFeedbackInstanced and "
   1538 										"DrawTransformFeedbackStreamInstanced if <mode> did not match geometry shader."
   1539 			<< tcu::TestLog::EndMessage;
   1540 		return false;
   1541 	}
   1542 
   1543 	/*  INVALID_VALUE is generated by DrawTransformFeedbackInstanced and
   1544 	 DrawTransformFeedbackStreamInstanced if <id> is not name of transform
   1545 	 feedback object */
   1546 
   1547 	unsigned short int invalid_name = 1;
   1548 
   1549 	while (gl.isTransformFeedback(invalid_name))
   1550 	{
   1551 		++invalid_name;
   1552 
   1553 		/* Make sure that this loop ends someday, bad day. */
   1554 		if (invalid_name == USHRT_MAX)
   1555 		{
   1556 			m_context.getTestContext().getLog()
   1557 				<< tcu::TestLog::Message << "Cannot find unused trnasform feedback object." << tcu::TestLog::EndMessage;
   1558 			throw 0;
   1559 		}
   1560 	}
   1561 
   1562 	gl.drawTransformFeedbackInstanced(GL_PATCHES, (glw::GLuint)invalid_name, 1);
   1563 
   1564 	if (GL_INVALID_VALUE != gl.getError())
   1565 	{
   1566 		gl.endTransformFeedback();
   1567 
   1568 		return false;
   1569 	}
   1570 
   1571 	gl.drawTransformFeedbackStreamInstanced(GL_PATCHES, (glw::GLuint)invalid_name, 0, 1);
   1572 
   1573 	if (GL_INVALID_VALUE != gl.getError())
   1574 	{
   1575 		gl.endTransformFeedback();
   1576 
   1577 		return false;
   1578 	}
   1579 
   1580 	/*  INVALID_OPERATION is generated if by DrawTransformFeedbackStreamInstanced
   1581 	 if EndTransformFeedback was never called for the object named <id>.
   1582 	 return true */
   1583 
   1584 	gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_transform_feedback_object_1);
   1585 
   1586 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedback call failed.");
   1587 
   1588 	gl.drawTransformFeedbackStreamInstanced(GL_PATCHES, m_transform_feedback_object_1, 0, 1);
   1589 
   1590 	if (GL_INVALID_OPERATION != gl.getError())
   1591 	{
   1592 		m_context.getTestContext().getLog()
   1593 			<< tcu::TestLog::Message << "INVALID_OPERATION was not generated by DrawTransformFeedbackInstanced and "
   1594 										"DrawTransformFeedbackStreamInstanced if <mode> did not match geometry shader."
   1595 			<< tcu::TestLog::EndMessage;
   1596 
   1597 		return false;
   1598 	}
   1599 
   1600 	return true;
   1601 }
   1602 
   1603 const glw::GLchar* gl3cts::TransformFeedback::APIErrors::m_tessellation_control_shader =
   1604 	"#version 400\n"
   1605 	"\n"
   1606 	"layout (vertices = 2 ) out;\n"
   1607 	"\n"
   1608 	"void main()\n"
   1609 	"{\n"
   1610 	"    gl_TessLevelOuter[1]                = 3.0;\n"
   1611 	"    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
   1612 	"}\n";
   1613 
   1614 const glw::GLchar* gl3cts::TransformFeedback::APIErrors::m_tessellation_evaluation_shader =
   1615 	"#version 400\n"
   1616 	"\n"
   1617 	"layout(isolines, equal_spacing, ccw) in;\n"
   1618 	"\n"
   1619 	"out float result;\n"
   1620 	"\n"
   1621 	"void main()\n"
   1622 	"{\n"
   1623 	"    result      = 0.5;\n"
   1624 	"    gl_Position = gl_in[0].gl_Position + gl_in[1].gl_Position + gl_in[2].gl_Position;\n"
   1625 	"}\n";
   1626 
   1627 const glw::GLchar* gl3cts::TransformFeedback::APIErrors::m_geometry_shader =
   1628 	"#version 150\n"
   1629 	"\n"
   1630 	"layout(points) in;\n"
   1631 	"layout(points, max_vertices = 2) out;\n"
   1632 	"\n"
   1633 	"out float result;\n"
   1634 	"\n"
   1635 	"void main()\n"
   1636 	"{\n"
   1637 	"    gl_Position = gl_in[0].gl_Position + vec4(0.0, 0.0, 0.0, 0.0);\n"
   1638 	"    result = 0.0;\n"
   1639 	"    EmitVertex();\n"
   1640 	"\n"
   1641 	"    gl_Position = gl_in[0].gl_Position + vec4(1.0, 0.0, 0.0, 0.0);\n"
   1642 	"    result = 1.0;\n"
   1643 	"    EmitVertex();\n"
   1644 	"}\n";
   1645 
   1646 const glw::GLchar* gl3cts::TransformFeedback::APIErrors::s_vertex_shader_with_output =
   1647 	"#version 130\n"
   1648 	"\n"
   1649 	"out float result;\n"
   1650 	"\n"
   1651 	"void main()\n"
   1652 	"{\n"
   1653 	"    result      = float(gl_VertexID);\n"
   1654 	"    gl_Position = vec4(1.0);\n"
   1655 	"}\n";
   1656 
   1657 const glw::GLchar* gl3cts::TransformFeedback::APIErrors::s_vertex_shader_with_input_output =
   1658 	"#version 130\n"
   1659 	"\n"
   1660 	"in float v_input;\n"
   1661 	"\n"
   1662 	"out float result;\n"
   1663 	"\n"
   1664 	"void main()\n"
   1665 	"{\n"
   1666 	"    result      = float(gl_VertexID);\n"
   1667 	"    gl_Position = vec4(v_input);\n"
   1668 	"}\n";
   1669 
   1670 const glw::GLchar* gl3cts::TransformFeedback::APIErrors::s_vertex_shader_without_output =
   1671 	"#version 130\n"
   1672 	"\n"
   1673 	"void main()\n"
   1674 	"{\n"
   1675 	"    gl_Position = vec4(1.0);\n"
   1676 	"}\n";
   1677 
   1678 const glw::GLchar* gl3cts::TransformFeedback::APIErrors::s_fragment_shader = "#version 130\n"
   1679 																			 "\n"
   1680 																			 "out vec4 color;\n"
   1681 																			 "\n"
   1682 																			 "void main()\n"
   1683 																			 "{\n"
   1684 																			 "    color = vec4(1.0);\n"
   1685 																			 "}\n";
   1686 
   1687 const glw::GLchar* gl3cts::TransformFeedback::APIErrors::m_varying_name = "result";
   1688 
   1689 const glw::GLfloat gl3cts::TransformFeedback::APIErrors::m_buffer_1_data[] = { 3.14159265359f, 2.7182818f };
   1690 
   1691 const glw::GLsizei gl3cts::TransformFeedback::APIErrors::m_buffer_1_size =
   1692 	sizeof(gl3cts::TransformFeedback::APIErrors::m_buffer_1_data);
   1693 
   1694 /*-----------------------------------------------------------------------------------------------*/
   1695 
   1696 gl3cts::TransformFeedback::LinkingErrors::LinkingErrors(deqp::Context& context)
   1697 	: deqp::TestCase(context, "linking_errors_test", "Transform Feedback Linking Errors Test"), m_context(context)
   1698 {
   1699 	/* Left intentionally blank. */
   1700 }
   1701 
   1702 gl3cts::TransformFeedback::LinkingErrors::~LinkingErrors(void)
   1703 {
   1704 }
   1705 
   1706 tcu::TestNode::IterateResult gl3cts::TransformFeedback::LinkingErrors::iterate(void)
   1707 {
   1708 	bool is_ok		= true;
   1709 	bool test_error = false;
   1710 
   1711 	try
   1712 	{
   1713 		is_ok = is_ok && testNoVertexNoGeometry();
   1714 		is_ok = is_ok && testInvalidVarying();
   1715 		is_ok = is_ok && testRepeatedVarying();
   1716 		is_ok = is_ok && testTooManyVaryings();
   1717 	}
   1718 	catch (...)
   1719 	{
   1720 		is_ok	  = false;
   1721 		test_error = true;
   1722 	}
   1723 
   1724 	/* Result's setup. */
   1725 	if (is_ok)
   1726 	{
   1727 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   1728 	}
   1729 	else
   1730 	{
   1731 		if (test_error)
   1732 		{
   1733 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   1734 		}
   1735 		else
   1736 		{
   1737 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   1738 		}
   1739 	}
   1740 
   1741 	return STOP;
   1742 }
   1743 
   1744 bool gl3cts::TransformFeedback::LinkingErrors::testNoVertexNoGeometry(void)
   1745 {
   1746 	/* Functions handler */
   1747 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1748 
   1749 	/*  Check if link process fails under the following conditions:
   1750 	 <count> specified by TransformFeedbackVaryings is non-zero and program has
   1751 	 neither vertex nor geometry shader; */
   1752 
   1753 	glw::GLint linking_status = 1;
   1754 
   1755 	glw::GLuint program = gl3cts::TransformFeedback::Utilities::buildProgram(
   1756 		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, NULL, s_fragment_shader,
   1757 		&s_valid_transform_feedback_varying, 1, GL_INTERLEAVED_ATTRIBS, false, &linking_status);
   1758 
   1759 	if ((GL_FALSE != linking_status) || program)
   1760 	{
   1761 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1762 											<< "Linking unexpectedly succeded when Transform Feedback varying was "
   1763 											   "specified but program had neither vertex nor geometry shader stages."
   1764 											<< tcu::TestLog::EndMessage;
   1765 
   1766 		if (program)
   1767 		{
   1768 			gl.deleteProgram(program);
   1769 		}
   1770 
   1771 		return false;
   1772 	}
   1773 
   1774 	/* Log success. */
   1775 	m_context.getTestContext().getLog() << tcu::TestLog::Message
   1776 										<< "Linking failed as expected when Transform Feedback varying was specified "
   1777 										   "but program had neither vertex nor geometry shader stages."
   1778 										<< tcu::TestLog::EndMessage;
   1779 
   1780 	return true;
   1781 }
   1782 
   1783 bool gl3cts::TransformFeedback::LinkingErrors::testInvalidVarying(void)
   1784 {
   1785 	/* Functions handler */
   1786 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1787 
   1788 	/*  Check if link process fails under the following conditions:
   1789 	 <varyings> specified by TransformFeedbackVaryings contains name of
   1790 	 variable that is not available for capture; */
   1791 
   1792 	std::string vertex_shader(s_vertex_shader_template);
   1793 
   1794 	vertex_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(
   1795 		vertex_shader, "TEMPLATE_INPUT_OUTPUT_DECLARATIONS", "in float data;\n");
   1796 	vertex_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(vertex_shader, "TEMPLATE_OUTPUT_SETTERS", "");
   1797 
   1798 	glw::GLint linking_status = 1;
   1799 
   1800 	glw::GLuint program = gl3cts::TransformFeedback::Utilities::buildProgram(
   1801 		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, vertex_shader.c_str(), s_fragment_shader,
   1802 		&s_invalid_transform_feedback_varying, 1, GL_INTERLEAVED_ATTRIBS, false, &linking_status);
   1803 
   1804 	if ((GL_FALSE != linking_status) || program)
   1805 	{
   1806 		m_context.getTestContext().getLog()
   1807 			<< tcu::TestLog::Message
   1808 			<< "Linking unexpectedly succeded when Transform Feedback varying was specified with name of variable ("
   1809 			<< s_invalid_transform_feedback_varying << ") that is not available for capture."
   1810 			<< tcu::TestLog::EndMessage;
   1811 
   1812 		if (program)
   1813 		{
   1814 			gl.deleteProgram(program);
   1815 		}
   1816 
   1817 		return false;
   1818 	}
   1819 
   1820 	/* Log success. */
   1821 	m_context.getTestContext().getLog()
   1822 		<< tcu::TestLog::Message
   1823 		<< "Linking failed as expected when Transform Feedback varying was specified with name of variable ("
   1824 		<< s_invalid_transform_feedback_varying << ") that is not available for capture." << tcu::TestLog::EndMessage;
   1825 
   1826 	return true;
   1827 }
   1828 
   1829 bool gl3cts::TransformFeedback::LinkingErrors::testRepeatedVarying(void)
   1830 {
   1831 	/* Functions handler */
   1832 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1833 
   1834 	/*  Check if link process fails under the following conditions:
   1835 	 <varyings> specified by TransformFeedbackVaryings contains name of
   1836 	 variable more than once; */
   1837 
   1838 	std::string vertex_shader(s_vertex_shader_template);
   1839 
   1840 	vertex_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(
   1841 		vertex_shader, "TEMPLATE_INPUT_OUTPUT_DECLARATIONS", "out float result;\n");
   1842 	vertex_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(vertex_shader, "TEMPLATE_OUTPUT_SETTERS",
   1843 																		 "    result = 0.577215664901532;\n");
   1844 
   1845 	glw::GLint linking_status = 1;
   1846 
   1847 	glw::GLuint program = gl3cts::TransformFeedback::Utilities::buildProgram(
   1848 		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, vertex_shader.c_str(), s_fragment_shader,
   1849 		s_repeated_transform_feedback_varying, s_repeated_transform_feedback_varying_count, GL_INTERLEAVED_ATTRIBS,
   1850 		false, &linking_status);
   1851 
   1852 	if ((GL_FALSE != linking_status) || program)
   1853 	{
   1854 		m_context.getTestContext().getLog()
   1855 			<< tcu::TestLog::Message
   1856 			<< "Linking unexpectedly succeded when Transform Feedback varying was specified twice."
   1857 			<< tcu::TestLog::EndMessage;
   1858 
   1859 		if (program)
   1860 		{
   1861 			gl.deleteProgram(program);
   1862 		}
   1863 
   1864 		return false;
   1865 	}
   1866 
   1867 	/* Log success. */
   1868 	m_context.getTestContext().getLog()
   1869 		<< tcu::TestLog::Message << "Linking failed as expected when Transform Feedback varying was specified twice."
   1870 		<< tcu::TestLog::EndMessage;
   1871 
   1872 	return true;
   1873 }
   1874 
   1875 bool gl3cts::TransformFeedback::LinkingErrors::testTooManyVaryings(void)
   1876 {
   1877 	/* Functions handler */
   1878 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1879 
   1880 	/*  Check if link process fails under the following conditions:
   1881 	 number of components specified to capture exceeds limits
   1882 	 MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS or
   1883 	 MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS. */
   1884 
   1885 	/* Fetching limits. */
   1886 	glw::GLint max_transform_feedback_separate_components	= 0;
   1887 	glw::GLint max_transform_feedback_interleaved_components = 0;
   1888 
   1889 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_transform_feedback_separate_components);
   1890 
   1891 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   1892 
   1893 	if (max_transform_feedback_separate_components == 0)
   1894 	{
   1895 		throw 0;
   1896 	}
   1897 
   1898 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components);
   1899 
   1900 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   1901 
   1902 	if (max_transform_feedback_interleaved_components == 0)
   1903 	{
   1904 		throw 0;
   1905 	}
   1906 
   1907 	glw::GLint more_than_max_transform_feedback_components =
   1908 		deMax32(max_transform_feedback_separate_components, max_transform_feedback_interleaved_components) + 1;
   1909 
   1910 	/* Preparing source code. */
   1911 	std::string						vertex_shader(s_vertex_shader_template);
   1912 	std::string						transform_feedback_variable_declarations("");
   1913 	std::string						transform_feedback_variable_setters("");
   1914 	std::vector<std::string>		transform_feedback_varyings(more_than_max_transform_feedback_components);
   1915 	std::vector<const glw::GLchar*> transform_feedback_varyings_c(more_than_max_transform_feedback_components);
   1916 
   1917 	for (glw::GLint i = 0; i < more_than_max_transform_feedback_components; ++i)
   1918 	{
   1919 		std::string varying = "result_";
   1920 		varying.append(gl3cts::TransformFeedback::Utilities::itoa(i));
   1921 
   1922 		transform_feedback_varyings[i] = varying;
   1923 
   1924 		transform_feedback_varyings_c[i] = transform_feedback_varyings[i].c_str();
   1925 
   1926 		transform_feedback_variable_declarations.append("out float ");
   1927 		transform_feedback_variable_declarations.append(varying);
   1928 		transform_feedback_variable_declarations.append(";\n");
   1929 
   1930 		transform_feedback_variable_setters.append("    ");
   1931 		transform_feedback_variable_setters.append(varying);
   1932 		transform_feedback_variable_setters.append(" = ");
   1933 		transform_feedback_variable_setters.append(gl3cts::TransformFeedback::Utilities::itoa(i * i));
   1934 		transform_feedback_variable_setters.append(".0;\n");
   1935 	}
   1936 
   1937 	vertex_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(
   1938 		vertex_shader, "TEMPLATE_INPUT_OUTPUT_DECLARATIONS", transform_feedback_variable_declarations);
   1939 	vertex_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(vertex_shader, "TEMPLATE_OUTPUT_SETTERS",
   1940 																		 transform_feedback_variable_setters);
   1941 
   1942 	glw::GLuint program = gl3cts::TransformFeedback::Utilities::buildProgram(
   1943 		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, vertex_shader.c_str(), s_fragment_shader,
   1944 		&transform_feedback_varyings_c[0], more_than_max_transform_feedback_components, GL_INTERLEAVED_ATTRIBS);
   1945 
   1946 	/* Note: we check for program as not only linking shall fail, but also glTransformFeedbackVaryings shall return an error. */
   1947 
   1948 	if (program)
   1949 	{
   1950 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1951 											<< "Linking unexpectedly succeded when too many Transform Feedback varying "
   1952 											   "were specified in INTERLEAVED mode."
   1953 											<< tcu::TestLog::EndMessage;
   1954 
   1955 		if (program)
   1956 		{
   1957 			gl.deleteProgram(program);
   1958 		}
   1959 
   1960 		return false;
   1961 	}
   1962 
   1963 	program = gl3cts::TransformFeedback::Utilities::buildProgram(
   1964 		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, vertex_shader.c_str(), s_fragment_shader,
   1965 		&transform_feedback_varyings_c[0], more_than_max_transform_feedback_components, GL_SEPARATE_ATTRIBS);
   1966 
   1967 	if (program)
   1968 	{
   1969 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1970 											<< "Linking unexpectedly succeded when too many Transform Feedback "
   1971 											   "varyings were specified in SEPARATE mode."
   1972 											<< tcu::TestLog::EndMessage;
   1973 
   1974 		if (program)
   1975 		{
   1976 			gl.deleteProgram(program);
   1977 		}
   1978 
   1979 		return false;
   1980 	}
   1981 
   1982 	/* Log success. */
   1983 	m_context.getTestContext().getLog()
   1984 		<< tcu::TestLog::Message
   1985 		<< "Linking failed as expected when too many Transform Feedback varyings were specified."
   1986 		<< tcu::TestLog::EndMessage;
   1987 
   1988 	return true;
   1989 }
   1990 
   1991 const glw::GLchar* gl3cts::TransformFeedback::LinkingErrors::s_fragment_shader = "#version 130\n"
   1992 																				 "\n"
   1993 																				 "out vec4 color;\n"
   1994 																				 "\n"
   1995 																				 "void main()\n"
   1996 																				 "{\n"
   1997 																				 "    color = vec4(1.0);\n"
   1998 																				 "}\n";
   1999 
   2000 const glw::GLchar* gl3cts::TransformFeedback::LinkingErrors::s_vertex_shader_template =
   2001 	"#version 130\n"
   2002 	"\n"
   2003 	"TEMPLATE_INPUT_OUTPUT_DECLARATIONS"
   2004 	"\n"
   2005 	"void main()\n"
   2006 	"{\n"
   2007 	"TEMPLATE_OUTPUT_SETTERS"
   2008 	"\n"
   2009 	"    gl_Position = vec4(1.618033988749);\n"
   2010 	"}\n";
   2011 
   2012 const glw::GLchar* gl3cts::TransformFeedback::LinkingErrors::s_valid_transform_feedback_varying = "result";
   2013 
   2014 const glw::GLchar* gl3cts::TransformFeedback::LinkingErrors::s_invalid_transform_feedback_varying = "data";
   2015 
   2016 const glw::GLchar* gl3cts::TransformFeedback::LinkingErrors::s_repeated_transform_feedback_varying[] = { "result",
   2017 																										 "result" };
   2018 
   2019 const glw::GLsizei gl3cts::TransformFeedback::LinkingErrors::s_repeated_transform_feedback_varying_count =
   2020 	sizeof(s_repeated_transform_feedback_varying) / sizeof(s_repeated_transform_feedback_varying[0]);
   2021 
   2022 /*-----------------------------------------------------------------------------------------------*/
   2023 
   2024 const glw::GLint gl3cts::TransformFeedback::Limits::s_min_value_of_max_transform_feedback_interleaved_components = 64;
   2025 const glw::GLint gl3cts::TransformFeedback::Limits::s_min_value_of_max_transform_feedback_separate_attribs		 = 4;
   2026 const glw::GLint gl3cts::TransformFeedback::Limits::s_min_value_of_max_transform_feedback_separate_components	= 4;
   2027 const glw::GLint gl3cts::TransformFeedback::Limits::s_min_value_of_max_transform_feedback_buffers				 = 4;
   2028 const glw::GLint gl3cts::TransformFeedback::Limits::s_min_value_of_max_vertex_streams							 = 1;
   2029 
   2030 gl3cts::TransformFeedback::Limits::Limits(deqp::Context& context)
   2031 	: deqp::TestCase(context, "limits_test", "Transform Feedback Limits Test"), m_context(context)
   2032 {
   2033 }
   2034 
   2035 gl3cts::TransformFeedback::Limits::~Limits(void)
   2036 {
   2037 }
   2038 
   2039 tcu::TestNode::IterateResult gl3cts::TransformFeedback::Limits::iterate(void)
   2040 {
   2041 	/* Initializations. */
   2042 	bool is_at_least_gl_30 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(3, 0)));
   2043 	bool is_at_least_gl_40 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 0)));
   2044 
   2045 	bool is_ext_tf_1 = m_context.getContextInfo().isExtensionSupported("GL_EXT_transform_feedback");
   2046 	bool is_arb_tf_3 = m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback3");
   2047 
   2048 	bool is_ok		= true;
   2049 	bool test_error = false;
   2050 
   2051 	/* Tests. */
   2052 	try
   2053 	{
   2054 		if (is_at_least_gl_30 || is_ext_tf_1)
   2055 		{
   2056 			is_ok = is_ok && test_max_transform_feedback_interleaved_components();
   2057 			is_ok = is_ok && test_max_transform_feedback_separate_attribs();
   2058 			is_ok = is_ok && test_max_transform_feedback_separate_components();
   2059 		}
   2060 
   2061 		if (is_at_least_gl_40 || is_arb_tf_3)
   2062 		{
   2063 			is_ok = is_ok && test_max_transform_feedback_buffers();
   2064 			is_ok = is_ok && test_max_vertex_streams();
   2065 		}
   2066 	}
   2067 	catch (...)
   2068 	{
   2069 		is_ok	  = false;
   2070 		test_error = true;
   2071 	}
   2072 
   2073 	/* Result's setup. */
   2074 	if (is_ok)
   2075 	{
   2076 		/* Log success. */
   2077 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Limits are in range of specification."
   2078 											<< tcu::TestLog::EndMessage;
   2079 
   2080 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   2081 	}
   2082 	else
   2083 	{
   2084 		if (test_error)
   2085 		{
   2086 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   2087 		}
   2088 		else
   2089 		{
   2090 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   2091 		}
   2092 	}
   2093 
   2094 	return STOP;
   2095 }
   2096 
   2097 bool gl3cts::TransformFeedback::Limits::test_max_transform_feedback_interleaved_components(void)
   2098 {
   2099 	/* Functions handler */
   2100 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2101 
   2102 	/* Check that MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS is at least 64. */
   2103 	glw::GLint max_transform_feedback_interleaved_components = 0;
   2104 
   2105 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components);
   2106 
   2107 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   2108 
   2109 	if (max_transform_feedback_interleaved_components < s_min_value_of_max_transform_feedback_interleaved_components)
   2110 	{
   2111 		m_context.getTestContext().getLog()
   2112 			<< tcu::TestLog::Message << "GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS is equal to "
   2113 			<< max_transform_feedback_interleaved_components << " which is less than expected "
   2114 			<< s_min_value_of_max_transform_feedback_interleaved_components << "." << tcu::TestLog::EndMessage;
   2115 		return false;
   2116 	}
   2117 
   2118 	return true;
   2119 }
   2120 
   2121 bool gl3cts::TransformFeedback::Limits::test_max_transform_feedback_separate_attribs(void)
   2122 {
   2123 	/* Functions handler */
   2124 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2125 
   2126 	/* Check that MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS is at least 4. */
   2127 	glw::GLint max_transform_feedback_separate_attribs = 0;
   2128 
   2129 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &max_transform_feedback_separate_attribs);
   2130 
   2131 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   2132 
   2133 	if (max_transform_feedback_separate_attribs < s_min_value_of_max_transform_feedback_separate_attribs)
   2134 	{
   2135 		m_context.getTestContext().getLog()
   2136 			<< tcu::TestLog::Message << "GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS is equal to "
   2137 			<< max_transform_feedback_separate_attribs << " which is less than expected "
   2138 			<< s_min_value_of_max_transform_feedback_separate_attribs << "." << tcu::TestLog::EndMessage;
   2139 		return false;
   2140 	}
   2141 
   2142 	return true;
   2143 }
   2144 
   2145 bool gl3cts::TransformFeedback::Limits::test_max_transform_feedback_separate_components(void)
   2146 {
   2147 	/* Functions handler */
   2148 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2149 
   2150 	/* Check that MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS is at least 4. */
   2151 	glw::GLint max_transform_feedback_separate_components = 0;
   2152 
   2153 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_transform_feedback_separate_components);
   2154 
   2155 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   2156 
   2157 	if (max_transform_feedback_separate_components < s_min_value_of_max_transform_feedback_separate_components)
   2158 	{
   2159 		m_context.getTestContext().getLog()
   2160 			<< tcu::TestLog::Message << "GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS is equal to "
   2161 			<< max_transform_feedback_separate_components << " which is less than expected "
   2162 			<< s_min_value_of_max_transform_feedback_separate_components << "." << tcu::TestLog::EndMessage;
   2163 		return false;
   2164 	}
   2165 
   2166 	return true;
   2167 }
   2168 
   2169 bool gl3cts::TransformFeedback::Limits::test_max_transform_feedback_buffers(void)
   2170 {
   2171 	/* Functions handler */
   2172 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2173 
   2174 	/* Check that MAX_TRANSFORM_FEEDBACK_BUFFERS is at least 4. */
   2175 	glw::GLint max_transform_feedback_buffers = 0;
   2176 
   2177 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers);
   2178 
   2179 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   2180 
   2181 	if (max_transform_feedback_buffers < s_min_value_of_max_transform_feedback_buffers)
   2182 	{
   2183 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "MAX_TRANSFORM_FEEDBACK_BUFFERS is equal to "
   2184 											<< max_transform_feedback_buffers << " which is less than expected "
   2185 											<< s_min_value_of_max_transform_feedback_buffers << "."
   2186 											<< tcu::TestLog::EndMessage;
   2187 		return false;
   2188 	}
   2189 
   2190 	return true;
   2191 }
   2192 
   2193 bool gl3cts::TransformFeedback::Limits::test_max_vertex_streams(void)
   2194 {
   2195 	/* Functions handler */
   2196 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2197 
   2198 	/* Check that MAX_VERTEX_STREAMS is at least 1. */
   2199 	glw::GLint max_vertex_streams = 0;
   2200 
   2201 	gl.getIntegerv(GL_MAX_VERTEX_STREAMS, &max_vertex_streams);
   2202 
   2203 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   2204 
   2205 	if (max_vertex_streams < s_min_value_of_max_vertex_streams)
   2206 	{
   2207 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "MAX_VERTEX_STREAMS is equal to "
   2208 											<< max_vertex_streams << " which is less than expected "
   2209 											<< s_min_value_of_max_vertex_streams << "." << tcu::TestLog::EndMessage;
   2210 		return false;
   2211 	}
   2212 
   2213 	return true;
   2214 }
   2215 
   2216 /*-----------------------------------------------------------------------------------------------*/
   2217 
   2218 gl3cts::TransformFeedback::CaptureVertexInterleaved::CaptureVertexInterleaved(deqp::Context& context,
   2219 																			  const char*	test_name,
   2220 																			  const char*	test_description)
   2221 	: deqp::TestCase(context, test_name, test_description)
   2222 	, m_context(context)
   2223 	, m_program(0)
   2224 	, m_framebuffer(0)
   2225 	, m_renderbuffer(0)
   2226 	, m_buffer(0)
   2227 	, m_buffer_size(0)
   2228 	, m_vertex_array_object(0)
   2229 	, m_max_transform_feedback_components(0)
   2230 	, m_attrib_type(GL_INTERLEAVED_ATTRIBS)
   2231 	, m_max_vertices_drawn(8)
   2232 	, m_glBindBufferOffsetEXT(DE_NULL)
   2233 {
   2234 }
   2235 
   2236 gl3cts::TransformFeedback::CaptureVertexInterleaved::~CaptureVertexInterleaved(void)
   2237 {
   2238 }
   2239 
   2240 tcu::TestNode::IterateResult gl3cts::TransformFeedback::CaptureVertexInterleaved::iterate(void)
   2241 {
   2242 	/* Functions handler */
   2243 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2244 
   2245 	/* Initializations. */
   2246 	bool is_at_least_gl_30 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(3, 0)));
   2247 	bool is_ext_tf_1	   = m_context.getContextInfo().isExtensionSupported("GL_EXT_transform_feedback");
   2248 
   2249 	bool is_ok		= true;
   2250 	bool test_error = false;
   2251 
   2252 	try
   2253 	{
   2254 		if (is_ext_tf_1)
   2255 		{
   2256 			/* Extension query. */
   2257 			m_glBindBufferOffsetEXT =
   2258 				(BindBufferOffsetEXT_ProcAddress)m_context.getRenderContext().getProcAddress("glBindBufferOffsetEXT");
   2259 
   2260 			if (DE_NULL == m_glBindBufferOffsetEXT)
   2261 			{
   2262 				throw 0;
   2263 			}
   2264 		}
   2265 
   2266 		if (is_at_least_gl_30 || is_ext_tf_1)
   2267 		{
   2268 			fetchLimits();
   2269 			buildProgram();
   2270 			createFramebuffer();
   2271 			createTransformFeedbackBuffer();
   2272 			createVertexArrayObject();
   2273 
   2274 			gl.useProgram(m_program);
   2275 
   2276 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
   2277 
   2278 			for (glw::GLint i_bind_case = 0; (i_bind_case < BIND_BUFFER_CASES_COUNT) && is_ok; ++i_bind_case)
   2279 			{
   2280 				if ((i_bind_case == BIND_BUFFER_OFFSET_CASE) && (DE_NULL == m_glBindBufferOffsetEXT))
   2281 				{
   2282 					continue;
   2283 				}
   2284 
   2285 				bindBuffer((BindBufferCase)i_bind_case);
   2286 
   2287 				for (glw::GLuint i_primitive_case = 0; (i_primitive_case < s_primitive_cases_count) && is_ok;
   2288 					 ++i_primitive_case)
   2289 				{
   2290 					draw(i_primitive_case);
   2291 
   2292 					is_ok = is_ok && checkFramebuffer(s_primitive_cases[i_primitive_case]);
   2293 					is_ok = is_ok && checkTransformFeedbackBuffer((BindBufferCase)i_bind_case,
   2294 																  s_primitive_cases[i_primitive_case]);
   2295 				}
   2296 			}
   2297 		}
   2298 	}
   2299 	catch (...)
   2300 	{
   2301 		is_ok	  = false;
   2302 		test_error = true;
   2303 	}
   2304 
   2305 	/* Clean objects. */
   2306 	clean();
   2307 
   2308 	/* Result's setup. */
   2309 	if (is_ok)
   2310 	{
   2311 		/* Log success. */
   2312 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Capture Vertex have passed."
   2313 											<< tcu::TestLog::EndMessage;
   2314 
   2315 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   2316 	}
   2317 	else
   2318 	{
   2319 		if (test_error)
   2320 		{
   2321 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   2322 		}
   2323 		else
   2324 		{
   2325 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   2326 		}
   2327 	}
   2328 
   2329 	return STOP;
   2330 }
   2331 
   2332 void gl3cts::TransformFeedback::CaptureVertexInterleaved::fetchLimits(void)
   2333 {
   2334 	/* Functions handler */
   2335 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2336 
   2337 	/* Fetching limits. */
   2338 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &m_max_transform_feedback_components);
   2339 
   2340 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   2341 
   2342 	if (m_max_transform_feedback_components == 0)
   2343 	{
   2344 		throw 0;
   2345 	}
   2346 
   2347 	glw::GLint max_varyings_components = 0;
   2348 
   2349 	gl.getIntegerv(GL_MAX_VARYING_COMPONENTS, &max_varyings_components);
   2350 
   2351 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   2352 
   2353 	if (max_varyings_components == 0)
   2354 	{
   2355 		throw 0;
   2356 	}
   2357 
   2358 	if (m_max_transform_feedback_components > max_varyings_components)
   2359 	{
   2360 		m_max_transform_feedback_components = max_varyings_components;
   2361 	}
   2362 }
   2363 
   2364 void gl3cts::TransformFeedback::CaptureVertexInterleaved::buildProgram(void)
   2365 {
   2366 	/* Functions handler */
   2367 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2368 
   2369 	/* Preparing source code. */
   2370 	std::string vertex_shader(s_vertex_shader_source_code_template); /* Storage for vertex shader source code. */
   2371 	std::string transform_feedback_variable_declarations(
   2372 		""); /* String to contain all custom outputs from vertex shader. */
   2373 	std::string transform_feedback_variable_setters(
   2374 		""); /* String containing all initializations of custom outputs from vertex shader. */
   2375 	std::vector<std::string> transform_feedback_varyings(m_max_transform_feedback_components); /* Varyings array. */
   2376 	std::vector<const glw::GLchar*> transform_feedback_varyings_c(
   2377 		m_max_transform_feedback_components); /* Varyings array in C form to pass to the GL. */
   2378 
   2379 	glw::GLint user_defined_transform_feedback_interleaved_varyings_count =
   2380 		m_max_transform_feedback_components /* total max to be written by the shader */
   2381 			/ 4								/* components per vec4 */
   2382 		- 1 /* gl_Position */;
   2383 
   2384 	glw::GLint all_transform_feedback_interleaved_varyings_count =
   2385 		user_defined_transform_feedback_interleaved_varyings_count + 1 /* gl_Position */;
   2386 
   2387 	/* Most of varyings is declarated output variables. */
   2388 	for (glw::GLint i = 0; i < user_defined_transform_feedback_interleaved_varyings_count; ++i)
   2389 	{
   2390 		std::string varying = "result_";
   2391 		varying.append(gl3cts::TransformFeedback::Utilities::itoa(i));
   2392 
   2393 		transform_feedback_varyings[i] = varying;
   2394 
   2395 		transform_feedback_varyings_c[i] = transform_feedback_varyings[i].c_str();
   2396 
   2397 		transform_feedback_variable_declarations.append("out vec4 ");
   2398 		transform_feedback_variable_declarations.append(varying);
   2399 		transform_feedback_variable_declarations.append(";\n");
   2400 
   2401 		transform_feedback_variable_setters.append("    ");
   2402 		transform_feedback_variable_setters.append(varying);
   2403 		transform_feedback_variable_setters.append(" = vec4(");
   2404 		transform_feedback_variable_setters.append(gl3cts::TransformFeedback::Utilities::itoa(i * 4));
   2405 		transform_feedback_variable_setters.append(".0, ");
   2406 		transform_feedback_variable_setters.append(gl3cts::TransformFeedback::Utilities::itoa(i * 4 + 1));
   2407 		transform_feedback_variable_setters.append(".0, ");
   2408 		transform_feedback_variable_setters.append(gl3cts::TransformFeedback::Utilities::itoa(i * 4 + 2));
   2409 		transform_feedback_variable_setters.append(".0, ");
   2410 		transform_feedback_variable_setters.append(gl3cts::TransformFeedback::Utilities::itoa(i * 4 + 3));
   2411 		transform_feedback_variable_setters.append(".0);\n");
   2412 	}
   2413 
   2414 	/* Last four varying components are gl_Position components. */
   2415 	transform_feedback_varyings[user_defined_transform_feedback_interleaved_varyings_count] = "gl_Position";
   2416 
   2417 	transform_feedback_varyings_c[user_defined_transform_feedback_interleaved_varyings_count] =
   2418 		transform_feedback_varyings[user_defined_transform_feedback_interleaved_varyings_count].c_str();
   2419 
   2420 	/* Preprocess vertex shader source code template. */
   2421 	vertex_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(
   2422 		vertex_shader, "TEMPLATE_INPUT_OUTPUT_DECLARATIONS", transform_feedback_variable_declarations);
   2423 	vertex_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(vertex_shader, "TEMPLATE_OUTPUT_SETTERS",
   2424 																		 transform_feedback_variable_setters);
   2425 	vertex_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(
   2426 		vertex_shader, "TEMPLATE_RASTERIZATION_EPSILON",
   2427 		gl3cts::TransformFeedback::Utilities::ftoa(s_rasterization_epsilon));
   2428 
   2429 	/* Compile, link and check. */
   2430 	m_program = gl3cts::TransformFeedback::Utilities::buildProgram(
   2431 		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, vertex_shader.c_str(), s_fragment_shader_source_code,
   2432 		&transform_feedback_varyings_c[0], all_transform_feedback_interleaved_varyings_count, m_attrib_type);
   2433 
   2434 	if (0 == m_program)
   2435 	{
   2436 		throw 0;
   2437 	}
   2438 }
   2439 
   2440 void gl3cts::TransformFeedback::CaptureVertexInterleaved::createFramebuffer(void)
   2441 {
   2442 	/* Functions handler */
   2443 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2444 
   2445 	/* Setting clear color */
   2446 	gl.clearColor(0.f, 0.f, 0.f, 1.f);
   2447 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");
   2448 
   2449 	/* Creating framebuffer */
   2450 	gl.genFramebuffers(1, &m_framebuffer);
   2451 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
   2452 
   2453 	gl.genRenderbuffers(1, &m_renderbuffer);
   2454 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
   2455 
   2456 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
   2457 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
   2458 
   2459 	gl.bindRenderbuffer(GL_RENDERBUFFER, m_renderbuffer);
   2460 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
   2461 
   2462 	gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32F, s_framebuffer_size, s_framebuffer_size);
   2463 	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed.");
   2464 
   2465 	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_renderbuffer);
   2466 	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed.");
   2467 
   2468 	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
   2469 	{
   2470 		throw 0;
   2471 	}
   2472 
   2473 	gl.viewport(0, 0, s_framebuffer_size, s_framebuffer_size);
   2474 	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
   2475 }
   2476 
   2477 void gl3cts::TransformFeedback::CaptureVertexInterleaved::createTransformFeedbackBuffer(void)
   2478 {
   2479 	/* Functions handler */
   2480 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2481 
   2482 	/* Creating xfb buffer */
   2483 	gl.genBuffers(1, &m_buffer);
   2484 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   2485 
   2486 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_buffer);
   2487 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   2488 
   2489 	m_buffer_size =
   2490 		static_cast<glw::GLuint>(m_max_transform_feedback_components * m_max_vertices_drawn * sizeof(glw::GLfloat));
   2491 
   2492 	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, m_buffer_size, NULL, GL_DYNAMIC_READ);
   2493 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
   2494 }
   2495 
   2496 void gl3cts::TransformFeedback::CaptureVertexInterleaved::createVertexArrayObject(void)
   2497 {
   2498 	/* Functions handler */
   2499 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2500 
   2501 	/* VAO Creations */
   2502 	gl.genVertexArrays(1, &m_vertex_array_object);
   2503 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
   2504 
   2505 	gl.bindVertexArray(m_vertex_array_object);
   2506 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   2507 }
   2508 
   2509 void gl3cts::TransformFeedback::CaptureVertexInterleaved::draw(glw::GLuint primitive_case)
   2510 {
   2511 	/* Functions handler */
   2512 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2513 
   2514 	/* Draw */
   2515 	gl.clear(GL_COLOR_BUFFER_BIT);
   2516 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed.");
   2517 
   2518 	gl.beginTransformFeedback(s_primitive_cases_xfb[primitive_case]);
   2519 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedbac call failed.");
   2520 
   2521 	gl.drawElements(s_primitive_cases[primitive_case], s_element_indices_counts[primitive_case], GL_UNSIGNED_INT,
   2522 					s_element_indices[primitive_case]);
   2523 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawElements call failed.");
   2524 
   2525 	gl.endTransformFeedback();
   2526 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedbac call failed.");
   2527 }
   2528 
   2529 bool gl3cts::TransformFeedback::CaptureVertexInterleaved::checkFramebuffer(glw::GLenum primitive_type UNUSED)
   2530 {
   2531 	/* Functions handler */
   2532 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2533 
   2534 	/* Fetch framebuffer. */
   2535 	std::vector<glw::GLfloat> pixels(s_framebuffer_size * s_framebuffer_size);
   2536 
   2537 	if ((s_framebuffer_size > 0) && (s_framebuffer_size > 0))
   2538 	{
   2539 		gl.readPixels(0, 0, s_framebuffer_size, s_framebuffer_size, GL_RED, GL_FLOAT, pixels.data());
   2540 		GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");
   2541 	}
   2542 
   2543 	/* Check results.
   2544 	 Note: assuming that s_buffer_size == 2 -> then all points shall be drawn. */
   2545 	for (std::vector<glw::GLfloat>::iterator i = pixels.begin(); i != pixels.end(); ++i)
   2546 	{
   2547 		if (fabs(*i - 0.5f) > 0.0625f /* precision */)
   2548 		{
   2549 			return false;
   2550 		}
   2551 	}
   2552 
   2553 	return true;
   2554 }
   2555 
   2556 bool gl3cts::TransformFeedback::CaptureVertexInterleaved::checkTransformFeedbackBuffer(BindBufferCase bind_case UNUSED,
   2557 																					   glw::GLenum primitive_type)
   2558 {
   2559 	/* Functions handler */
   2560 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2561 
   2562 	/* Check */
   2563 	glw::GLuint number_of_vertices = 0;
   2564 
   2565 	switch (primitive_type)
   2566 	{
   2567 	case GL_POINTS:
   2568 		number_of_vertices = 4;
   2569 		break;
   2570 	case GL_LINES:
   2571 		number_of_vertices = 4;
   2572 		break;
   2573 	case GL_LINE_LOOP:
   2574 		number_of_vertices = 8;
   2575 		break;
   2576 	case GL_LINE_STRIP:
   2577 		number_of_vertices = 6;
   2578 		break;
   2579 	case GL_TRIANGLES:
   2580 		number_of_vertices = 6;
   2581 		break;
   2582 	case GL_TRIANGLE_STRIP:
   2583 		number_of_vertices = 6;
   2584 		break;
   2585 	case GL_TRIANGLE_FAN:
   2586 		number_of_vertices = 6;
   2587 		break;
   2588 	default:
   2589 		throw 0;
   2590 	}
   2591 
   2592 	glw::GLfloat* results = (glw::GLfloat*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
   2593 	GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed.");
   2594 
   2595 	bool is_ok = true;
   2596 
   2597 	for (glw::GLuint j = 0; (j < number_of_vertices) && is_ok; ++j)
   2598 	{
   2599 		for (glw::GLint i = 0; i < m_max_transform_feedback_components - 4; ++i)
   2600 		{
   2601 			glw::GLfloat result	= results[i + j * m_max_transform_feedback_components];
   2602 			glw::GLfloat reference = (glw::GLfloat)(i);
   2603 
   2604 			if (fabs(result - reference) > 0.125 /* precision */)
   2605 			{
   2606 				is_ok = false;
   2607 
   2608 				break;
   2609 			}
   2610 		}
   2611 
   2612 		/* gl_Position */
   2613 		glw::GLfloat result[4] = { results[(j + 1) * m_max_transform_feedback_components - 4],
   2614 								   results[(j + 1) * m_max_transform_feedback_components - 3],
   2615 								   results[(j + 1) * m_max_transform_feedback_components - 2],
   2616 								   results[(j + 1) * m_max_transform_feedback_components - 1] };
   2617 
   2618 		if ((fabs(fabs(result[0]) - 1.0 + s_rasterization_epsilon) > 0.125 /* precision */) ||
   2619 			(fabs(fabs(result[1]) - 1.0 + s_rasterization_epsilon) > 0.125 /* precision */) ||
   2620 			(fabs(result[2]) > 0.125 /* precision */) || (fabs(result[3] - 1.0) > 0.125 /* precision */))
   2621 		{
   2622 			is_ok = false;
   2623 
   2624 			break;
   2625 		}
   2626 	}
   2627 
   2628 	gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   2629 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");
   2630 
   2631 	return is_ok;
   2632 }
   2633 
   2634 void gl3cts::TransformFeedback::CaptureVertexInterleaved::bindBuffer(BindBufferCase bind_case)
   2635 {
   2636 	/* Functions handler */
   2637 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2638 
   2639 	switch (bind_case)
   2640 	{
   2641 	case BIND_BUFFER_BASE_CASE:
   2642 		gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer);
   2643 		break;
   2644 	case BIND_BUFFER_RANGE_CASE:
   2645 		gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer, 0, m_buffer_size);
   2646 		break;
   2647 	case BIND_BUFFER_OFFSET_CASE:
   2648 		if (DE_NULL == m_glBindBufferOffsetEXT)
   2649 		{
   2650 			throw 0;
   2651 		}
   2652 		m_glBindBufferOffsetEXT(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer, 0);
   2653 		break;
   2654 	default:
   2655 		throw 0;
   2656 	}
   2657 }
   2658 
   2659 void gl3cts::TransformFeedback::CaptureVertexInterleaved::clean(void)
   2660 {
   2661 	/* Functions handler */
   2662 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2663 
   2664 	if (m_program)
   2665 	{
   2666 		gl.deleteProgram(m_program);
   2667 
   2668 		m_program = 0;
   2669 	}
   2670 
   2671 	if (m_framebuffer)
   2672 	{
   2673 		gl.deleteFramebuffers(1, &m_framebuffer);
   2674 
   2675 		m_framebuffer = 0;
   2676 	}
   2677 
   2678 	if (m_renderbuffer)
   2679 	{
   2680 		gl.deleteRenderbuffers(1, &m_renderbuffer);
   2681 
   2682 		m_renderbuffer = 0;
   2683 	}
   2684 
   2685 	cleanBuffer();
   2686 
   2687 	if (m_vertex_array_object)
   2688 	{
   2689 		gl.deleteVertexArrays(1, &m_vertex_array_object);
   2690 
   2691 		m_vertex_array_object = 0;
   2692 	}
   2693 }
   2694 
   2695 void gl3cts::TransformFeedback::CaptureVertexInterleaved::cleanBuffer(void)
   2696 {
   2697 	/* Functions handler */
   2698 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2699 
   2700 	if (m_buffer)
   2701 	{
   2702 		gl.deleteBuffers(1, &m_buffer);
   2703 
   2704 		m_buffer = 0;
   2705 	}
   2706 }
   2707 
   2708 const glw::GLchar* gl3cts::TransformFeedback::CaptureVertexInterleaved::s_vertex_shader_source_code_template =
   2709 	"#version 130\n"
   2710 	"\n"
   2711 	"TEMPLATE_INPUT_OUTPUT_DECLARATIONS"
   2712 	"\n"
   2713 	"void main()\n"
   2714 	"{\n"
   2715 	"TEMPLATE_OUTPUT_SETTERS"
   2716 	"\n"
   2717 	"    vec4 position = vec4(0.0);\n"
   2718 	"\n"
   2719 	"    /* Note: The points are moved 0.0625 from the borders to\n"
   2720 	"             reduce non-XFB related rasterization problems. */\n"
   2721 	"    switch(gl_VertexID)\n"
   2722 	"    {\n"
   2723 	"        case 0:\n"
   2724 	"            position = vec4(-1.0 + TEMPLATE_RASTERIZATION_EPSILON,  1.0 - TEMPLATE_RASTERIZATION_EPSILON,  0.0,  "
   2725 	"1.0);\n"
   2726 	"            break;\n"
   2727 	"        case 1:\n"
   2728 	"            position = vec4( 1.0 - TEMPLATE_RASTERIZATION_EPSILON,  1.0 - TEMPLATE_RASTERIZATION_EPSILON,  0.0,  "
   2729 	"1.0);\n"
   2730 	"            break;\n"
   2731 	"        case 2:\n"
   2732 	"            position = vec4(-1.0 + TEMPLATE_RASTERIZATION_EPSILON, -1.0 + TEMPLATE_RASTERIZATION_EPSILON,  0.0,  "
   2733 	"1.0);\n"
   2734 	"            break;\n"
   2735 	"        case 3:\n"
   2736 	"            position = vec4( 1.0 - TEMPLATE_RASTERIZATION_EPSILON, -1.0 + TEMPLATE_RASTERIZATION_EPSILON,  0.0,  "
   2737 	"1.0);\n"
   2738 	"            break;\n"
   2739 	"    }\n"
   2740 	"\n"
   2741 	"    gl_Position = position;\n"
   2742 	"}\n";
   2743 
   2744 const glw::GLchar* gl3cts::TransformFeedback::CaptureVertexInterleaved::s_fragment_shader_source_code =
   2745 	"#version 130\n"
   2746 	"\n"
   2747 	"out vec4 color;\n"
   2748 	"\n"
   2749 	"void main()\n"
   2750 	"{\n"
   2751 	"    color = vec4(0.5);\n"
   2752 	"}\n";
   2753 
   2754 const glw::GLuint
   2755 	gl3cts::TransformFeedback::CaptureVertexInterleaved::s_element_indices[][s_max_element_indices_count] = {
   2756 		{ 0, 1, 2, 3 },		  { 0, 1, 2, 3 }, { 0, 1, 3, 2 }, { 0, 1, 3, 2 },
   2757 		{ 2, 0, 1, 2, 1, 3 }, { 0, 1, 2, 3 }, { 2, 0, 1, 3 }
   2758 	};
   2759 
   2760 const glw::GLuint gl3cts::TransformFeedback::CaptureVertexInterleaved::s_primitive_cases_count =
   2761 	sizeof(s_element_indices) / sizeof(s_element_indices[0]);
   2762 
   2763 const glw::GLenum gl3cts::TransformFeedback::CaptureVertexInterleaved::s_primitive_cases[] = {
   2764 	GL_POINTS, GL_LINES, GL_LINE_LOOP, GL_LINE_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN
   2765 };
   2766 
   2767 const glw::GLenum gl3cts::TransformFeedback::CaptureVertexInterleaved::s_primitive_cases_xfb[] = {
   2768 	GL_POINTS, GL_LINES, GL_LINES, GL_LINES, GL_TRIANGLES, GL_TRIANGLES, GL_TRIANGLES
   2769 };
   2770 
   2771 const glw::GLuint gl3cts::TransformFeedback::CaptureVertexInterleaved::s_element_indices_counts[] = { 4, 4, 4, 4,
   2772 																									  6, 4, 4 };
   2773 
   2774 const glw::GLuint gl3cts::TransformFeedback::CaptureVertexInterleaved::s_framebuffer_size =
   2775 	2; /* If you change this, update checkFramebuffer function according. */
   2776 
   2777 const glw::GLfloat gl3cts::TransformFeedback::CaptureVertexInterleaved::s_rasterization_epsilon = 0.0625;
   2778 
   2779 /*-----------------------------------------------------------------------------------------------*/
   2780 
   2781 gl3cts::TransformFeedback::CaptureGeometryInterleaved::CaptureGeometryInterleaved(deqp::Context& context,
   2782 																				  const char*	test_name,
   2783 																				  const char*	test_description)
   2784 	: CaptureVertexInterleaved(context, test_name, test_description)
   2785 {
   2786 }
   2787 
   2788 gl3cts::TransformFeedback::CaptureGeometryInterleaved::~CaptureGeometryInterleaved(void)
   2789 {
   2790 }
   2791 
   2792 tcu::TestNode::IterateResult gl3cts::TransformFeedback::CaptureGeometryInterleaved::iterate(void)
   2793 {
   2794 	/* Functions handler */
   2795 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2796 
   2797 	/* Initializations. */
   2798 	bool is_at_least_gl_30 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(3, 0)));
   2799 	bool is_at_least_gl_32 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(3, 2)));
   2800 	bool is_ext_tf_1	   = m_context.getContextInfo().isExtensionSupported("GL_EXT_transform_feedback");
   2801 	bool is_arb_gs_4	   = m_context.getContextInfo().isExtensionSupported("GL_ARB_geometry_shader4");
   2802 
   2803 	bool is_ok		= true;
   2804 	bool test_error = false;
   2805 
   2806 	/* Tests. */
   2807 	try
   2808 	{
   2809 		if ((is_at_least_gl_30 || is_ext_tf_1) && (is_at_least_gl_32 || is_arb_gs_4))
   2810 		{
   2811 			fetchLimits();
   2812 			createFramebuffer();
   2813 			createTransformFeedbackBuffer();
   2814 			createVertexArrayObject();
   2815 
   2816 			for (glw::GLuint i_primitive_case = 0;
   2817 				 (i_primitive_case < s_geometry_interleaved_primitive_cases_count) && is_ok; ++i_primitive_case)
   2818 			{
   2819 				buildProgram(i_primitive_case);
   2820 
   2821 				gl.useProgram(m_program);
   2822 
   2823 				GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
   2824 
   2825 				for (glw::GLint i_bind_case = 0; (i_bind_case < BIND_BUFFER_CASES_COUNT) && is_ok; ++i_bind_case)
   2826 				{
   2827 					if ((i_bind_case == BIND_BUFFER_OFFSET_CASE) && (DE_NULL == m_glBindBufferOffsetEXT))
   2828 					{
   2829 						continue;
   2830 					}
   2831 
   2832 					bindBuffer((BindBufferCase)i_bind_case);
   2833 
   2834 					draw(i_primitive_case);
   2835 
   2836 					is_ok = is_ok && checkFramebuffer(s_primitive_cases[i_primitive_case]);
   2837 					is_ok = is_ok &&
   2838 							checkTransformFeedbackBuffer((BindBufferCase)i_bind_case,
   2839 														 s_geometry_interleaved_primitive_cases_xfb[i_primitive_case]);
   2840 				}
   2841 
   2842 				gl.deleteProgram(m_program);
   2843 
   2844 				m_program = 0;
   2845 
   2846 				GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteProgram call failed.");
   2847 			}
   2848 		}
   2849 	}
   2850 	catch (...)
   2851 	{
   2852 		is_ok	  = false;
   2853 		test_error = true;
   2854 	}
   2855 
   2856 	/* Clean objects. */
   2857 	clean();
   2858 
   2859 	/* Result's setup. */
   2860 	if (is_ok)
   2861 	{
   2862 		/* Log success. */
   2863 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Capture Geometry have passed."
   2864 											<< tcu::TestLog::EndMessage;
   2865 
   2866 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   2867 	}
   2868 	else
   2869 	{
   2870 		if (test_error)
   2871 		{
   2872 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   2873 		}
   2874 		else
   2875 		{
   2876 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   2877 		}
   2878 	}
   2879 
   2880 	return STOP;
   2881 }
   2882 
   2883 void gl3cts::TransformFeedback::CaptureGeometryInterleaved::fetchLimits(void)
   2884 {
   2885 	/* Functions handler */
   2886 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2887 
   2888 	/* Fetching limits. */
   2889 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &m_max_transform_feedback_components);
   2890 
   2891 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   2892 
   2893 	if (m_max_transform_feedback_components == 0)
   2894 	{
   2895 		throw 0;
   2896 	}
   2897 
   2898 	glw::GLint max_geometry_total_components = 0;
   2899 
   2900 	gl.getIntegerv(GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS, &max_geometry_total_components);
   2901 
   2902 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   2903 
   2904 	if (max_geometry_total_components == 0)
   2905 	{
   2906 		throw 0;
   2907 	}
   2908 
   2909 	if (m_max_transform_feedback_components * 4 > max_geometry_total_components)
   2910 	{
   2911 		m_max_transform_feedback_components = max_geometry_total_components / 4;
   2912 	}
   2913 }
   2914 
   2915 void gl3cts::TransformFeedback::CaptureGeometryInterleaved::buildProgram(glw::GLuint primitive_case)
   2916 {
   2917 	/* Functions handler */
   2918 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2919 
   2920 	/* Preparing source code. */
   2921 	std::string geometry_shader(s_geometry_shader_source_code_template); /* Storage for vertex shader source code. */
   2922 	std::string transform_feedback_variable_declarations(
   2923 		""); /* String to contain all custom outputs from vertex shader. */
   2924 	std::string transform_feedback_variable_setters(
   2925 		""); /* String containing all initializations of custom outputs from vertex shader. */
   2926 	std::vector<std::string> transform_feedback_varyings(m_max_transform_feedback_components); /* Varyings array. */
   2927 	std::vector<const glw::GLchar*> transform_feedback_varyings_c(
   2928 		m_max_transform_feedback_components); /* Varyings array in C form to pass to the GL. */
   2929 
   2930 	glw::GLint user_defined_transform_feedback_interleaved_varyings_count =
   2931 		m_max_transform_feedback_components /* total max to be written by the shader */
   2932 			/ 4								/* components per vec4 */
   2933 		//                                                                          / 4 /* number of vertices */
   2934 		- 1 /* gl_Position */;
   2935 
   2936 	glw::GLint all_transform_feedback_interleaved_varyings_count =
   2937 		user_defined_transform_feedback_interleaved_varyings_count + 1 /* gl_Position */;
   2938 
   2939 	/* Most of varyings is declarated output variables. */
   2940 	for (glw::GLint i = 0; i < user_defined_transform_feedback_interleaved_varyings_count; ++i)
   2941 	{
   2942 		/* Preparing variable name. */
   2943 		std::string varying = "result_";
   2944 		varying.append(gl3cts::TransformFeedback::Utilities::itoa(i));
   2945 
   2946 		transform_feedback_varyings[i] = varying;
   2947 
   2948 		transform_feedback_varyings_c[i] = transform_feedback_varyings[i].c_str();
   2949 
   2950 		/* Preparing variable declaration. */
   2951 		transform_feedback_variable_declarations.append("out vec4 ");
   2952 		transform_feedback_variable_declarations.append(varying);
   2953 		transform_feedback_variable_declarations.append(";\n");
   2954 
   2955 		/* Preparing variable setters. */
   2956 		transform_feedback_variable_setters.append("    ");
   2957 		transform_feedback_variable_setters.append(varying);
   2958 		transform_feedback_variable_setters.append(" = vec4(");
   2959 		transform_feedback_variable_setters.append(gl3cts::TransformFeedback::Utilities::itoa(i * 4));
   2960 		transform_feedback_variable_setters.append(".0, ");
   2961 		transform_feedback_variable_setters.append(gl3cts::TransformFeedback::Utilities::itoa(i * 4 + 1));
   2962 		transform_feedback_variable_setters.append(".0, ");
   2963 		transform_feedback_variable_setters.append(gl3cts::TransformFeedback::Utilities::itoa(i * 4 + 2));
   2964 		transform_feedback_variable_setters.append(".0, ");
   2965 		transform_feedback_variable_setters.append(gl3cts::TransformFeedback::Utilities::itoa(i * 4 + 3));
   2966 		transform_feedback_variable_setters.append(".0);\n");
   2967 	}
   2968 
   2969 	/* Last four varying components are gl_Position components. */
   2970 	transform_feedback_varyings[user_defined_transform_feedback_interleaved_varyings_count /* gl_Position */] =
   2971 		"gl_Position";
   2972 
   2973 	transform_feedback_varyings_c[user_defined_transform_feedback_interleaved_varyings_count /* gl_Position */] =
   2974 		transform_feedback_varyings[user_defined_transform_feedback_interleaved_varyings_count /* gl_Position */]
   2975 			.c_str();
   2976 
   2977 	/* Preprocess vertex shader source code template. */
   2978 	geometry_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(
   2979 		geometry_shader, "TEMPLATE_PRIMITIVE_TYPE", s_geometry_interleaved_primitive_cases[primitive_case]);
   2980 	geometry_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(
   2981 		geometry_shader, "TEMPLATE_INPUT_OUTPUT_DECLARATIONS", transform_feedback_variable_declarations);
   2982 	geometry_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(geometry_shader, "TEMPLATE_OUTPUT_SETTERS",
   2983 																		   transform_feedback_variable_setters);
   2984 	geometry_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(
   2985 		geometry_shader, "TEMPLATE_RASTERIZATION_EPSILON",
   2986 		gl3cts::TransformFeedback::Utilities::ftoa(s_rasterization_epsilon));
   2987 
   2988 	/* Compile, link and check. */
   2989 	m_program = gl3cts::TransformFeedback::Utilities::buildProgram(
   2990 		gl, m_context.getTestContext().getLog(), geometry_shader.c_str(), NULL, NULL, s_blank_vertex_shader_source_code,
   2991 		s_fragment_shader_source_code, &transform_feedback_varyings_c[0],
   2992 		all_transform_feedback_interleaved_varyings_count, m_attrib_type);
   2993 
   2994 	if (0 == m_program)
   2995 	{
   2996 		throw 0;
   2997 	}
   2998 }
   2999 
   3000 void gl3cts::TransformFeedback::CaptureGeometryInterleaved::draw(glw::GLuint primitive_case)
   3001 {
   3002 	/* Functions handler */
   3003 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3004 
   3005 	gl.clear(GL_COLOR_BUFFER_BIT);
   3006 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed.");
   3007 
   3008 	gl.beginTransformFeedback(s_geometry_interleaved_primitive_cases_xfb[primitive_case]);
   3009 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
   3010 
   3011 	gl.drawArrays(GL_POINTS, 0, 1);
   3012 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
   3013 
   3014 	gl.endTransformFeedback();
   3015 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedbac call failed.");
   3016 }
   3017 
   3018 const glw::GLchar* gl3cts::TransformFeedback::CaptureGeometryInterleaved::s_geometry_shader_source_code_template =
   3019 	"#version 150\n"
   3020 	"\n"
   3021 	"layout(points) in;\n"
   3022 	"layout(TEMPLATE_PRIMITIVE_TYPE, max_vertices = 4) out;\n"
   3023 	"\n"
   3024 	"TEMPLATE_INPUT_OUTPUT_DECLARATIONS"
   3025 	"\n"
   3026 	"void main()\n"
   3027 	"{\n"
   3028 	"    /* Note: The points are moved 0.0625 from the borders to\n"
   3029 	"             reduce non-XFB related rasterization problems. */\n"
   3030 	"\n"
   3031 	"    gl_Position = vec4(-1.0 + TEMPLATE_RASTERIZATION_EPSILON,  1.0 - TEMPLATE_RASTERIZATION_EPSILON,  0.0,  "
   3032 	"1.0);\n"
   3033 	"TEMPLATE_OUTPUT_SETTERS"
   3034 	"    EmitVertex();\n"
   3035 	"\n"
   3036 	"    gl_Position = vec4( 1.0 - TEMPLATE_RASTERIZATION_EPSILON,  1.0 - TEMPLATE_RASTERIZATION_EPSILON,  0.0,  "
   3037 	"1.0);\n"
   3038 	"TEMPLATE_OUTPUT_SETTERS"
   3039 	"    EmitVertex();\n"
   3040 	"\n"
   3041 	"    gl_Position = vec4(-1.0 + TEMPLATE_RASTERIZATION_EPSILON, -1.0 + TEMPLATE_RASTERIZATION_EPSILON,  0.0,  "
   3042 	"1.0);\n"
   3043 	"TEMPLATE_OUTPUT_SETTERS"
   3044 	"    EmitVertex();\n"
   3045 	"\n"
   3046 	"    gl_Position = vec4( 1.0 - TEMPLATE_RASTERIZATION_EPSILON, -1.0 + TEMPLATE_RASTERIZATION_EPSILON,  0.0,  "
   3047 	"1.0);\n"
   3048 	"TEMPLATE_OUTPUT_SETTERS"
   3049 	"    EmitVertex();\n"
   3050 	"}\n";
   3051 
   3052 const glw::GLchar* gl3cts::TransformFeedback::CaptureGeometryInterleaved::s_blank_vertex_shader_source_code =
   3053 	"#version 130\n"
   3054 	"\n"
   3055 	"void main()\n"
   3056 	"{\n"
   3057 	"}\n";
   3058 
   3059 const glw::GLchar* gl3cts::TransformFeedback::CaptureGeometryInterleaved::s_geometry_interleaved_primitive_cases[] = {
   3060 	"points", "line_strip", "triangle_strip"
   3061 };
   3062 
   3063 const glw::GLenum gl3cts::TransformFeedback::CaptureGeometryInterleaved::s_geometry_interleaved_primitive_cases_xfb[] =
   3064 	{ GL_POINTS, GL_LINES, GL_TRIANGLES };
   3065 
   3066 const glw::GLuint gl3cts::TransformFeedback::CaptureGeometryInterleaved::s_geometry_interleaved_primitive_cases_count =
   3067 	sizeof(s_geometry_interleaved_primitive_cases) / sizeof(s_geometry_interleaved_primitive_cases[0]);
   3068 
   3069 /*-----------------------------------------------------------------------------------------------*/
   3070 
   3071 gl3cts::TransformFeedback::CaptureVertexSeparate::CaptureVertexSeparate(deqp::Context& context, const char* test_name,
   3072 																		const char* test_description)
   3073 	: CaptureVertexInterleaved(context, test_name, test_description)
   3074 	, m_buffers(DE_NULL)
   3075 	, m_max_transform_feedback_separate_attribs(0)
   3076 {
   3077 	m_attrib_type = GL_SEPARATE_ATTRIBS;
   3078 }
   3079 
   3080 void gl3cts::TransformFeedback::CaptureVertexSeparate::fetchLimits(void)
   3081 {
   3082 	/* Functions handler */
   3083 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3084 
   3085 	/* Fetching limits. */
   3086 	glw::GLint max_transform_feedback_separate_components;
   3087 
   3088 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_transform_feedback_separate_components);
   3089 
   3090 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   3091 
   3092 	if (max_transform_feedback_separate_components < 4)
   3093 	{
   3094 		throw 0;
   3095 	}
   3096 
   3097 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &m_max_transform_feedback_separate_attribs);
   3098 
   3099 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   3100 
   3101 	if (m_max_transform_feedback_separate_attribs == 0)
   3102 	{
   3103 		throw 0;
   3104 	}
   3105 
   3106 	m_max_transform_feedback_components = m_max_transform_feedback_separate_attribs * 4 /* vec4 is used */;
   3107 
   3108 	glw::GLint max_varyings_components = 0;
   3109 
   3110 	gl.getIntegerv(GL_MAX_VARYING_COMPONENTS, &max_varyings_components);
   3111 
   3112 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   3113 
   3114 	if (max_varyings_components == 0)
   3115 	{
   3116 		throw 0;
   3117 	}
   3118 
   3119 	if (m_max_transform_feedback_components > max_varyings_components)
   3120 	{
   3121 		m_max_transform_feedback_components = max_varyings_components;
   3122 	}
   3123 }
   3124 
   3125 void gl3cts::TransformFeedback::CaptureVertexSeparate::createTransformFeedbackBuffer(void)
   3126 {
   3127 	/* Functions handler */
   3128 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3129 
   3130 	m_buffers = new glw::GLuint[m_max_transform_feedback_components];
   3131 
   3132 	if (DE_NULL == m_buffers)
   3133 	{
   3134 		throw 0;
   3135 	}
   3136 
   3137 	gl.genBuffers(m_max_transform_feedback_separate_attribs, m_buffers);
   3138 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   3139 
   3140 	m_buffer_size = static_cast<glw::GLuint>(m_max_vertices_drawn * 4 /* vec4 */ * sizeof(glw::GLfloat));
   3141 
   3142 	for (glw::GLint i = 0; i < m_max_transform_feedback_separate_attribs; ++i)
   3143 	{
   3144 		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_buffers[i]);
   3145 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   3146 
   3147 		gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, m_buffer_size, NULL, GL_DYNAMIC_READ);
   3148 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
   3149 	}
   3150 }
   3151 
   3152 void gl3cts::TransformFeedback::CaptureVertexSeparate::bindBuffer(BindBufferCase bind_case)
   3153 {
   3154 	/* Functions handler */
   3155 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3156 
   3157 	switch (bind_case)
   3158 	{
   3159 	case BIND_BUFFER_BASE_CASE:
   3160 		for (glw::GLint i = 0; i < m_max_transform_feedback_separate_attribs; ++i)
   3161 		{
   3162 			gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, i, m_buffers[i]);
   3163 		}
   3164 		break;
   3165 	case BIND_BUFFER_RANGE_CASE:
   3166 		for (glw::GLint i = 0; i < m_max_transform_feedback_separate_attribs; ++i)
   3167 		{
   3168 			gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, i, m_buffers[i], 0, m_buffer_size);
   3169 		}
   3170 		break;
   3171 	case BIND_BUFFER_OFFSET_CASE:
   3172 		for (glw::GLint i = 0; i < m_max_transform_feedback_separate_attribs; ++i)
   3173 		{
   3174 			m_glBindBufferOffsetEXT(GL_TRANSFORM_FEEDBACK_BUFFER, i, m_buffers[i], 0);
   3175 		}
   3176 		break;
   3177 	default:
   3178 		throw 0;
   3179 	}
   3180 }
   3181 
   3182 void gl3cts::TransformFeedback::CaptureVertexSeparate::cleanBuffer(void)
   3183 {
   3184 	/* Functions handler */
   3185 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3186 
   3187 	if (DE_NULL != m_buffers)
   3188 	{
   3189 		gl.deleteBuffers(m_max_transform_feedback_separate_attribs, m_buffers);
   3190 
   3191 		delete[] m_buffers;
   3192 
   3193 		m_buffers = DE_NULL;
   3194 	}
   3195 }
   3196 
   3197 bool gl3cts::TransformFeedback::CaptureVertexSeparate::checkTransformFeedbackBuffer(BindBufferCase bind_case UNUSED,
   3198 																					glw::GLenum primitive_type)
   3199 {
   3200 	/* Functions handler */
   3201 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3202 
   3203 	glw::GLuint number_of_vertices = 0;
   3204 
   3205 	switch (primitive_type)
   3206 	{
   3207 	case GL_POINTS:
   3208 		number_of_vertices = 4;
   3209 		break;
   3210 	case GL_LINES:
   3211 		number_of_vertices = 4;
   3212 		break;
   3213 	case GL_LINE_LOOP:
   3214 		number_of_vertices = 8;
   3215 		break;
   3216 	case GL_LINE_STRIP:
   3217 		number_of_vertices = 6;
   3218 		break;
   3219 	case GL_TRIANGLES:
   3220 		number_of_vertices = 6;
   3221 		break;
   3222 	case GL_TRIANGLE_STRIP:
   3223 		number_of_vertices = 6;
   3224 		break;
   3225 	case GL_TRIANGLE_FAN:
   3226 		number_of_vertices = 6;
   3227 		break;
   3228 	default:
   3229 		throw 0;
   3230 	}
   3231 
   3232 	bool is_ok = true;
   3233 
   3234 	for (glw::GLint i = 0; i < m_max_transform_feedback_separate_attribs - 1; ++i)
   3235 	{
   3236 		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_buffers[i]);
   3237 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   3238 
   3239 		glw::GLfloat* results = (glw::GLfloat*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
   3240 		GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed.");
   3241 
   3242 		for (glw::GLuint j = 0; (j < number_of_vertices) && is_ok; ++j)
   3243 		{
   3244 			for (glw::GLuint k = 0; k < 4 /* vec4 */; ++k)
   3245 			{
   3246 				glw::GLfloat result	= results[j * 4 + k];
   3247 				glw::GLfloat reference = (glw::GLfloat)(i * 4 + k);
   3248 
   3249 				if (fabs(result - reference) > 0.125 /* precision */)
   3250 				{
   3251 					is_ok = false;
   3252 
   3253 					break;
   3254 				}
   3255 			}
   3256 		}
   3257 
   3258 		gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   3259 		GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");
   3260 	}
   3261 
   3262 	/* gl_Position */
   3263 	if (is_ok)
   3264 	{
   3265 		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_buffers[m_max_transform_feedback_separate_attribs - 1]);
   3266 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   3267 
   3268 		glw::GLfloat* results = (glw::GLfloat*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
   3269 		GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed.");
   3270 
   3271 		for (glw::GLuint j = 0; (j < number_of_vertices) && is_ok; ++j)
   3272 		{
   3273 			glw::GLfloat result[4] = { results[j * 4], results[j * 4 + 1], results[j * 4 + 2], results[j * 4 + 3] };
   3274 
   3275 			if ((fabs(fabs(result[0]) - 1.0 + s_rasterization_epsilon) > 0.125 /* precision */) ||
   3276 				(fabs(fabs(result[1]) - 1.0 + s_rasterization_epsilon) > 0.125 /* precision */) ||
   3277 				(fabs(result[2]) > 0.125 /* precision */) || (fabs(result[3] - 1.0) > 0.125 /* precision */))
   3278 			{
   3279 				is_ok = false;
   3280 
   3281 				break;
   3282 			}
   3283 		}
   3284 
   3285 		gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   3286 		GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");
   3287 	}
   3288 
   3289 	return is_ok;
   3290 }
   3291 
   3292 /*-----------------------------------------------------------------------------------------------*/
   3293 
   3294 gl3cts::TransformFeedback::CaptureGeometrySeparate::CaptureGeometrySeparate(deqp::Context& context,
   3295 																			const char*	test_name,
   3296 																			const char*	test_description)
   3297 	: CaptureVertexInterleaved(context, test_name, test_description)
   3298 	, CaptureVertexSeparate(context, test_name, test_description)
   3299 	, CaptureGeometryInterleaved(context, test_name, test_description)
   3300 	, m_buffers(DE_NULL)
   3301 	, m_max_transform_feedback_separate_attribs(0)
   3302 {
   3303 }
   3304 
   3305 /*-----------------------------------------------------------------------------------------------*/
   3306 
   3307 gl3cts::TransformFeedback::CheckGetXFBVarying::CheckGetXFBVarying(deqp::Context& context, const char* test_name,
   3308 																  const char* test_description)
   3309 	: deqp::TestCase(context, test_name, test_description)
   3310 	, m_context(context)
   3311 	, m_max_xfb_interleaved_components(0)
   3312 	, m_max_xfb_separate_attributes(0)
   3313 	, m_max_xfb_separate_components(0)
   3314 	, m_max_varying_components(0)
   3315 	, m_max_varying_vectors(0)
   3316 	, m_max_geometry_total_output_components(0)
   3317 {
   3318 }
   3319 
   3320 gl3cts::TransformFeedback::CheckGetXFBVarying::~CheckGetXFBVarying(void)
   3321 {
   3322 }
   3323 
   3324 void gl3cts::TransformFeedback::CheckGetXFBVarying::fetchLimits(void)
   3325 {
   3326 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3327 
   3328 	/* Fetching limits. */
   3329 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &m_max_xfb_interleaved_components);
   3330 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &m_max_xfb_separate_attributes);
   3331 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &m_max_xfb_separate_components);
   3332 	gl.getIntegerv(GL_MAX_VARYING_COMPONENTS, &m_max_varying_components);
   3333 	gl.getIntegerv(GL_MAX_VARYING_VECTORS, &m_max_varying_vectors);
   3334 	gl.getIntegerv(GL_MAX_GEOMETRY_OUTPUT_COMPONENTS, &m_max_geometry_total_output_components);
   3335 
   3336 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   3337 }
   3338 
   3339 glw::GLuint gl3cts::TransformFeedback::CheckGetXFBVarying::numberOfAttributes(glw::GLuint capture_way,
   3340 																			  glw::GLuint shader_case,
   3341 																			  glw::GLuint varying_type)
   3342 {
   3343 	/* Setup limits of the case. */
   3344 	const glw::GLuint max_total_components =
   3345 		((s_shader_cases[shader_case].geometry_shader == DE_NULL) ? m_max_varying_components :
   3346 																	m_max_geometry_total_output_components) -
   3347 		4 /* gl_Position is not captured */;
   3348 
   3349 	const glw::GLuint attribute_components = s_varying_types[varying_type].components_count;
   3350 	const glw::GLuint max_xfb_components   = (s_capture_ways[capture_way] == GL_INTERLEAVED_ATTRIBS) ?
   3351 											   m_max_xfb_interleaved_components :
   3352 											   (attribute_components * m_max_xfb_separate_components);
   3353 
   3354 	if (s_capture_ways[capture_way] == GL_SEPARATE_ATTRIBS)
   3355 	{
   3356 		if (attribute_components > glw::GLuint(m_max_xfb_separate_components))
   3357 		{
   3358 			return 0;
   3359 		}
   3360 	}
   3361 
   3362 	/* Setup number of attributes. */
   3363 	glw::GLuint number_of_attributes = max_xfb_components / attribute_components;
   3364 
   3365 	if (s_capture_ways[capture_way] == GL_SEPARATE_ATTRIBS &&
   3366 		number_of_attributes > glw::GLuint(m_max_xfb_separate_attributes))
   3367 	{
   3368 		number_of_attributes = m_max_xfb_separate_attributes;
   3369 	}
   3370 
   3371 	/* Clamp to limits. */
   3372 	if (number_of_attributes * attribute_components > max_total_components)
   3373 	{
   3374 		number_of_attributes = max_total_components / attribute_components;
   3375 	}
   3376 
   3377 	/* Vectors limit. */
   3378 	if (attribute_components <= 4)
   3379 	{
   3380 		if (number_of_attributes > glw::GLuint(m_max_varying_vectors))
   3381 		{
   3382 			number_of_attributes = m_max_varying_vectors;
   3383 		}
   3384 	}
   3385 	else
   3386 	{
   3387 		if (number_of_attributes > glw::GLuint(m_max_varying_vectors) / 4)
   3388 		{
   3389 			number_of_attributes = glw::GLuint(m_max_varying_vectors) / 4;
   3390 		}
   3391 	}
   3392 
   3393 	/* Return. */
   3394 	return number_of_attributes;
   3395 }
   3396 
   3397 tcu::TestNode::IterateResult gl3cts::TransformFeedback::CheckGetXFBVarying::iterate(void)
   3398 {
   3399 	/* Functions handler */
   3400 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3401 
   3402 	/* Initializations. */
   3403 	bool is_at_least_gl_30 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(3, 0)));
   3404 	bool is_ext_tf_1	   = m_context.getContextInfo().isExtensionSupported("GL_EXT_transform_feedback");
   3405 
   3406 	bool is_ok		= true;
   3407 	bool test_error = false;
   3408 
   3409 	glw::GLuint program = 0;
   3410 
   3411 	/* Tests. */
   3412 	try
   3413 	{
   3414 		if (is_at_least_gl_30 || is_ext_tf_1)
   3415 		{
   3416 			fetchLimits();
   3417 
   3418 			for (glw::GLuint i = 0; (i < s_capture_ways_count) && is_ok; ++i)
   3419 			{
   3420 				for (glw::GLuint j = 0; (j < s_shader_cases_count) && is_ok; ++j)
   3421 				{
   3422 					for (glw::GLuint k = 0; (k < s_varying_types_count) && is_ok; ++k)
   3423 					{
   3424 						glw::GLuint n = numberOfAttributes(i, j, k);
   3425 
   3426 						if (n)
   3427 						{
   3428 							program = buildProgram(i, j, k, n);
   3429 
   3430 							is_ok = is_ok && (program != 0);
   3431 
   3432 							is_ok = is_ok && check(program, i, j, k, n);
   3433 
   3434 							gl.deleteProgram(program);
   3435 
   3436 							GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteProgram call failed.");
   3437 
   3438 							program = 0;
   3439 						}
   3440 					}
   3441 				}
   3442 			}
   3443 		}
   3444 	}
   3445 	catch (...)
   3446 	{
   3447 		is_ok	  = false;
   3448 		test_error = true;
   3449 
   3450 		if (program)
   3451 		{
   3452 			gl.deleteProgram(program);
   3453 
   3454 			program = 0;
   3455 		}
   3456 	}
   3457 
   3458 	/* Result's setup. */
   3459 	if (is_ok)
   3460 	{
   3461 		/* Log success. */
   3462 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   3463 											<< "Test checking Get Transform Feedback Varying have passed."
   3464 											<< tcu::TestLog::EndMessage;
   3465 
   3466 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   3467 	}
   3468 	else
   3469 	{
   3470 		if (test_error)
   3471 		{
   3472 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   3473 		}
   3474 		else
   3475 		{
   3476 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   3477 		}
   3478 	}
   3479 
   3480 	return STOP;
   3481 }
   3482 
   3483 glw::GLuint gl3cts::TransformFeedback::CheckGetXFBVarying::buildProgram(glw::GLuint capture_way,
   3484 																		glw::GLuint shader_case,
   3485 																		glw::GLuint varying_type,
   3486 																		glw::GLuint number_of_attributes)
   3487 {
   3488 	/* Functions handler */
   3489 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3490 
   3491 	/* Preparing source code. */
   3492 	std::string						xfb_variable_declarations("");
   3493 	std::string						xfb_variable_setters("");
   3494 	std::vector<std::string>		xfb_varyings(number_of_attributes);
   3495 	std::vector<const glw::GLchar*> xfb_varyings_c(number_of_attributes);
   3496 
   3497 	/* Most of varyings is declarated output variables. */
   3498 	for (glw::GLuint i = 0; i < number_of_attributes; ++i)
   3499 	{
   3500 		/* Varying name: result_# */
   3501 		std::string varying = "result_";
   3502 		varying.append(gl3cts::TransformFeedback::Utilities::itoa(i));
   3503 
   3504 		xfb_varyings[i]   = varying;
   3505 		xfb_varyings_c[i] = xfb_varyings[i].c_str();
   3506 
   3507 		/* Varying declaration: out TYPE result_#;*/
   3508 		xfb_variable_declarations.append("out ");
   3509 		xfb_variable_declarations.append(s_varying_types[varying_type].name);
   3510 		xfb_variable_declarations.append(" ");
   3511 		xfb_variable_declarations.append(varying);
   3512 		xfb_variable_declarations.append(";\n");
   3513 
   3514 		/* Varying setter: result_# = TYPE(#); */
   3515 		xfb_variable_setters.append("    ");
   3516 		xfb_variable_setters.append(varying);
   3517 		xfb_variable_setters.append(" = ");
   3518 		xfb_variable_setters.append(s_varying_types[varying_type].name);
   3519 		xfb_variable_setters.append("(");
   3520 		xfb_variable_setters.append("2"); //gl3cts::TransformFeedback::Utilities::itoa(i));
   3521 		if (s_varying_types[varying_type].float_component)
   3522 		{
   3523 			/* if varying is float varying setter is: result_# = TYPE(#.0); */
   3524 			xfb_variable_setters.append(".0");
   3525 		}
   3526 		xfb_variable_setters.append(");\n");
   3527 	}
   3528 
   3529 	/* Preprocess vertex shader source code template. */
   3530 	const glw::GLchar* vertex_shader   = s_shader_cases[shader_case].vertex_shader;
   3531 	const glw::GLchar* geometry_shader = s_shader_cases[shader_case].geometry_shader;
   3532 
   3533 	std::string xfb_shader;
   3534 
   3535 	if (DE_NULL == s_shader_cases[shader_case].geometry_shader)
   3536 	{
   3537 		/* XFB tested in vertex shader. */
   3538 		xfb_shader = vertex_shader;
   3539 	}
   3540 	else
   3541 	{
   3542 		/* XFB tested in geometry shader. */
   3543 		xfb_shader = geometry_shader;
   3544 	}
   3545 
   3546 	/* Preprocess shader. */
   3547 	xfb_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(xfb_shader, "TEMPLATE_OUTPUT_DECLARATIONS",
   3548 																	  xfb_variable_declarations);
   3549 	xfb_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(xfb_shader, "TEMPLATE_OUTPUT_SETTERS",
   3550 																	  xfb_variable_setters);
   3551 
   3552 	if (DE_NULL == s_shader_cases[shader_case].geometry_shader)
   3553 	{
   3554 		/* XFB tested in vertex shader. */
   3555 		vertex_shader = xfb_shader.c_str();
   3556 	}
   3557 	else
   3558 	{
   3559 		/* XFB tested in geometry shader. */
   3560 		geometry_shader = xfb_shader.c_str();
   3561 	}
   3562 
   3563 	/* Compile, link and check. */
   3564 	glw::GLuint program = gl3cts::TransformFeedback::Utilities::buildProgram(
   3565 		gl, m_context.getTestContext().getLog(), geometry_shader, NULL, NULL, vertex_shader, s_generic_fragment_shader,
   3566 		&xfb_varyings_c[0], number_of_attributes, s_capture_ways[capture_way]);
   3567 
   3568 	/* Check compilation status. */
   3569 	if (0 == program)
   3570 	{
   3571 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Building program has failed.\nVertex shader:\n"
   3572 											<< vertex_shader << "Geometry shader:\n"
   3573 											<< ((DE_NULL == geometry_shader) ? "" : geometry_shader)
   3574 											<< "Fragment shader:\n"
   3575 											<< s_generic_fragment_shader << tcu::TestLog::EndMessage;
   3576 
   3577 		throw 0;
   3578 	}
   3579 
   3580 	return program;
   3581 }
   3582 
   3583 bool gl3cts::TransformFeedback::CheckGetXFBVarying::check(glw::GLuint program, glw::GLuint capture_way,
   3584 														  glw::GLuint shader_case UNUSED, glw::GLuint varying_type,
   3585 														  glw::GLuint number_of_attributes)
   3586 {
   3587 	/* Functions handler */
   3588 	const glw::Functions& gl		 = m_context.getRenderContext().getFunctions();
   3589 	glw::GLuint			  max_length = 0;
   3590 
   3591 	/* Inspect glGetTransformFeedbackVarying. */
   3592 	for (glw::GLuint i = 0; i < number_of_attributes; ++i)
   3593 	{
   3594 		const glw::GLsizei bufSize  = 18;
   3595 		glw::GLsizei	   length   = 0;
   3596 		glw::GLsizei	   size		= 0;
   3597 		glw::GLenum		   type		= GL_NONE;
   3598 		glw::GLchar		   name[18] = { 0 }; /* Size of bufSize. */
   3599 
   3600 		gl.getTransformFeedbackVarying(program, i, bufSize, &length, &size, &type, name);
   3601 
   3602 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbackVarying call failed.");
   3603 
   3604 		max_length = deMaxu32(max_length, glw::GLuint(length));
   3605 
   3606 		/* Check name. */
   3607 		if (length)
   3608 		{
   3609 			std::string varying		= name;
   3610 			std::string varying_ref = "result_";
   3611 			varying_ref.append(gl3cts::TransformFeedback::Utilities::itoa(i));
   3612 
   3613 			if (0 != varying.compare(varying_ref))
   3614 			{
   3615 				return false;
   3616 			}
   3617 		}
   3618 		else
   3619 		{
   3620 			return false;
   3621 		}
   3622 
   3623 		/* Check size. */
   3624 		const glw::GLuint size_ref = 1;
   3625 
   3626 		if (size != size_ref)
   3627 		{
   3628 			return false;
   3629 		}
   3630 
   3631 		/* Check type. */
   3632 		if (type != s_varying_types[varying_type].type)
   3633 		{
   3634 			return false;
   3635 		}
   3636 	}
   3637 
   3638 	/* Inspect glGetProgramiv. */
   3639 	glw::GLint xfb_varyings			  = 0;
   3640 	glw::GLint xfb_mode				  = 0;
   3641 	glw::GLint xfb_varying_max_length = 0;
   3642 
   3643 	gl.getProgramiv(program, GL_TRANSFORM_FEEDBACK_VARYINGS, &xfb_varyings);
   3644 	gl.getProgramiv(program, GL_TRANSFORM_FEEDBACK_BUFFER_MODE, &xfb_mode);
   3645 	gl.getProgramiv(program, GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, &xfb_varying_max_length);
   3646 
   3647 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");
   3648 
   3649 	if (glw::GLuint(xfb_varyings) != number_of_attributes)
   3650 	{
   3651 		return false;
   3652 	}
   3653 
   3654 	if (glw::GLenum(xfb_mode) != s_capture_ways[capture_way])
   3655 	{
   3656 		return false;
   3657 	}
   3658 
   3659 	if (glw::GLuint(xfb_varying_max_length) < max_length)
   3660 	{
   3661 		return false;
   3662 	}
   3663 
   3664 	return true;
   3665 }
   3666 
   3667 const glw::GLchar* gl3cts::TransformFeedback::CheckGetXFBVarying::s_generic_fragment_shader = "#version 130\n"
   3668 																							  "\n"
   3669 																							  "out vec4 color;\n"
   3670 																							  "\n"
   3671 																							  "void main()\n"
   3672 																							  "{\n"
   3673 																							  "    color = vec4(1.0);\n"
   3674 																							  "}\n";
   3675 
   3676 const struct gl3cts::TransformFeedback::CheckGetXFBVarying::ShaderCase
   3677 	gl3cts::TransformFeedback::CheckGetXFBVarying::s_shader_cases[] = { { /* Vertex Shader. */
   3678 																		  "#version 130\n"
   3679 																		  "\n"
   3680 																		  "TEMPLATE_OUTPUT_DECLARATIONS"
   3681 																		  "\n"
   3682 																		  "void main()\n"
   3683 																		  "{\n"
   3684 																		  "    gl_Position = vec4(1.0);\n"
   3685 																		  "TEMPLATE_OUTPUT_SETTERS"
   3686 																		  "}\n",
   3687 
   3688 																		  /* Geometry Shader. */
   3689 																		  NULL },
   3690 																		{ /* Vertex Shader. */
   3691 																		  "#version 130\n"
   3692 																		  "\n"
   3693 																		  "void main()\n"
   3694 																		  "{\n"
   3695 																		  "}\n",
   3696 
   3697 																		  /* Geometry Shader. */
   3698 																		  "#version 150\n"
   3699 																		  "\n"
   3700 																		  "layout(points) in;\n"
   3701 																		  "layout(points, max_vertices = 1) out;\n"
   3702 																		  "\n"
   3703 																		  "TEMPLATE_OUTPUT_DECLARATIONS"
   3704 																		  "\n"
   3705 																		  "void main()\n"
   3706 																		  "{\n"
   3707 																		  "    gl_Position = vec4(1.0);\n"
   3708 																		  "TEMPLATE_OUTPUT_SETTERS"
   3709 																		  "    EmitVertex();\n"
   3710 																		  "}\n" } };
   3711 
   3712 const glw::GLuint gl3cts::TransformFeedback::CheckGetXFBVarying::s_shader_cases_count =
   3713 	sizeof(s_shader_cases) / sizeof(s_shader_cases[0]);
   3714 
   3715 const struct gl3cts::TransformFeedback::CheckGetXFBVarying::VaryingType
   3716 	gl3cts::TransformFeedback::CheckGetXFBVarying::s_varying_types[] = {
   3717 		/* type,				name,		#components,	is component float */
   3718 		{ GL_FLOAT, "float", 1, true },
   3719 		{ GL_FLOAT_VEC2, "vec2", 2, true },
   3720 		{ GL_FLOAT_VEC3, "vec3", 3, true },
   3721 		{ GL_FLOAT_VEC4, "vec4", 4, true },
   3722 		{ GL_INT, "int", 1, false },
   3723 		{ GL_INT_VEC2, "ivec2", 2, false },
   3724 		{ GL_INT_VEC3, "ivec3", 3, false },
   3725 		{ GL_INT_VEC4, "ivec4", 4, false },
   3726 		{ GL_UNSIGNED_INT, "uint", 1, false },
   3727 		{ GL_UNSIGNED_INT_VEC2, "uvec2", 2, false },
   3728 		{ GL_UNSIGNED_INT_VEC3, "uvec3", 3, false },
   3729 		{ GL_UNSIGNED_INT_VEC4, "uvec4", 4, false },
   3730 		{ GL_FLOAT_MAT2, "mat2", 4, true },
   3731 		{ GL_FLOAT_MAT3, "mat3", 9, true },
   3732 		{ GL_FLOAT_MAT4, "mat4", 16, true }
   3733 	};
   3734 
   3735 const glw::GLuint gl3cts::TransformFeedback::CheckGetXFBVarying::s_varying_types_count =
   3736 	sizeof(s_varying_types) / sizeof(s_varying_types[0]);
   3737 
   3738 const glw::GLenum gl3cts::TransformFeedback::CheckGetXFBVarying::s_capture_ways[] = { GL_INTERLEAVED_ATTRIBS,
   3739 																					  GL_SEPARATE_ATTRIBS };
   3740 
   3741 const glw::GLuint gl3cts::TransformFeedback::CheckGetXFBVarying::s_capture_ways_count =
   3742 	sizeof(s_capture_ways) / sizeof(s_capture_ways[0]);
   3743 
   3744 /*-----------------------------------------------------------------------------------------------*/
   3745 
   3746 gl3cts::TransformFeedback::QueryVertexInterleaved::QueryVertexInterleaved(deqp::Context& context, const char* test_name,
   3747 																		  const char* test_description)
   3748 	: CaptureVertexInterleaved(context, test_name, test_description), m_query_object(0)
   3749 {
   3750 	m_max_vertices_drawn = 3; /* Make buffer smaller up to 3 vertices. */
   3751 }
   3752 
   3753 void gl3cts::TransformFeedback::QueryVertexInterleaved::createTransformFeedbackBuffer(void)
   3754 {
   3755 	/* Functions handler */
   3756 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3757 
   3758 	/* Create buffer object. */
   3759 	gl3cts::TransformFeedback::CaptureVertexInterleaved::createTransformFeedbackBuffer();
   3760 
   3761 	/* Create query object. */
   3762 	gl.genQueries(1, &m_query_object);
   3763 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenQueries call failed.");
   3764 }
   3765 
   3766 void gl3cts::TransformFeedback::QueryVertexInterleaved::draw(glw::GLuint primitive_case)
   3767 {
   3768 	/* Functions handler */
   3769 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3770 
   3771 	gl.beginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, m_query_object);
   3772 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginQuery call failed.");
   3773 
   3774 	gl3cts::TransformFeedback::CaptureVertexInterleaved::draw(primitive_case);
   3775 
   3776 	gl.endQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
   3777 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndQuery call failed.");
   3778 }
   3779 
   3780 bool gl3cts::TransformFeedback::QueryVertexInterleaved::checkTransformFeedbackBuffer(BindBufferCase bind_case UNUSED,
   3781 																					 glw::GLenum primitive_type)
   3782 {
   3783 	/* Functions handler */
   3784 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3785 
   3786 	glw::GLuint number_of_primitives;
   3787 
   3788 	gl.getQueryObjectuiv(m_query_object, GL_QUERY_RESULT, &number_of_primitives);
   3789 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryObjectuiv call failed.");
   3790 
   3791 	/* expected result */
   3792 	glw::GLuint number_of_primitives_reference = (primitive_type == GL_POINTS) ? 3 : 1; /* m_max_vertices_drawn == 3 */
   3793 
   3794 	if (number_of_primitives_reference != number_of_primitives)
   3795 	{
   3796 		return false;
   3797 	}
   3798 
   3799 	return true;
   3800 }
   3801 
   3802 void gl3cts::TransformFeedback::QueryVertexInterleaved::clean(void)
   3803 {
   3804 	/* Functions handler */
   3805 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3806 
   3807 	/* Delete query object. */
   3808 	gl.deleteQueries(1, &m_query_object);
   3809 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteQueries call failed.");
   3810 
   3811 	/* Other */
   3812 	gl3cts::TransformFeedback::CaptureVertexInterleaved::clean();
   3813 }
   3814 
   3815 /*-----------------------------------------------------------------------------------------------*/
   3816 
   3817 gl3cts::TransformFeedback::QueryGeometryInterleaved::QueryGeometryInterleaved(deqp::Context& context,
   3818 																			  const char*	test_name,
   3819 																			  const char*	test_description)
   3820 	: CaptureVertexInterleaved(context, test_name, test_description)
   3821 	, CaptureGeometryInterleaved(context, test_name, test_description)
   3822 {
   3823 	m_query_object		 = 0;
   3824 	m_max_vertices_drawn = 3; /* Make buffer smaller up to 3 vertices. */
   3825 }
   3826 
   3827 void gl3cts::TransformFeedback::QueryGeometryInterleaved::createTransformFeedbackBuffer(void)
   3828 {
   3829 	/* Functions handler */
   3830 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3831 
   3832 	/* Create buffer object. */
   3833 	gl3cts::TransformFeedback::CaptureGeometryInterleaved::createTransformFeedbackBuffer();
   3834 
   3835 	/* Create query object. */
   3836 	gl.genQueries(1, &m_query_object);
   3837 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenQueries call failed.");
   3838 }
   3839 
   3840 void gl3cts::TransformFeedback::QueryGeometryInterleaved::draw(glw::GLuint primitive_case)
   3841 {
   3842 	/* Functions handler */
   3843 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3844 
   3845 	gl.beginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, m_query_object);
   3846 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginQuery call failed.");
   3847 
   3848 	gl3cts::TransformFeedback::CaptureGeometryInterleaved::draw(primitive_case);
   3849 
   3850 	gl.endQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
   3851 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndQuery call failed.");
   3852 }
   3853 
   3854 bool gl3cts::TransformFeedback::QueryGeometryInterleaved::checkTransformFeedbackBuffer(BindBufferCase bind_case UNUSED,
   3855 																					   glw::GLenum primitive_type)
   3856 {
   3857 	/* Functions handler */
   3858 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3859 
   3860 	glw::GLuint number_of_primitives;
   3861 
   3862 	gl.getQueryObjectuiv(m_query_object, GL_QUERY_RESULT, &number_of_primitives);
   3863 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryObjectuiv call failed.");
   3864 
   3865 	/* expected result */
   3866 	glw::GLuint number_of_primitives_reference = (primitive_type == GL_POINTS) ? 3 : 1; /* m_max_vertices_drawn == 3 */
   3867 
   3868 	if (number_of_primitives_reference != number_of_primitives)
   3869 	{
   3870 		return false;
   3871 	}
   3872 
   3873 	return true;
   3874 }
   3875 
   3876 void gl3cts::TransformFeedback::QueryGeometryInterleaved::clean(void)
   3877 {
   3878 	/* Functions handler */
   3879 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3880 
   3881 	/* Delete query object. */
   3882 	gl.deleteQueries(1, &m_query_object);
   3883 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteQueries call failed.");
   3884 
   3885 	/* Other. */
   3886 	gl3cts::TransformFeedback::CaptureGeometryInterleaved::clean();
   3887 }
   3888 
   3889 /*-----------------------------------------------------------------------------------------------*/
   3890 
   3891 gl3cts::TransformFeedback::QueryVertexSeparate::QueryVertexSeparate(deqp::Context& context, const char* test_name,
   3892 																	const char* test_description)
   3893 	: CaptureVertexInterleaved(context, test_name, test_description)
   3894 	, CaptureVertexSeparate(context, test_name, test_description)
   3895 {
   3896 	m_query_object		 = 0;
   3897 	m_max_vertices_drawn = 3; /* Make buffer smaller up to 3 vertices. */
   3898 }
   3899 
   3900 void gl3cts::TransformFeedback::QueryVertexSeparate::createTransformFeedbackBuffer(void)
   3901 {
   3902 	/* Functions handler */
   3903 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3904 
   3905 	/* Create buffer object. */
   3906 	gl3cts::TransformFeedback::CaptureVertexSeparate::createTransformFeedbackBuffer();
   3907 
   3908 	/* Create query object. */
   3909 	gl.genQueries(1, &m_query_object);
   3910 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenQueries call failed.");
   3911 }
   3912 
   3913 void gl3cts::TransformFeedback::QueryVertexSeparate::draw(glw::GLuint primitive_case)
   3914 {
   3915 	/* Functions handler */
   3916 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3917 
   3918 	gl.beginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, m_query_object);
   3919 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginQuery call failed.");
   3920 
   3921 	gl3cts::TransformFeedback::CaptureVertexSeparate::draw(primitive_case);
   3922 
   3923 	gl.endQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
   3924 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndQuery call failed.");
   3925 }
   3926 
   3927 bool gl3cts::TransformFeedback::QueryVertexSeparate::checkTransformFeedbackBuffer(BindBufferCase bind_case UNUSED,
   3928 																				  glw::GLenum primitive_type)
   3929 {
   3930 	/* Functions handler */
   3931 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3932 
   3933 	glw::GLuint number_of_primitives;
   3934 
   3935 	gl.getQueryObjectuiv(m_query_object, GL_QUERY_RESULT, &number_of_primitives);
   3936 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryObjectuiv call failed.");
   3937 
   3938 	/* expected result */
   3939 	glw::GLuint number_of_primitives_reference = (primitive_type == GL_POINTS) ? 3 : 1; /* m_max_vertices_drawn == 3 */
   3940 
   3941 	if (number_of_primitives_reference != number_of_primitives)
   3942 	{
   3943 		return false;
   3944 	}
   3945 
   3946 	return true;
   3947 }
   3948 
   3949 void gl3cts::TransformFeedback::QueryVertexSeparate::clean(void)
   3950 {
   3951 	/* Functions handler */
   3952 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3953 
   3954 	/* Delete query object. */
   3955 	gl.deleteQueries(1, &m_query_object);
   3956 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteQueries call failed.");
   3957 
   3958 	/* Other */
   3959 	gl3cts::TransformFeedback::CaptureVertexSeparate::clean();
   3960 }
   3961 
   3962 /*-----------------------------------------------------------------------------------------------*/
   3963 
   3964 gl3cts::TransformFeedback::QueryGeometrySeparate::QueryGeometrySeparate(deqp::Context& context, const char* test_name,
   3965 																		const char* test_description)
   3966 	: CaptureVertexInterleaved(context, test_name, test_description)
   3967 	, CaptureVertexSeparate(context, test_name, test_description)
   3968 	, CaptureGeometrySeparate(context, test_name, test_description)
   3969 {
   3970 	m_query_object		 = 0;
   3971 	m_max_vertices_drawn = 3; /* Make buffer smaller up to 3 vertices. */
   3972 }
   3973 
   3974 void gl3cts::TransformFeedback::QueryGeometrySeparate::createTransformFeedbackBuffer(void)
   3975 {
   3976 	/* Functions handler */
   3977 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3978 
   3979 	/* Create buffer object. */
   3980 	gl3cts::TransformFeedback::CaptureGeometrySeparate::createTransformFeedbackBuffer();
   3981 
   3982 	/* Create query object. */
   3983 	gl.genQueries(1, &m_query_object);
   3984 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenQueries call failed.");
   3985 }
   3986 
   3987 void gl3cts::TransformFeedback::QueryGeometrySeparate::draw(glw::GLuint primitive_case)
   3988 {
   3989 	/* Functions handler */
   3990 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3991 
   3992 	gl.beginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, m_query_object);
   3993 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginQuery call failed.");
   3994 
   3995 	gl3cts::TransformFeedback::CaptureGeometrySeparate::draw(primitive_case);
   3996 
   3997 	gl.endQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
   3998 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndQuery call failed.");
   3999 }
   4000 
   4001 bool gl3cts::TransformFeedback::QueryGeometrySeparate::checkTransformFeedbackBuffer(BindBufferCase bind_case UNUSED,
   4002 																					glw::GLenum primitive_type)
   4003 {
   4004 	/* Functions handler */
   4005 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4006 
   4007 	glw::GLuint number_of_primitives;
   4008 
   4009 	gl.getQueryObjectuiv(m_query_object, GL_QUERY_RESULT, &number_of_primitives);
   4010 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryObjectuiv call failed.");
   4011 
   4012 	/* expected result */
   4013 	glw::GLuint number_of_primitives_reference = (primitive_type == GL_POINTS) ? 3 : 1; /* m_max_vertices_drawn == 3 */
   4014 
   4015 	if (number_of_primitives_reference != number_of_primitives)
   4016 	{
   4017 		return false;
   4018 	}
   4019 
   4020 	return true;
   4021 }
   4022 
   4023 void gl3cts::TransformFeedback::QueryGeometrySeparate::clean(void)
   4024 {
   4025 	/* Functions handler */
   4026 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4027 
   4028 	/* Delete query object. */
   4029 	gl.deleteQueries(1, &m_query_object);
   4030 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteQueries call failed.");
   4031 
   4032 	/* Other */
   4033 	gl3cts::TransformFeedback::CaptureGeometrySeparate::clean();
   4034 }
   4035 
   4036 /*-----------------------------------------------------------------------------------------------*/
   4037 
   4038 gl3cts::TransformFeedback::DiscardVertex::DiscardVertex(deqp::Context& context, const char* test_name,
   4039 														const char* test_description)
   4040 	: CaptureVertexInterleaved(context, test_name, test_description)
   4041 {
   4042 }
   4043 
   4044 void gl3cts::TransformFeedback::DiscardVertex::draw(glw::GLuint primitive_case)
   4045 {
   4046 	/* Functions handler */
   4047 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4048 
   4049 	/* Must clear before rasterizer discard */
   4050 	gl.clear(GL_COLOR_BUFFER_BIT);
   4051 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed.");
   4052 
   4053 	gl.enable(GL_RASTERIZER_DISCARD);
   4054 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable call failed.");
   4055 
   4056 	gl3cts::TransformFeedback::CaptureVertexInterleaved::draw(primitive_case);
   4057 
   4058 	gl.disable(GL_RASTERIZER_DISCARD);
   4059 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable call failed.");
   4060 }
   4061 
   4062 bool gl3cts::TransformFeedback::DiscardVertex::checkFramebuffer(glw::GLuint primitive_case UNUSED)
   4063 {
   4064 	/* Functions handler */
   4065 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4066 
   4067 	/* Fetch framebuffer. */
   4068 	std::vector<glw::GLfloat> pixels(s_framebuffer_size * s_framebuffer_size);
   4069 
   4070 	if ((s_framebuffer_size > 0) && (s_framebuffer_size > 0))
   4071 	{
   4072 		gl.readPixels(0, 0, s_framebuffer_size, s_framebuffer_size, GL_RED, GL_FLOAT, pixels.data());
   4073 		GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");
   4074 	}
   4075 
   4076 	/* Check results.
   4077 	 Note: assuming that s_buffer_size == 2 -> then all points shall be drawn. */
   4078 	for (std::vector<glw::GLfloat>::iterator i = pixels.begin(); i != pixels.end(); ++i)
   4079 	{
   4080 		if (fabs(*i) > 0.0625f /* precision */)
   4081 		{
   4082 			return false;
   4083 		}
   4084 	}
   4085 
   4086 	return true;
   4087 }
   4088 
   4089 /*-----------------------------------------------------------------------------------------------*/
   4090 
   4091 gl3cts::TransformFeedback::DiscardGeometry::DiscardGeometry(deqp::Context& context, const char* test_name,
   4092 															const char* test_description)
   4093 	: CaptureVertexInterleaved(context, test_name, test_description)
   4094 	, CaptureGeometryInterleaved(context, test_name, test_description)
   4095 {
   4096 }
   4097 
   4098 void gl3cts::TransformFeedback::DiscardGeometry::draw(glw::GLuint primitive_case)
   4099 {
   4100 	/* Functions handler */
   4101 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4102 
   4103 	/* Must clear before rasterizer discard */
   4104 	gl.clear(GL_COLOR_BUFFER_BIT);
   4105 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed.");
   4106 
   4107 	gl.enable(GL_RASTERIZER_DISCARD);
   4108 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable call failed.");
   4109 
   4110 	gl3cts::TransformFeedback::CaptureGeometryInterleaved::draw(primitive_case);
   4111 
   4112 	gl.disable(GL_RASTERIZER_DISCARD);
   4113 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable call failed.");
   4114 }
   4115 
   4116 bool gl3cts::TransformFeedback::DiscardGeometry::checkFramebuffer(glw::GLuint primitive_case UNUSED)
   4117 {
   4118 	/* Functions handler */
   4119 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4120 
   4121 	/* Fetch framebuffer. */
   4122 	std::vector<glw::GLfloat> pixels(s_framebuffer_size * s_framebuffer_size);
   4123 
   4124 	if ((s_framebuffer_size > 0) && (s_framebuffer_size > 0))
   4125 	{
   4126 		gl.readPixels(0, 0, s_framebuffer_size, s_framebuffer_size, GL_RED, GL_FLOAT, pixels.data());
   4127 		GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");
   4128 	}
   4129 
   4130 	/* Check results.
   4131 	 Note: assuming that s_buffer_size == 2 -> then all points shall be drawn. */
   4132 	for (std::vector<glw::GLfloat>::iterator i = pixels.begin(); i != pixels.end(); ++i)
   4133 	{
   4134 		if (fabs(*i) > 0.0625f /* precision */)
   4135 		{
   4136 			return false;
   4137 		}
   4138 	}
   4139 
   4140 	return true;
   4141 }
   4142 
   4143 /*-----------------------------------------------------------------------------------------------*/
   4144 
   4145 gl3cts::TransformFeedback::DrawXFB::DrawXFB(deqp::Context& context, const char* test_name, const char* test_description)
   4146 	: deqp::TestCase(context, test_name, test_description)
   4147 	, m_context(context)
   4148 	, m_program_id_xfb(0)
   4149 	, m_program_id_draw(0)
   4150 	, m_fbo_id(0)
   4151 	, m_rbo_id(0)
   4152 	, m_vao_id(0)
   4153 {
   4154 	memset(m_xfb_id, 0, sizeof(m_xfb_id));
   4155 	memset(m_bo_id, 0, sizeof(m_bo_id));
   4156 }
   4157 
   4158 gl3cts::TransformFeedback::DrawXFB::~DrawXFB(void)
   4159 {
   4160 }
   4161 
   4162 tcu::TestNode::IterateResult gl3cts::TransformFeedback::DrawXFB::iterate(void)
   4163 {
   4164 	/* Initializations. */
   4165 	bool is_at_least_gl_40 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 0)));
   4166 	bool is_arb_tf_2	   = m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback2");
   4167 
   4168 	bool is_ok		= true;
   4169 	bool test_error = false;
   4170 
   4171 	/* Tests. */
   4172 	try
   4173 	{
   4174 		if (is_at_least_gl_40 || is_arb_tf_2)
   4175 		{
   4176 			for (glw::GLuint i = 0; (i < s_capture_modes_count) && is_ok; ++i)
   4177 			{
   4178 				prepare(s_capture_modes[i]);
   4179 
   4180 				bindVAO(m_vao_id);
   4181 				useProgram(m_program_id_xfb);
   4182 
   4183 				for (glw::GLuint j = 0; (j < s_xfb_count) && is_ok; ++j)
   4184 				{
   4185 					bindXFB(m_xfb_id[j]);
   4186 					bindBOForXFB(s_capture_modes[i], m_bo_id[j]);
   4187 					useColour(m_program_id_xfb, s_colours[j][0], s_colours[j][1], s_colours[j][2], s_colours[j][3]);
   4188 					useGeometrySet(m_program_id_xfb, false);
   4189 					drawForCapture(true, true, false, false);
   4190 
   4191 					is_ok = is_ok && inspectXFBState(true, true);
   4192 				}
   4193 
   4194 				for (glw::GLuint j = 0; (j < s_xfb_count) && is_ok; ++j)
   4195 				{
   4196 					bindXFB(m_xfb_id[j]);
   4197 					useColour(m_program_id_xfb, s_colours[j][0], s_colours[j][1], s_colours[j][2], s_colours[j][3]);
   4198 					useGeometrySet(m_program_id_xfb, true);
   4199 					drawForCapture(false, false, true, true);
   4200 
   4201 					is_ok = is_ok && inspectXFBState(false, false);
   4202 				}
   4203 
   4204 				useProgram(m_program_id_draw);
   4205 
   4206 				for (glw::GLuint j = 0; (j < s_xfb_count) && is_ok; ++j)
   4207 				{
   4208 					bindXFB(m_xfb_id[j]);
   4209 					bindBOForDraw(m_program_id_draw, s_capture_modes[i], m_bo_id[j]);
   4210 					drawToFramebuffer(m_xfb_id[j]);
   4211 
   4212 					is_ok =
   4213 						is_ok && checkFramebuffer(s_colours[j][0], s_colours[j][1], s_colours[j][2], s_colours[j][3]);
   4214 				}
   4215 
   4216 				clean();
   4217 			}
   4218 		}
   4219 	}
   4220 	catch (...)
   4221 	{
   4222 		is_ok	  = false;
   4223 		test_error = true;
   4224 		clean();
   4225 	}
   4226 
   4227 	/* Result's setup. */
   4228 	if (is_ok)
   4229 	{
   4230 		/* Log success. */
   4231 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB have passed."
   4232 											<< tcu::TestLog::EndMessage;
   4233 
   4234 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   4235 	}
   4236 	else
   4237 	{
   4238 		if (test_error)
   4239 		{
   4240 			/* Log error. */
   4241 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB have approached error."
   4242 												<< tcu::TestLog::EndMessage;
   4243 
   4244 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   4245 		}
   4246 		else
   4247 		{
   4248 			/* Log fail. */
   4249 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB have failed."
   4250 												<< tcu::TestLog::EndMessage;
   4251 
   4252 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   4253 		}
   4254 	}
   4255 
   4256 	return STOP;
   4257 }
   4258 
   4259 void gl3cts::TransformFeedback::DrawXFB::prepare(glw::GLenum capture_mode)
   4260 {
   4261 	/* Functions handler */
   4262 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4263 
   4264 	/* Prepare programs. */
   4265 	m_program_id_xfb = gl3cts::TransformFeedback::Utilities::buildProgram(
   4266 		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, s_vertex_shader_xfb, s_fragment_shader,
   4267 		s_xfb_varyings, s_xfb_varyings_count, capture_mode);
   4268 
   4269 	if (0 == m_program_id_xfb)
   4270 	{
   4271 		throw 0;
   4272 	}
   4273 
   4274 	m_program_id_draw = gl3cts::TransformFeedback::Utilities::buildProgram(gl, m_context.getTestContext().getLog(),
   4275 																		   NULL, NULL, NULL, s_vertex_shader_draw,
   4276 																		   s_fragment_shader, NULL, 0, capture_mode);
   4277 
   4278 	if (0 == m_program_id_draw)
   4279 	{
   4280 		throw 0;
   4281 	}
   4282 
   4283 	/* Prepare transform feedbacks. */
   4284 	gl.genTransformFeedbacks(s_xfb_count, m_xfb_id);
   4285 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTransformFeedbacks call failed.");
   4286 
   4287 	/* Prepare buffer objects. */
   4288 	gl.genBuffers(s_xfb_count, m_bo_id);
   4289 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   4290 
   4291 	for (glw::GLuint i = 0; i < s_xfb_count; ++i)
   4292 	{
   4293 		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id[i]);
   4294 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   4295 
   4296 		gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, s_capture_size, NULL, GL_DYNAMIC_COPY);
   4297 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
   4298 	}
   4299 
   4300 	/* Prepare framebuffer. */
   4301 	gl.clearColor(0.f, 0.f, 0.f, 1.f);
   4302 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");
   4303 
   4304 	gl.genFramebuffers(1, &m_fbo_id);
   4305 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
   4306 
   4307 	gl.genRenderbuffers(1, &m_rbo_id);
   4308 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
   4309 
   4310 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id);
   4311 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
   4312 
   4313 	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_id);
   4314 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
   4315 
   4316 	gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, s_view_size, s_view_size);
   4317 	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed.");
   4318 
   4319 	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo_id);
   4320 	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed.");
   4321 
   4322 	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
   4323 	{
   4324 		throw 0;
   4325 	}
   4326 
   4327 	gl.viewport(0, 0, s_view_size, s_view_size);
   4328 	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
   4329 
   4330 	/* Create empty Vertex Array Object */
   4331 	gl.genVertexArrays(1, &m_vao_id);
   4332 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
   4333 }
   4334 
   4335 void gl3cts::TransformFeedback::DrawXFB::bindXFB(glw::GLuint xfb_id)
   4336 {
   4337 	/* Functions handler */
   4338 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4339 
   4340 	gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, xfb_id);
   4341 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedback call failed.");
   4342 }
   4343 
   4344 void gl3cts::TransformFeedback::DrawXFB::bindVAO(glw::GLuint vao_id)
   4345 {
   4346 	/* Functions handler */
   4347 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4348 
   4349 	gl.bindVertexArray(vao_id);
   4350 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   4351 }
   4352 
   4353 void gl3cts::TransformFeedback::DrawXFB::bindBOForXFB(glw::GLenum capture_mode, glw::GLuint bo_id)
   4354 {
   4355 	/* Functions handler */
   4356 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4357 
   4358 	switch (capture_mode)
   4359 	{
   4360 	case GL_INTERLEAVED_ATTRIBS:
   4361 		gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, bo_id);
   4362 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed.");
   4363 		break;
   4364 	case GL_SEPARATE_ATTRIBS:
   4365 		for (glw::GLuint i = 0; i < s_xfb_varyings_count; ++i)
   4366 		{
   4367 			gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, i, bo_id, i * s_capture_size / s_xfb_varyings_count,
   4368 							   (i + 1) * s_capture_size / s_xfb_varyings_count);
   4369 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed.");
   4370 		}
   4371 		break;
   4372 	default:
   4373 		throw 0;
   4374 	};
   4375 }
   4376 
   4377 void gl3cts::TransformFeedback::DrawXFB::bindBOForDraw(glw::GLuint program_id, glw::GLenum capture_mode,
   4378 													   glw::GLuint bo_id)
   4379 {
   4380 	/* Functions handler */
   4381 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4382 
   4383 	gl.bindBuffer(GL_ARRAY_BUFFER, bo_id);
   4384 
   4385 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   4386 
   4387 	glw::GLuint position_location = gl.getAttribLocation(program_id, "position");
   4388 	glw::GLuint color_location	= gl.getAttribLocation(program_id, "color");
   4389 
   4390 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation call failed.");
   4391 
   4392 	glw::GLvoid* color_offset = (capture_mode == GL_INTERLEAVED_ATTRIBS) ?
   4393 									(glw::GLvoid*)(4 /* components */ * sizeof(glw::GLfloat)) :
   4394 									(glw::GLvoid*)(4 /* components */ * 6 /* vertices */ * sizeof(glw::GLfloat));
   4395 
   4396 	glw::GLuint stride =
   4397 		static_cast<glw::GLuint>((capture_mode == GL_INTERLEAVED_ATTRIBS) ?
   4398 									 (4 /* components */ * 2 /* position and color */ * sizeof(glw::GLfloat)) :
   4399 									 (4 /* components */ * sizeof(glw::GLfloat)));
   4400 
   4401 	gl.vertexAttribPointer(position_location, 4, GL_FLOAT, GL_FALSE, stride, NULL);
   4402 	gl.vertexAttribPointer(color_location, 4, GL_FLOAT, GL_FALSE, stride, color_offset);
   4403 
   4404 	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed.");
   4405 
   4406 	gl.enableVertexAttribArray(position_location);
   4407 	gl.enableVertexAttribArray(color_location);
   4408 
   4409 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
   4410 }
   4411 
   4412 void gl3cts::TransformFeedback::DrawXFB::useProgram(glw::GLuint program_id)
   4413 {
   4414 	/* Functions handler */
   4415 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4416 
   4417 	gl.useProgram(program_id);
   4418 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
   4419 }
   4420 
   4421 void gl3cts::TransformFeedback::DrawXFB::useColour(glw::GLuint program_id, glw::GLfloat r, glw::GLfloat g,
   4422 												   glw::GLfloat b, glw::GLfloat a)
   4423 {
   4424 	/* Functions handler */
   4425 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4426 
   4427 	glw::GLint location = gl.getUniformLocation(program_id, "color");
   4428 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation call failed.");
   4429 
   4430 	gl.uniform4f(location, r, g, b, a);
   4431 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform4f call failed.");
   4432 }
   4433 
   4434 void gl3cts::TransformFeedback::DrawXFB::useGeometrySet(glw::GLuint program_id, bool invert_sign)
   4435 {
   4436 	/* Functions handler */
   4437 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4438 
   4439 	glw::GLint location = gl.getUniformLocation(program_id, "invert_sign");
   4440 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation call failed.");
   4441 
   4442 	gl.uniform1f(location, invert_sign ? -1.f : 1.f);
   4443 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform4f call failed.");
   4444 }
   4445 
   4446 void gl3cts::TransformFeedback::DrawXFB::clean()
   4447 {
   4448 	/* Functions handler */
   4449 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4450 
   4451 	gl.useProgram(0);
   4452 
   4453 	if (m_program_id_xfb)
   4454 	{
   4455 		gl.deleteProgram(m_program_id_xfb);
   4456 
   4457 		m_program_id_xfb = 0;
   4458 	}
   4459 
   4460 	if (m_program_id_draw)
   4461 	{
   4462 		gl.deleteProgram(m_program_id_draw);
   4463 
   4464 		m_program_id_draw = 1;
   4465 	}
   4466 
   4467 	for (glw::GLuint i = 0; i < s_xfb_count; ++i)
   4468 	{
   4469 		if (m_xfb_id[i])
   4470 		{
   4471 			gl.deleteTransformFeedbacks(1, &m_xfb_id[i]);
   4472 
   4473 			m_xfb_id[i] = 0;
   4474 		}
   4475 	}
   4476 
   4477 	for (glw::GLuint i = 0; i < s_xfb_count; ++i)
   4478 	{
   4479 		if (m_bo_id[i])
   4480 		{
   4481 			gl.deleteBuffers(1, &m_bo_id[i]);
   4482 
   4483 			m_bo_id[i] = 0;
   4484 		}
   4485 	}
   4486 
   4487 	if (m_vao_id)
   4488 	{
   4489 		gl.deleteVertexArrays(1, &m_vao_id);
   4490 
   4491 		m_vao_id = 0;
   4492 	}
   4493 
   4494 	if (m_fbo_id)
   4495 	{
   4496 		gl.deleteFramebuffers(1, &m_fbo_id);
   4497 
   4498 		m_fbo_id = 0;
   4499 	}
   4500 
   4501 	if (m_rbo_id)
   4502 	{
   4503 		gl.deleteRenderbuffers(1, &m_rbo_id);
   4504 
   4505 		m_rbo_id = 0;
   4506 	}
   4507 }
   4508 
   4509 void gl3cts::TransformFeedback::DrawXFB::drawForCapture(bool begin_xfb, bool pause_xfb, bool resume_xfb, bool end_xfb)
   4510 {
   4511 	/* Functions handler */
   4512 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4513 
   4514 	gl.enable(GL_RASTERIZER_DISCARD);
   4515 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable call failed.");
   4516 
   4517 	if (begin_xfb)
   4518 	{
   4519 		gl.beginTransformFeedback(GL_POINTS);
   4520 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
   4521 	}
   4522 
   4523 	if (resume_xfb)
   4524 	{
   4525 		gl.resumeTransformFeedback();
   4526 		GLU_EXPECT_NO_ERROR(gl.getError(), "glResumeTransformFeedback call failed.");
   4527 	}
   4528 
   4529 	gl.drawArrays(GL_POINTS, 0, 3);
   4530 
   4531 	if (pause_xfb)
   4532 	{
   4533 		gl.pauseTransformFeedback();
   4534 		GLU_EXPECT_NO_ERROR(gl.getError(), "glPauseTransformFeedback call failed.");
   4535 	}
   4536 
   4537 	if (end_xfb)
   4538 	{
   4539 		gl.endTransformFeedback();
   4540 		GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
   4541 	}
   4542 
   4543 	gl.disable(GL_RASTERIZER_DISCARD);
   4544 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable call failed.");
   4545 }
   4546 
   4547 void gl3cts::TransformFeedback::DrawXFB::drawToFramebuffer(glw::GLuint xfb_id)
   4548 {
   4549 	/* Functions handler */
   4550 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4551 
   4552 	gl.clearColor(0.f, 0.f, 0.f, 0.f);
   4553 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");
   4554 
   4555 	gl.clear(GL_COLOR_BUFFER_BIT);
   4556 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed.");
   4557 
   4558 	gl.drawTransformFeedback(GL_TRIANGLES, xfb_id);
   4559 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawTransformFeedback call failed.");
   4560 }
   4561 
   4562 bool gl3cts::TransformFeedback::DrawXFB::checkFramebuffer(glw::GLfloat r, glw::GLfloat g, glw::GLfloat b,
   4563 														  glw::GLfloat a)
   4564 {
   4565 	/* Functions handler */
   4566 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4567 
   4568 	/* Number of pixels. */
   4569 	const glw::GLuint number_of_pixels = s_view_size * s_view_size;
   4570 
   4571 	/* Fetch framebuffer. */
   4572 	std::vector<glw::GLubyte> pixels(number_of_pixels * 4 /* components */);
   4573 
   4574 	if ((s_view_size > 0) && (s_view_size > 0))
   4575 	{
   4576 		gl.readPixels(0, 0, s_view_size, s_view_size, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
   4577 		GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");
   4578 	}
   4579 
   4580 	/* Convert color to integer. */
   4581 	glw::GLubyte ir = (glw::GLubyte)(255.f * r);
   4582 	glw::GLubyte ig = (glw::GLubyte)(255.f * g);
   4583 	glw::GLubyte ib = (glw::GLubyte)(255.f * b);
   4584 	glw::GLubyte ia = (glw::GLubyte)(255.f * a);
   4585 
   4586 	/* Check results. */
   4587 	for (glw::GLuint i = 0; i < number_of_pixels; ++i)
   4588 	{
   4589 		if ((pixels[i * 4 /* components */] != ir) || (pixels[i * 4 /* components */ + 1] != ig) ||
   4590 			(pixels[i * 4 /* components */ + 2] != ib) || (pixels[i * 4 /* components */ + 3] != ia))
   4591 		{
   4592 			return false;
   4593 		}
   4594 	}
   4595 
   4596 	return true;
   4597 }
   4598 
   4599 bool gl3cts::TransformFeedback::DrawXFB::inspectXFBState(bool shall_be_paused, bool shall_be_active)
   4600 {
   4601 	/* Functions handler */
   4602 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4603 
   4604 	glw::GLint is_paused = 0;
   4605 	glw::GLint is_active = 0;
   4606 
   4607 	gl.getIntegerv(GL_TRANSFORM_FEEDBACK_PAUSED, &is_paused);
   4608 	gl.getIntegerv(GL_TRANSFORM_FEEDBACK_ACTIVE, &is_active);
   4609 
   4610 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   4611 
   4612 	if ((is_paused == -1) || (is_active == -1))
   4613 	{
   4614 		throw 0;
   4615 	}
   4616 
   4617 	if (shall_be_paused ^ (is_paused == GL_TRUE))
   4618 	{
   4619 		return false;
   4620 	}
   4621 
   4622 	if (shall_be_active ^ (is_active == GL_TRUE))
   4623 	{
   4624 		return false;
   4625 	}
   4626 
   4627 	return true;
   4628 }
   4629 
   4630 const glw::GLchar* gl3cts::TransformFeedback::DrawXFB::s_vertex_shader_xfb =
   4631 	"#version 130\n"
   4632 	"\n"
   4633 	"uniform vec4 color;\n"
   4634 	"uniform float invert_sign;\n"
   4635 	"out     vec4 colour;\n"
   4636 	"\n"
   4637 	"void main()\n"
   4638 	"{\n"
   4639 	"    switch(gl_VertexID)\n"
   4640 	"    {\n"
   4641 	"        case 0:\n"
   4642 	"            gl_Position = vec4(-1.0,               -1.0,              0.0,  1.0);\n"
   4643 	"        break;\n"
   4644 	"        case 1:\n"
   4645 	"            gl_Position = vec4(-1.0 * invert_sign,  1.0,              0.0,  1.0);\n"
   4646 	"        break;\n"
   4647 	"        case 2:\n"
   4648 	"            gl_Position = vec4( 1.0,                1.0 * invert_sign, 0.0,  1.0);\n"
   4649 	"        break;\n"
   4650 	"    }\n"
   4651 	"\n"
   4652 	"    colour = color;\n"
   4653 	"}\n";
   4654 
   4655 const glw::GLchar* gl3cts::TransformFeedback::DrawXFB::s_vertex_shader_draw = "#version 130\n"
   4656 																			  "\n"
   4657 																			  "in  vec4 color;\n"
   4658 																			  "in  vec4 position;\n"
   4659 																			  "out vec4 colour;\n"
   4660 																			  "\n"
   4661 																			  "void main()\n"
   4662 																			  "{\n"
   4663 																			  "    gl_Position = position;\n"
   4664 																			  "    colour      = color;\n"
   4665 																			  "}\n";
   4666 
   4667 const glw::GLchar* gl3cts::TransformFeedback::DrawXFB::s_fragment_shader = "#version 130\n"
   4668 																		   "\n"
   4669 																		   "in  vec4 colour;\n"
   4670 																		   "out vec4 pixel;\n"
   4671 																		   "\n"
   4672 																		   "void main()\n"
   4673 																		   "{\n"
   4674 																		   "    pixel = colour;\n"
   4675 																		   "}\n";
   4676 
   4677 const glw::GLchar* gl3cts::TransformFeedback::DrawXFB::s_xfb_varyings[s_xfb_varyings_count] = { "gl_Position",
   4678 																								"colour" };
   4679 
   4680 const glw::GLenum gl3cts::TransformFeedback::DrawXFB::s_capture_modes[] = { GL_INTERLEAVED_ATTRIBS,
   4681 																			GL_SEPARATE_ATTRIBS };
   4682 const glw::GLuint gl3cts::TransformFeedback::DrawXFB::s_capture_modes_count =
   4683 	sizeof(s_capture_modes) / sizeof(s_capture_modes[0]);
   4684 
   4685 const glw::GLfloat gl3cts::TransformFeedback::DrawXFB::s_colours[s_xfb_count][4] = { { 1.f, 0.f, 0.f, 1.f },
   4686 																					 { 0.f, 1.f, 0.f, 1.f },
   4687 																					 { 0.f, 0.f, 1.f, 1.f } };
   4688 
   4689 /*-----------------------------------------------------------------------------------------------*/
   4690 
   4691 gl3cts::TransformFeedback::DrawXFBFeedback::DrawXFBFeedback(deqp::Context& context, const char* test_name,
   4692 															const char* test_description)
   4693 	: deqp::TestCase(context, test_name, test_description)
   4694 	, m_context(context)
   4695 	, m_program_id(0)
   4696 	, m_xfb_id(0)
   4697 	, m_source_bo_index(0)
   4698 {
   4699 	memset(m_bo_id, 1, sizeof(m_bo_id));
   4700 	memset(m_bo_id, 1, sizeof(m_vao_id));
   4701 }
   4702 
   4703 gl3cts::TransformFeedback::DrawXFBFeedback::~DrawXFBFeedback(void)
   4704 {
   4705 }
   4706 
   4707 tcu::TestNode::IterateResult gl3cts::TransformFeedback::DrawXFBFeedback::iterate(void)
   4708 {
   4709 	/* Initializations. */
   4710 	bool is_at_least_gl_40 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 0)));
   4711 	bool is_arb_tf_2	   = m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback2");
   4712 
   4713 	bool is_ok		= true;
   4714 	bool test_error = false;
   4715 
   4716 	/* Tests. */
   4717 	try
   4718 	{
   4719 		if (is_at_least_gl_40 || is_arb_tf_2)
   4720 		{
   4721 			prepareAndBind();
   4722 			draw(true);
   4723 			swapBuffers();
   4724 			draw(false);
   4725 			swapBuffers();
   4726 			draw(false);
   4727 
   4728 			is_ok = is_ok && check();
   4729 		}
   4730 	}
   4731 	catch (...)
   4732 	{
   4733 		is_ok	  = false;
   4734 		test_error = true;
   4735 	}
   4736 
   4737 	/* Clean GL objects. */
   4738 	clean();
   4739 
   4740 	/* Result's setup. */
   4741 	if (is_ok)
   4742 	{
   4743 		/* Log success. */
   4744 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB Feedback have passed."
   4745 											<< tcu::TestLog::EndMessage;
   4746 
   4747 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   4748 	}
   4749 	else
   4750 	{
   4751 		if (test_error)
   4752 		{
   4753 			/* Log error. */
   4754 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB Feedback have approached error."
   4755 												<< tcu::TestLog::EndMessage;
   4756 
   4757 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   4758 		}
   4759 		else
   4760 		{
   4761 			/* Log fail. */
   4762 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB Feedback have failed."
   4763 												<< tcu::TestLog::EndMessage;
   4764 
   4765 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   4766 		}
   4767 	}
   4768 
   4769 	return STOP;
   4770 }
   4771 
   4772 void gl3cts::TransformFeedback::DrawXFBFeedback::prepareAndBind()
   4773 {
   4774 	/* Functions handler */
   4775 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4776 
   4777 	/* Prepare programs. */
   4778 	m_program_id = gl3cts::TransformFeedback::Utilities::buildProgram(gl, m_context.getTestContext().getLog(), NULL,
   4779 																	  NULL, NULL, s_vertex_shader, s_fragment_shader,
   4780 																	  &s_xfb_varying, 1, GL_INTERLEAVED_ATTRIBS);
   4781 
   4782 	if (0 == m_program_id)
   4783 	{
   4784 		throw 0;
   4785 	}
   4786 
   4787 	gl.useProgram(m_program_id);
   4788 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
   4789 
   4790 	/* Prepare transform feedbacks. */
   4791 	gl.genTransformFeedbacks(1, &m_xfb_id);
   4792 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTransformFeedbacks call failed.");
   4793 
   4794 	gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_xfb_id);
   4795 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedbacks call failed.");
   4796 
   4797 	/* Prepare buffer objects. */
   4798 	gl.genBuffers(s_bo_count, m_bo_id);
   4799 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   4800 
   4801 	gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id[0]);
   4802 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   4803 
   4804 	gl.bufferData(GL_ARRAY_BUFFER, s_bo_size, s_initial_data, GL_DYNAMIC_COPY);
   4805 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
   4806 
   4807 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_id[1]);
   4808 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   4809 
   4810 	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, s_bo_size, NULL, GL_DYNAMIC_COPY);
   4811 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
   4812 
   4813 	/* Setup vertex arrays. */
   4814 	gl.genVertexArrays(s_bo_count, m_vao_id);
   4815 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
   4816 
   4817 	glw::GLuint position_location = gl.getAttribLocation(m_program_id, "position");
   4818 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation call failed.");
   4819 
   4820 	for (glw::GLuint i = 0; i < 2; ++i)
   4821 	{
   4822 		gl.bindVertexArray(m_vao_id[i]);
   4823 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   4824 
   4825 		gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id[i]);
   4826 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   4827 
   4828 		gl.vertexAttribPointer(position_location, 4, GL_FLOAT, GL_FALSE, 0, NULL);
   4829 		GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed.");
   4830 
   4831 		gl.enableVertexAttribArray(position_location);
   4832 		GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
   4833 	}
   4834 
   4835 	gl.bindBuffer(GL_ARRAY_BUFFER, 0);
   4836 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   4837 
   4838 	gl.bindVertexArray(m_vao_id[0]);
   4839 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   4840 }
   4841 
   4842 void gl3cts::TransformFeedback::DrawXFBFeedback::swapBuffers()
   4843 {
   4844 	/* Functions handler */
   4845 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4846 
   4847 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_id[m_source_bo_index]);
   4848 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   4849 
   4850 	m_source_bo_index = (m_source_bo_index + 1) % 2;
   4851 
   4852 	gl.bindVertexArray(m_vao_id[(m_source_bo_index)]);
   4853 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   4854 }
   4855 
   4856 void gl3cts::TransformFeedback::DrawXFBFeedback::draw(bool is_first_draw)
   4857 {
   4858 	/* Functions handler */
   4859 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4860 
   4861 	gl.enable(GL_RASTERIZER_DISCARD);
   4862 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable call failed.");
   4863 
   4864 	gl.beginTransformFeedback(GL_POINTS);
   4865 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
   4866 
   4867 	if (is_first_draw)
   4868 	{
   4869 		gl.drawArrays(GL_POINTS, 0, 1);
   4870 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
   4871 	}
   4872 	else
   4873 	{
   4874 		gl.drawTransformFeedback(GL_POINTS, m_xfb_id);
   4875 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawTransformFeedback call failed.");
   4876 	}
   4877 
   4878 	gl.endTransformFeedback();
   4879 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
   4880 
   4881 	gl.disable(GL_RASTERIZER_DISCARD);
   4882 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable call failed.");
   4883 }
   4884 
   4885 bool gl3cts::TransformFeedback::DrawXFBFeedback::check()
   4886 {
   4887 	/* Functions handler */
   4888 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4889 
   4890 	glw::GLfloat* results =
   4891 		(glw::GLfloat*)gl.mapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, s_bo_size, GL_MAP_READ_BIT);
   4892 	GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange call failed.");
   4893 
   4894 	bool is_ok = false;
   4895 
   4896 	if (results)
   4897 	{
   4898 		if ((results[0] == 8.f) && (results[1] == 16.f) && (results[2] == 24.f) && (results[3] == 32.f))
   4899 		{
   4900 			is_ok = true;
   4901 		}
   4902 
   4903 		gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   4904 		GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");
   4905 	}
   4906 
   4907 	return is_ok;
   4908 }
   4909 
   4910 void gl3cts::TransformFeedback::DrawXFBFeedback::clean()
   4911 {
   4912 	/* Functions handler */
   4913 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4914 
   4915 	gl.useProgram(0);
   4916 
   4917 	if (m_program_id)
   4918 	{
   4919 		gl.deleteProgram(m_program_id);
   4920 
   4921 		m_program_id = 0;
   4922 	}
   4923 
   4924 	if (m_xfb_id)
   4925 	{
   4926 		gl.deleteTransformFeedbacks(1, &m_xfb_id);
   4927 
   4928 		m_xfb_id = 0;
   4929 	}
   4930 
   4931 	for (glw::GLuint i = 0; i < s_bo_count; ++i)
   4932 	{
   4933 		if (m_bo_id[i])
   4934 		{
   4935 			gl.deleteBuffers(1, &m_bo_id[i]);
   4936 
   4937 			m_bo_id[i] = 0;
   4938 		}
   4939 	}
   4940 
   4941 	for (glw::GLuint i = 0; i < s_bo_count; ++i)
   4942 	{
   4943 		if (m_vao_id[i])
   4944 		{
   4945 			gl.deleteVertexArrays(1, &m_vao_id[i]);
   4946 
   4947 			m_vao_id[i] = 0;
   4948 		}
   4949 	}
   4950 }
   4951 
   4952 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBFeedback::s_vertex_shader = "#version 130\n"
   4953 																				 "\n"
   4954 																				 "in  vec4 position;\n"
   4955 																				 "\n"
   4956 																				 "void main()\n"
   4957 																				 "{\n"
   4958 																				 "    gl_Position = position * 2.0;\n"
   4959 																				 "}\n";
   4960 
   4961 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBFeedback::s_fragment_shader = "#version 130\n"
   4962 																				   "\n"
   4963 																				   "out vec4 pixel;\n"
   4964 																				   "\n"
   4965 																				   "void main()\n"
   4966 																				   "{\n"
   4967 																				   "    pixel = vec4(1.0);\n"
   4968 																				   "}\n";
   4969 
   4970 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBFeedback::s_xfb_varying = "gl_Position";
   4971 
   4972 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBFeedback::s_attrib = "position";
   4973 
   4974 const glw::GLfloat gl3cts::TransformFeedback::DrawXFBFeedback::s_initial_data[] = { 1.f, 2.f, 3.f, 4.f };
   4975 
   4976 const glw::GLuint gl3cts::TransformFeedback::DrawXFBFeedback::s_draw_vertex_count =
   4977 	sizeof(s_initial_data) / sizeof(s_initial_data[0]) / 4 /* components */;
   4978 
   4979 const glw::GLuint gl3cts::TransformFeedback::DrawXFBFeedback::s_bo_size = sizeof(s_initial_data);
   4980 
   4981 /*-----------------------------------------------------------------------------------------------*/
   4982 
   4983 gl3cts::TransformFeedback::CaptureSpecialInterleaved::CaptureSpecialInterleaved(deqp::Context& context,
   4984 																				const char*	test_name,
   4985 																				const char*	test_description)
   4986 	: deqp::TestCase(context, test_name, test_description)
   4987 	, m_context(context)
   4988 	, m_program_id(0)
   4989 	, m_vao_id(0)
   4990 	, m_xfb_id(0)
   4991 {
   4992 	memset(m_bo_id, 0, sizeof(m_bo_id));
   4993 }
   4994 
   4995 gl3cts::TransformFeedback::CaptureSpecialInterleaved::~CaptureSpecialInterleaved(void)
   4996 {
   4997 }
   4998 
   4999 tcu::TestNode::IterateResult gl3cts::TransformFeedback::CaptureSpecialInterleaved::iterate(void)
   5000 {
   5001 	/* Initializations. */
   5002 	bool is_at_least_gl_40 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 0)));
   5003 	bool is_arb_tf_3	   = m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback3");
   5004 
   5005 	bool is_ok		= true;
   5006 	bool test_error = false;
   5007 
   5008 	/* Tests. */
   5009 	try
   5010 	{
   5011 		if (is_at_least_gl_40 || is_arb_tf_3)
   5012 		{
   5013 			prepareAndBind();
   5014 			draw();
   5015 
   5016 			is_ok = is_ok && check();
   5017 		}
   5018 	}
   5019 	catch (...)
   5020 	{
   5021 		is_ok	  = false;
   5022 		test_error = true;
   5023 	}
   5024 
   5025 	/* Clean GL objects. */
   5026 	clean();
   5027 
   5028 	/* Result's setup. */
   5029 	if (is_ok)
   5030 	{
   5031 		/* Log success. */
   5032 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Capture Special Interleaved have passed."
   5033 											<< tcu::TestLog::EndMessage;
   5034 
   5035 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   5036 	}
   5037 	else
   5038 	{
   5039 		if (test_error)
   5040 		{
   5041 			/* Log error. */
   5042 			m_context.getTestContext().getLog() << tcu::TestLog::Message
   5043 												<< "Capture Special Interleaved have approached error."
   5044 												<< tcu::TestLog::EndMessage;
   5045 
   5046 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   5047 		}
   5048 		else
   5049 		{
   5050 			/* Log fail. */
   5051 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Capture Special Interleaved have failed."
   5052 												<< tcu::TestLog::EndMessage;
   5053 
   5054 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   5055 		}
   5056 	}
   5057 
   5058 	return STOP;
   5059 }
   5060 
   5061 void gl3cts::TransformFeedback::CaptureSpecialInterleaved::prepareAndBind()
   5062 {
   5063 	/* Functions handler */
   5064 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5065 
   5066 	/* Prepare programs. */
   5067 	m_program_id = gl3cts::TransformFeedback::Utilities::buildProgram(
   5068 		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, s_vertex_shader, s_fragment_shader, s_xfb_varyings,
   5069 		s_xfb_varyings_count, GL_INTERLEAVED_ATTRIBS);
   5070 
   5071 	if (0 == m_program_id)
   5072 	{
   5073 		throw 0;
   5074 	}
   5075 
   5076 	gl.useProgram(m_program_id);
   5077 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
   5078 
   5079 	/* Prepare transform feedbacks. */
   5080 	gl.genTransformFeedbacks(1, &m_xfb_id);
   5081 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTransformFeedbacks call failed.");
   5082 
   5083 	gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_xfb_id);
   5084 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedbacks call failed.");
   5085 
   5086 	/* Create empty Vertex Array Object */
   5087 	gl.genVertexArrays(1, &m_vao_id);
   5088 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
   5089 
   5090 	gl.bindVertexArray(m_vao_id);
   5091 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   5092 
   5093 	/* Prepare buffer objects. */
   5094 	gl.genBuffers(s_bo_ids_count, m_bo_id);
   5095 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   5096 
   5097 	for (glw::GLuint i = 0; i < s_bo_ids_count; ++i)
   5098 	{
   5099 		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id[i]);
   5100 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   5101 
   5102 		gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, s_bo_size, NULL, GL_DYNAMIC_COPY); /* allocation */
   5103 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
   5104 
   5105 		gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, i, m_bo_id[i]);
   5106 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferRange call failed.");
   5107 	}
   5108 }
   5109 
   5110 void gl3cts::TransformFeedback::CaptureSpecialInterleaved::draw()
   5111 {
   5112 	/* Functions handler */
   5113 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5114 
   5115 	gl.enable(GL_RASTERIZER_DISCARD);
   5116 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable call failed.");
   5117 
   5118 	gl.beginTransformFeedback(GL_POINTS);
   5119 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
   5120 
   5121 	gl.drawArrays(GL_POINTS, 0, 1);
   5122 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
   5123 
   5124 	gl.endTransformFeedback();
   5125 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
   5126 
   5127 	gl.disable(GL_RASTERIZER_DISCARD);
   5128 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable call failed.");
   5129 }
   5130 
   5131 bool gl3cts::TransformFeedback::CaptureSpecialInterleaved::check()
   5132 {
   5133 	/* Functions handler */
   5134 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5135 
   5136 	bool is_ok = true;
   5137 
   5138 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id[0]);
   5139 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   5140 
   5141 	glw::GLfloat* results =
   5142 		(glw::GLfloat*)gl.mapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, s_bo_size, GL_MAP_READ_BIT);
   5143 	GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange call failed.");
   5144 
   5145 	if ((results[0] != 1.0) || (results[1] != 2.0) || (results[2] != 3.0) || (results[3] != 4.0) ||
   5146 		/* gl_SkipComponents4 here */
   5147 		(results[8] != 5.0) || (results[9] != 6.0) || (results[10] != 7.0) || (results[11] != 8.0))
   5148 	{
   5149 		is_ok = false;
   5150 	}
   5151 
   5152 	gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   5153 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");
   5154 
   5155 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id[1]);
   5156 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   5157 
   5158 	results = (glw::GLfloat*)gl.mapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, s_bo_size, GL_MAP_READ_BIT);
   5159 	GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange call failed.");
   5160 
   5161 	if ((results[0] != 9.0) || (results[1] != 10.0) || (results[2] != 11.0) || (results[3] != 12.0) ||
   5162 		/* gl_SkipComponents4 here */
   5163 		(results[8] != 13.0) || (results[9] != 14.0) || (results[10] != 15.0) || (results[11] != 16.0))
   5164 	{
   5165 		is_ok = false;
   5166 	}
   5167 
   5168 	gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   5169 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");
   5170 
   5171 	return is_ok;
   5172 }
   5173 
   5174 void gl3cts::TransformFeedback::CaptureSpecialInterleaved::clean()
   5175 {
   5176 	/* Functions handler */
   5177 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5178 
   5179 	gl.useProgram(0);
   5180 
   5181 	if (m_program_id)
   5182 	{
   5183 		gl.deleteProgram(m_program_id);
   5184 
   5185 		m_program_id = 0;
   5186 	}
   5187 
   5188 	if (m_xfb_id)
   5189 	{
   5190 		gl.deleteTransformFeedbacks(1, &m_xfb_id);
   5191 
   5192 		m_xfb_id = 0;
   5193 	}
   5194 
   5195 	for (glw::GLuint i = 0; i < s_bo_ids_count; ++i)
   5196 	{
   5197 		if (m_bo_id[i])
   5198 		{
   5199 			gl.deleteBuffers(1, &m_bo_id[i]);
   5200 
   5201 			m_bo_id[i] = 0;
   5202 		}
   5203 	}
   5204 
   5205 	if (m_vao_id)
   5206 	{
   5207 		gl.deleteVertexArrays(1, &m_vao_id);
   5208 
   5209 		m_vao_id = 0;
   5210 	}
   5211 }
   5212 
   5213 const glw::GLchar* gl3cts::TransformFeedback::CaptureSpecialInterleaved::s_vertex_shader =
   5214 	"#version 130\n"
   5215 	"\n"
   5216 	"out vec4 variable_1;\n"
   5217 	"out vec4 variable_2;\n"
   5218 	"out vec4 variable_3;\n"
   5219 	"out vec4 variable_4;\n"
   5220 	"\n"
   5221 	"void main()\n"
   5222 	"{\n"
   5223 	"    variable_1 = vec4(1.0, 2.0, 3.0, 4.0);\n"
   5224 	"    variable_2 = vec4(5.0, 6.0, 7.0, 8.0);\n"
   5225 	"    variable_3 = vec4(9.0, 10.0, 11.0, 12.0);\n"
   5226 	"    variable_4 = vec4(13.0, 14.0, 15.0, 16.0);\n"
   5227 	"\n"
   5228 	"    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
   5229 	"}\n";
   5230 
   5231 const glw::GLchar* gl3cts::TransformFeedback::CaptureSpecialInterleaved::s_fragment_shader = "#version 130\n"
   5232 																							 "\n"
   5233 																							 "out vec4 pixel;\n"
   5234 																							 "\n"
   5235 																							 "void main()\n"
   5236 																							 "{\n"
   5237 																							 "    pixel = vec4(1.0);\n"
   5238 																							 "}\n";
   5239 
   5240 const glw::GLchar* gl3cts::TransformFeedback::CaptureSpecialInterleaved::s_xfb_varyings[] =
   5241 	{ "variable_1", "gl_SkipComponents4", "variable_2", "gl_NextBuffer",
   5242 	  "variable_3", "gl_SkipComponents4", "variable_4" };
   5243 
   5244 const glw::GLuint gl3cts::TransformFeedback::CaptureSpecialInterleaved::s_xfb_varyings_count =
   5245 	sizeof(s_xfb_varyings) / sizeof(s_xfb_varyings[0]);
   5246 
   5247 const glw::GLuint gl3cts::TransformFeedback::CaptureSpecialInterleaved::s_bo_size =
   5248 	3 /*number of variables / empty places */ * 4 /* vec4 */
   5249 	* sizeof(glw::GLfloat);
   5250 
   5251 /*-----------------------------------------------------------------------------------------------*/
   5252 
   5253 gl3cts::TransformFeedback::DrawXFBStream::DrawXFBStream(deqp::Context& context, const char* test_name,
   5254 														const char* test_description)
   5255 	: deqp::TestCase(context, test_name, test_description)
   5256 	, m_context(context)
   5257 	, m_program_id_generate(0)
   5258 	, m_program_id_draw(0)
   5259 	, m_vao_id(0)
   5260 	, m_xfb_id(0)
   5261 	, m_fbo_id(0)
   5262 	, m_rbo_id(0)
   5263 {
   5264 	memset(m_bo_id, 0, sizeof(m_bo_id));
   5265 	memset(m_qo_id, 0, sizeof(m_qo_id));
   5266 }
   5267 
   5268 gl3cts::TransformFeedback::DrawXFBStream::~DrawXFBStream(void)
   5269 {
   5270 }
   5271 
   5272 tcu::TestNode::IterateResult gl3cts::TransformFeedback::DrawXFBStream::iterate(void)
   5273 {
   5274 	/* Functions handler */
   5275 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5276 
   5277 	/* Initializations. */
   5278 	bool is_at_least_gl_40  = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 0)));
   5279 	bool is_arb_tf_3		= m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback3");
   5280 	bool is_arb_gpu_shader5 = m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader5");
   5281 
   5282 	glw::GLint max_vertex_streams = 0;
   5283 
   5284 	bool is_ok		= true;
   5285 	bool test_error = false;
   5286 
   5287 	/* Tests. */
   5288 	try
   5289 	{
   5290 		if (is_at_least_gl_40 || (is_arb_tf_3 && is_arb_gpu_shader5))
   5291 		{
   5292 			gl.getIntegerv(GL_MAX_VERTEX_STREAMS, &max_vertex_streams);
   5293 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   5294 
   5295 			if (max_vertex_streams >= 2)
   5296 			{
   5297 				prepareObjects();
   5298 
   5299 				useProgram(m_program_id_generate);
   5300 
   5301 				drawForXFB();
   5302 
   5303 				is_ok = is_ok && inspectQueries();
   5304 
   5305 				useProgram(m_program_id_draw);
   5306 
   5307 				setupVertexArray(m_bo_id[0]);
   5308 
   5309 				drawForFramebuffer(0);
   5310 
   5311 				setupVertexArray(m_bo_id[1]);
   5312 
   5313 				drawForFramebuffer(1);
   5314 
   5315 				is_ok = is_ok && check();
   5316 			}
   5317 		}
   5318 	}
   5319 	catch (...)
   5320 	{
   5321 		is_ok	  = false;
   5322 		test_error = true;
   5323 	}
   5324 
   5325 	/* Clean GL objects. */
   5326 	clean();
   5327 
   5328 	/* Result's setup. */
   5329 	if (is_ok)
   5330 	{
   5331 		/* Log success. */
   5332 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB Stream have passed."
   5333 											<< tcu::TestLog::EndMessage;
   5334 
   5335 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   5336 	}
   5337 	else
   5338 	{
   5339 		if (test_error)
   5340 		{
   5341 			/* Log error. */
   5342 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB Stream have approached error."
   5343 												<< tcu::TestLog::EndMessage;
   5344 
   5345 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   5346 		}
   5347 		else
   5348 		{
   5349 			/* Log fail. */
   5350 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB Stream have failed."
   5351 												<< tcu::TestLog::EndMessage;
   5352 
   5353 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   5354 		}
   5355 	}
   5356 
   5357 	return STOP;
   5358 }
   5359 
   5360 void gl3cts::TransformFeedback::DrawXFBStream::prepareObjects()
   5361 {
   5362 	/* Functions handler */
   5363 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5364 
   5365 	/* Prepare programs. */
   5366 	m_program_id_generate = gl3cts::TransformFeedback::Utilities::buildProgram(
   5367 		gl, m_context.getTestContext().getLog(), s_geometry_shader, NULL, NULL, s_vertex_shader_blank,
   5368 		s_fragment_shader, s_xfb_varyings, s_xfb_varyings_count, GL_INTERLEAVED_ATTRIBS);
   5369 
   5370 	if (0 == m_program_id_generate)
   5371 	{
   5372 		throw 0;
   5373 	}
   5374 
   5375 	m_program_id_draw = gl3cts::TransformFeedback::Utilities::buildProgram(
   5376 		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, s_vertex_shader_pass, s_fragment_shader, NULL, 0,
   5377 		GL_INTERLEAVED_ATTRIBS);
   5378 
   5379 	if (0 == m_program_id_draw)
   5380 	{
   5381 		throw 0;
   5382 	}
   5383 
   5384 	/* Prepare transform feedbacks. */
   5385 	gl.genTransformFeedbacks(1, &m_xfb_id);
   5386 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTransformFeedbacks call failed.");
   5387 
   5388 	gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_xfb_id);
   5389 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedbacks call failed.");
   5390 
   5391 	/* Create empty Vertex Array Object */
   5392 	gl.genVertexArrays(1, &m_vao_id);
   5393 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
   5394 
   5395 	gl.bindVertexArray(m_vao_id);
   5396 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   5397 
   5398 	/* Prepare buffer objects. */
   5399 	gl.genBuffers(s_bo_ids_count, m_bo_id);
   5400 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   5401 
   5402 	for (glw::GLuint i = 0; i < s_bo_ids_count; ++i)
   5403 	{
   5404 		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id[i]);
   5405 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   5406 
   5407 		gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, s_bo_size, NULL, GL_DYNAMIC_COPY); /* allocation */
   5408 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
   5409 
   5410 		gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, i, m_bo_id[i]);
   5411 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferRange call failed.");
   5412 	}
   5413 
   5414 	/* Generate queries */
   5415 	gl.genQueries(s_qo_ids_count, m_qo_id);
   5416 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenQueries call failed.");
   5417 
   5418 	/* Prepare framebuffer. */
   5419 	gl.clearColor(0.f, 0.f, 0.f, 1.f);
   5420 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");
   5421 
   5422 	gl.genFramebuffers(1, &m_fbo_id);
   5423 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
   5424 
   5425 	gl.genRenderbuffers(1, &m_rbo_id);
   5426 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
   5427 
   5428 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id);
   5429 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
   5430 
   5431 	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_id);
   5432 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
   5433 
   5434 	gl.renderbufferStorage(GL_RENDERBUFFER, GL_R8, s_view_size, s_view_size);
   5435 	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed.");
   5436 
   5437 	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo_id);
   5438 	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed.");
   5439 
   5440 	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
   5441 	{
   5442 		throw 0;
   5443 	}
   5444 
   5445 	gl.viewport(0, 0, s_view_size, s_view_size);
   5446 	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
   5447 }
   5448 
   5449 void gl3cts::TransformFeedback::DrawXFBStream::setupVertexArray(glw::GLuint bo_id)
   5450 {
   5451 	/* Functions handler */
   5452 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5453 
   5454 	gl.bindBuffer(GL_ARRAY_BUFFER, bo_id);
   5455 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   5456 
   5457 	glw::GLuint position_location = gl.getAttribLocation(m_program_id_draw, "position");
   5458 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation call failed.");
   5459 
   5460 	gl.vertexAttribPointer(position_location, 4, GL_FLOAT, GL_FALSE, 0, NULL);
   5461 	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed.");
   5462 
   5463 	gl.enableVertexAttribArray(position_location);
   5464 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
   5465 }
   5466 
   5467 void gl3cts::TransformFeedback::DrawXFBStream::useProgram(glw::GLuint program_id)
   5468 {
   5469 	/* Functions handler */
   5470 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5471 
   5472 	gl.useProgram(program_id);
   5473 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
   5474 }
   5475 
   5476 void gl3cts::TransformFeedback::DrawXFBStream::drawForXFB()
   5477 {
   5478 	/* Functions handler */
   5479 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5480 
   5481 	gl.enable(GL_RASTERIZER_DISCARD);
   5482 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable call failed.");
   5483 
   5484 	gl.beginTransformFeedback(GL_POINTS);
   5485 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
   5486 
   5487 	gl.beginQueryIndexed(GL_PRIMITIVES_GENERATED, 0, m_qo_id[0]);
   5488 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginQueryIndexed call failed.");
   5489 
   5490 	gl.beginQueryIndexed(GL_PRIMITIVES_GENERATED, 1, m_qo_id[1]);
   5491 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginQueryIndexed call failed.");
   5492 
   5493 	gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, 0, m_qo_id[2]);
   5494 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginQueryIndexed call failed.");
   5495 
   5496 	gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, 1, m_qo_id[3]);
   5497 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginQueryIndexed call failed.");
   5498 
   5499 	gl.drawArrays(GL_POINTS, 0, 1);
   5500 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
   5501 
   5502 	gl.endQueryIndexed(GL_PRIMITIVES_GENERATED, 0);
   5503 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndQueryIndexed call failed.");
   5504 
   5505 	gl.endQueryIndexed(GL_PRIMITIVES_GENERATED, 1);
   5506 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndQueryIndexed call failed.");
   5507 
   5508 	gl.endQueryIndexed(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, 0);
   5509 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndQueryIndexed call failed.");
   5510 
   5511 	gl.endQueryIndexed(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, 1);
   5512 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndQueryIndexed call failed.");
   5513 
   5514 	gl.endTransformFeedback();
   5515 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
   5516 
   5517 	gl.disable(GL_RASTERIZER_DISCARD);
   5518 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable call failed.");
   5519 }
   5520 
   5521 void gl3cts::TransformFeedback::DrawXFBStream::drawForFramebuffer(glw::GLuint stream)
   5522 {
   5523 	/* Functions handler */
   5524 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5525 
   5526 	gl.drawTransformFeedbackStream(GL_TRIANGLES, m_xfb_id, stream);
   5527 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawTransformFeedbackStream call failed.");
   5528 }
   5529 
   5530 bool gl3cts::TransformFeedback::DrawXFBStream::inspectQueries()
   5531 {
   5532 	/* Functions handler */
   5533 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5534 
   5535 	glw::GLint generated_primitives_to_stream_0 = 0;
   5536 	glw::GLint generated_primitives_to_stream_1 = 0;
   5537 
   5538 	gl.getQueryObjectiv(m_qo_id[0], GL_QUERY_RESULT, &generated_primitives_to_stream_0);
   5539 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryIndexediv call failed.");
   5540 
   5541 	gl.getQueryObjectiv(m_qo_id[1], GL_QUERY_RESULT, &generated_primitives_to_stream_1);
   5542 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryIndexediv call failed.");
   5543 
   5544 	glw::GLint primitives_written_to_xfb_to_stream_0 = 0;
   5545 	glw::GLint primitives_written_to_xfb_to_stream_1 = 0;
   5546 
   5547 	gl.getQueryObjectiv(m_qo_id[2], GL_QUERY_RESULT, &primitives_written_to_xfb_to_stream_0);
   5548 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryIndexediv call failed.");
   5549 
   5550 	gl.getQueryObjectiv(m_qo_id[3], GL_QUERY_RESULT, &primitives_written_to_xfb_to_stream_1);
   5551 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryIndexediv call failed.");
   5552 
   5553 	if ((generated_primitives_to_stream_0 == 3) && (generated_primitives_to_stream_1 == 3) &&
   5554 		(primitives_written_to_xfb_to_stream_0 == 3) && (primitives_written_to_xfb_to_stream_1 == 3))
   5555 	{
   5556 		return true;
   5557 	}
   5558 
   5559 	return false;
   5560 }
   5561 
   5562 bool gl3cts::TransformFeedback::DrawXFBStream::check()
   5563 {
   5564 	/* Functions handler */
   5565 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5566 
   5567 	/* Number of pixels. */
   5568 	const glw::GLuint number_of_pixels = s_view_size * s_view_size;
   5569 
   5570 	/* Fetch framebuffer. */
   5571 	std::vector<glw::GLfloat> pixels(number_of_pixels);
   5572 
   5573 	gl.readPixels(0, 0, s_view_size, s_view_size, GL_RED, GL_FLOAT, &pixels[0]);
   5574 	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");
   5575 
   5576 	/* Check results. */
   5577 	for (glw::GLuint i = 0; i < number_of_pixels; ++i)
   5578 	{
   5579 		if (fabs(pixels[i] - 1.f) > 0.0625 /* precision, expected result == 1.0 */)
   5580 		{
   5581 			return false;
   5582 		}
   5583 	}
   5584 
   5585 	return true;
   5586 }
   5587 
   5588 void gl3cts::TransformFeedback::DrawXFBStream::clean()
   5589 {
   5590 	/* Functions handler */
   5591 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5592 
   5593 	gl.useProgram(0);
   5594 
   5595 	if (m_program_id_generate)
   5596 	{
   5597 		gl.deleteProgram(m_program_id_generate);
   5598 
   5599 		m_program_id_generate = 0;
   5600 	}
   5601 
   5602 	if (m_program_id_draw)
   5603 	{
   5604 		glw::GLuint position_location = gl.getAttribLocation(m_program_id_draw, "position");
   5605 
   5606 		gl.disableVertexAttribArray(position_location);
   5607 
   5608 		gl.deleteProgram(m_program_id_draw);
   5609 
   5610 		m_program_id_draw = 0;
   5611 	}
   5612 
   5613 	if (m_xfb_id)
   5614 	{
   5615 		gl.deleteTransformFeedbacks(1, &m_xfb_id);
   5616 
   5617 		m_xfb_id = 0;
   5618 	}
   5619 
   5620 	for (glw::GLuint i = 0; i < s_bo_ids_count; ++i)
   5621 	{
   5622 		if (m_bo_id[i])
   5623 		{
   5624 			gl.deleteBuffers(1, &m_bo_id[i]);
   5625 
   5626 			m_bo_id[i] = 0;
   5627 		}
   5628 	}
   5629 
   5630 	if (m_vao_id)
   5631 	{
   5632 		gl.deleteVertexArrays(1, &m_vao_id);
   5633 
   5634 		m_vao_id = 0;
   5635 	}
   5636 
   5637 	if (m_fbo_id)
   5638 	{
   5639 		gl.deleteFramebuffers(1, &m_fbo_id);
   5640 
   5641 		m_fbo_id = 0;
   5642 	}
   5643 
   5644 	if (m_rbo_id)
   5645 	{
   5646 		gl.deleteRenderbuffers(1, &m_rbo_id);
   5647 
   5648 		m_rbo_id = 0;
   5649 	}
   5650 }
   5651 
   5652 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStream::s_vertex_shader_blank = "#version 130\n"
   5653 																					 "\n"
   5654 																					 "void main()\n"
   5655 																					 "{\n"
   5656 																					 "}\n";
   5657 
   5658 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStream::s_vertex_shader_pass = "#version 130\n"
   5659 																					"\n"
   5660 																					"in vec4 position;\n"
   5661 																					"\n"
   5662 																					"void main()\n"
   5663 																					"{\n"
   5664 																					"    gl_Position = position;\n"
   5665 																					"}\n";
   5666 
   5667 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStream::s_geometry_shader =
   5668 	"#version 400\n"
   5669 	"\n"
   5670 	"layout(points) in;\n"
   5671 	"layout(points, max_vertices = 6) out;\n"
   5672 	"\n"
   5673 	"layout(stream = 1) out vec4 position;\n"
   5674 	"\n"
   5675 	"void main()\n"
   5676 	"{\n"
   5677 	"    gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
   5678 	"    EmitStreamVertex(0);\n"
   5679 	"    gl_Position = vec4( 1.0, -1.0, 0.0, 1.0);\n"
   5680 	"    EmitStreamVertex(0);\n"
   5681 	"    gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
   5682 	"    EmitStreamVertex(0);\n"
   5683 	"\n"
   5684 	"    position = vec4( 1.0, -1.0, 0.0, 1.0);\n"
   5685 	"    EmitStreamVertex(1);\n"
   5686 	"    position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
   5687 	"    EmitStreamVertex(1);\n"
   5688 	"    position = vec4( 1.0,  1.0, 0.0, 1.0);\n"
   5689 	"    EmitStreamVertex(1);\n"
   5690 	"}\n";
   5691 
   5692 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStream::s_fragment_shader = "#version 130\n"
   5693 																				 "\n"
   5694 																				 "out vec4 pixel;\n"
   5695 																				 "\n"
   5696 																				 "void main()\n"
   5697 																				 "{\n"
   5698 																				 "    pixel = vec4(1.0);\n"
   5699 																				 "}\n";
   5700 
   5701 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStream::s_xfb_varyings[] = { "gl_Position", "gl_NextBuffer",
   5702 																				  "position" };
   5703 
   5704 const glw::GLuint gl3cts::TransformFeedback::DrawXFBStream::s_xfb_varyings_count =
   5705 	sizeof(s_xfb_varyings) / sizeof(s_xfb_varyings[0]);
   5706 
   5707 const glw::GLuint gl3cts::TransformFeedback::DrawXFBStream::s_bo_size =
   5708 	3 /* triangles */ * 4 /* vec4 */ * sizeof(glw::GLfloat);
   5709 
   5710 const glw::GLuint gl3cts::TransformFeedback::DrawXFBStream::s_view_size = 2;
   5711 
   5712 /*-----------------------------------------------------------------------------------------------*/
   5713 
   5714 gl3cts::TransformFeedback::DrawXFBInstanced::DrawXFBInstanced(deqp::Context& context, const char* test_name,
   5715 															  const char* test_description)
   5716 	: deqp::TestCase(context, test_name, test_description)
   5717 	, m_context(context)
   5718 	, m_program_id_generate(0)
   5719 	, m_program_id_draw(0)
   5720 	, m_vao_id(0)
   5721 	, m_xfb_id(0)
   5722 	, m_bo_id_xfb(0)
   5723 	, m_bo_id_uniform(0)
   5724 	, m_fbo_id(0)
   5725 	, m_rbo_id(0)
   5726 	, m_glGetUniformBlockIndex(DE_NULL)
   5727 	, m_glUniformBlockBinding(DE_NULL)
   5728 {
   5729 }
   5730 
   5731 gl3cts::TransformFeedback::DrawXFBInstanced::~DrawXFBInstanced(void)
   5732 {
   5733 }
   5734 
   5735 tcu::TestNode::IterateResult gl3cts::TransformFeedback::DrawXFBInstanced::iterate(void)
   5736 {
   5737 	/* Initializations. */
   5738 	bool is_at_least_gl_42   = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 2)));
   5739 	bool is_at_least_gl_31   = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(3, 1)));
   5740 	bool is_arb_tf_instanced = m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback_instanced");
   5741 	bool is_arb_ubo			 = m_context.getContextInfo().isExtensionSupported("GL_ARB_uniform_buffer_object");
   5742 
   5743 	bool is_ok		= true;
   5744 	bool test_error = false;
   5745 
   5746 	if (is_arb_ubo)
   5747 	{
   5748 		m_glGetUniformBlockIndex =
   5749 			(GetUniformBlockIndex_ProcAddress)m_context.getRenderContext().getProcAddress("glGetUniformBlockIndex");
   5750 
   5751 		m_glUniformBlockBinding =
   5752 			(UniformBlockBinding_ProcAddress)m_context.getRenderContext().getProcAddress("glUniformBlockBinding");
   5753 
   5754 		if (DE_NULL == m_glGetUniformBlockIndex || DE_NULL == m_glUniformBlockBinding)
   5755 		{
   5756 			throw 0;
   5757 		}
   5758 	}
   5759 
   5760 	try
   5761 	{
   5762 		if (is_at_least_gl_42 || ((is_at_least_gl_31 || is_arb_ubo) && is_arb_tf_instanced))
   5763 		{
   5764 			prepareObjects();
   5765 			drawForXFB();
   5766 			drawInstanced();
   5767 
   5768 			is_ok = is_ok && check();
   5769 		}
   5770 	}
   5771 	catch (...)
   5772 	{
   5773 		is_ok	  = false;
   5774 		test_error = true;
   5775 	}
   5776 
   5777 	/* Clean GL objects */
   5778 	clean();
   5779 
   5780 	/* Result's setup. */
   5781 	if (is_ok)
   5782 	{
   5783 		/* Log success. */
   5784 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB Instanced have passed."
   5785 											<< tcu::TestLog::EndMessage;
   5786 
   5787 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   5788 	}
   5789 	else
   5790 	{
   5791 		if (test_error)
   5792 		{
   5793 			/* Log error. */
   5794 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB Instanced have approached error."
   5795 												<< tcu::TestLog::EndMessage;
   5796 
   5797 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   5798 		}
   5799 		else
   5800 		{
   5801 			/* Log fail. */
   5802 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB Instanced have failed."
   5803 												<< tcu::TestLog::EndMessage;
   5804 
   5805 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   5806 		}
   5807 	}
   5808 
   5809 	return STOP;
   5810 }
   5811 
   5812 void gl3cts::TransformFeedback::DrawXFBInstanced::prepareObjects()
   5813 {
   5814 	/* Functions handler */
   5815 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5816 
   5817 	/* Prepare programs. */
   5818 	m_program_id_generate = gl3cts::TransformFeedback::Utilities::buildProgram(
   5819 		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, s_vertex_shader_generate, s_fragment_shader,
   5820 		&s_xfb_varying, 1, GL_INTERLEAVED_ATTRIBS);
   5821 
   5822 	if (0 == m_program_id_generate)
   5823 	{
   5824 		throw 0;
   5825 	}
   5826 
   5827 	m_program_id_draw = gl3cts::TransformFeedback::Utilities::buildProgram(
   5828 		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, s_vertex_shader_draw, s_fragment_shader, NULL, 0,
   5829 		GL_INTERLEAVED_ATTRIBS);
   5830 
   5831 	if (0 == m_program_id_draw)
   5832 	{
   5833 		throw 0;
   5834 	}
   5835 
   5836 	/* Prepare transform feedbacks. */
   5837 	gl.genTransformFeedbacks(1, &m_xfb_id);
   5838 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTransformFeedbacks call failed.");
   5839 
   5840 	gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_xfb_id);
   5841 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedbacks call failed.");
   5842 
   5843 	/* Create empty Vertex Array Object */
   5844 	gl.genVertexArrays(1, &m_vao_id);
   5845 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
   5846 
   5847 	gl.bindVertexArray(m_vao_id);
   5848 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   5849 
   5850 	/* Prepare xfb buffer object. */
   5851 	gl.genBuffers(1, &m_bo_id_xfb);
   5852 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   5853 
   5854 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id_xfb);
   5855 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   5856 
   5857 	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, s_bo_xfb_size, NULL, GL_DYNAMIC_COPY); /* allocation */
   5858 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
   5859 
   5860 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_id_xfb);
   5861 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferRange call failed.");
   5862 
   5863 	/* Prepare uniform buffer object. */
   5864 	gl.genBuffers(1, &m_bo_id_uniform);
   5865 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   5866 
   5867 	gl.bindBuffer(GL_UNIFORM_BUFFER, m_bo_id_uniform);
   5868 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   5869 
   5870 	gl.bufferData(GL_UNIFORM_BUFFER, s_bo_uniform_size, s_bo_uniform_data, GL_DYNAMIC_COPY); /* allocation */
   5871 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
   5872 
   5873 	gl.bindBufferBase(GL_UNIFORM_BUFFER, 0, m_bo_id_uniform);
   5874 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferRange call failed.");
   5875 
   5876 	glw::GLuint uniform_index = m_glGetUniformBlockIndex(m_program_id_draw, s_uniform);
   5877 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformBlockIndex call failed.");
   5878 
   5879 	if (GL_INVALID_INDEX == uniform_index)
   5880 	{
   5881 		throw 0;
   5882 	}
   5883 
   5884 	m_glUniformBlockBinding(m_program_id_draw, uniform_index, 0);
   5885 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniformBlockBinding call failed.");
   5886 
   5887 	/* Prepare framebuffer. */
   5888 	gl.clearColor(0.f, 0.f, 0.f, 1.f);
   5889 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");
   5890 
   5891 	gl.genFramebuffers(1, &m_fbo_id);
   5892 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
   5893 
   5894 	gl.genRenderbuffers(1, &m_rbo_id);
   5895 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
   5896 
   5897 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id);
   5898 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
   5899 
   5900 	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_id);
   5901 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
   5902 
   5903 	gl.renderbufferStorage(GL_RENDERBUFFER, GL_R8, s_view_size, s_view_size);
   5904 	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed.");
   5905 
   5906 	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo_id);
   5907 	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed.");
   5908 
   5909 	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
   5910 	{
   5911 		throw 0;
   5912 	}
   5913 
   5914 	gl.viewport(0, 0, s_view_size, s_view_size);
   5915 	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
   5916 }
   5917 
   5918 void gl3cts::TransformFeedback::DrawXFBInstanced::drawForXFB()
   5919 {
   5920 	/* Functions handler */
   5921 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5922 
   5923 	gl.useProgram(m_program_id_generate);
   5924 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
   5925 
   5926 	gl.enable(GL_RASTERIZER_DISCARD);
   5927 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable call failed.");
   5928 
   5929 	gl.beginTransformFeedback(GL_POINTS);
   5930 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
   5931 
   5932 	gl.drawArrays(GL_POINTS, 0, 4 /* quad vertex count */);
   5933 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
   5934 
   5935 	gl.endTransformFeedback();
   5936 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
   5937 
   5938 	gl.disable(GL_RASTERIZER_DISCARD);
   5939 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable call failed.");
   5940 }
   5941 
   5942 void gl3cts::TransformFeedback::DrawXFBInstanced::drawInstanced()
   5943 {
   5944 	/* Functions handler */
   5945 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5946 
   5947 	gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id_xfb);
   5948 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   5949 
   5950 	glw::GLuint position_location = gl.getAttribLocation(m_program_id_draw, "position");
   5951 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation call failed.");
   5952 
   5953 	gl.vertexAttribPointer(position_location, 4, GL_FLOAT, GL_FALSE, 0, NULL);
   5954 	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed.");
   5955 
   5956 	gl.enableVertexAttribArray(position_location);
   5957 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
   5958 
   5959 	gl.clear(GL_COLOR_BUFFER_BIT);
   5960 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed.");
   5961 
   5962 	gl.useProgram(m_program_id_draw);
   5963 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
   5964 
   5965 	gl.drawTransformFeedbackInstanced(GL_TRIANGLE_STRIP, m_xfb_id, 4);
   5966 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
   5967 }
   5968 
   5969 bool gl3cts::TransformFeedback::DrawXFBInstanced::check()
   5970 {
   5971 	/* Functions handler */
   5972 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5973 
   5974 	/* Number of pixels. */
   5975 	const glw::GLuint number_of_pixels = s_view_size * s_view_size;
   5976 
   5977 	/* Fetch framebuffer. */
   5978 	std::vector<glw::GLfloat> pixels(number_of_pixels);
   5979 
   5980 	gl.readPixels(0, 0, s_view_size, s_view_size, GL_RED, GL_FLOAT, &pixels[0]);
   5981 	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");
   5982 
   5983 	/* Check results. */
   5984 	for (glw::GLuint i = 0; i < number_of_pixels; ++i)
   5985 	{
   5986 		if (fabs(pixels[i] - 1.f) > 0.0625 /* precision, expected result == 1.0 */)
   5987 		{
   5988 			return false;
   5989 		}
   5990 	}
   5991 
   5992 	return true;
   5993 }
   5994 
   5995 void gl3cts::TransformFeedback::DrawXFBInstanced::clean()
   5996 {
   5997 	/* Functions handler */
   5998 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5999 
   6000 	gl.useProgram(0);
   6001 
   6002 	if (m_program_id_generate)
   6003 	{
   6004 		gl.deleteProgram(m_program_id_generate);
   6005 
   6006 		m_program_id_generate = 0;
   6007 	}
   6008 
   6009 	if (m_program_id_draw)
   6010 	{
   6011 		glw::GLuint position_location = gl.getAttribLocation(m_program_id_draw, "position");
   6012 
   6013 		gl.disableVertexAttribArray(position_location);
   6014 
   6015 		gl.deleteProgram(m_program_id_draw);
   6016 
   6017 		m_program_id_draw = 0;
   6018 	}
   6019 
   6020 	if (m_xfb_id)
   6021 	{
   6022 		gl.deleteTransformFeedbacks(1, &m_xfb_id);
   6023 
   6024 		m_xfb_id = 0;
   6025 	}
   6026 
   6027 	if (m_bo_id_xfb)
   6028 	{
   6029 		gl.deleteBuffers(1, &m_bo_id_xfb);
   6030 
   6031 		m_bo_id_xfb = 0;
   6032 	}
   6033 
   6034 	if (m_bo_id_uniform)
   6035 	{
   6036 		gl.deleteBuffers(1, &m_bo_id_uniform);
   6037 
   6038 		m_bo_id_uniform = 0;
   6039 	}
   6040 
   6041 	if (m_vao_id)
   6042 	{
   6043 		gl.deleteVertexArrays(1, &m_vao_id);
   6044 
   6045 		m_vao_id = 0;
   6046 	}
   6047 
   6048 	if (m_fbo_id)
   6049 	{
   6050 		gl.deleteFramebuffers(1, &m_fbo_id);
   6051 
   6052 		m_fbo_id = 0;
   6053 	}
   6054 
   6055 	if (m_rbo_id)
   6056 	{
   6057 		gl.deleteRenderbuffers(1, &m_rbo_id);
   6058 
   6059 		m_rbo_id = 0;
   6060 	}
   6061 }
   6062 
   6063 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBInstanced::s_vertex_shader_generate =
   6064 	"#version 140\n"
   6065 	"\n"
   6066 	"void main()\n"
   6067 	"{\n"
   6068 	"    switch(gl_VertexID % 4)\n"
   6069 	"    {\n"
   6070 	"    case 0:\n"
   6071 	"       gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
   6072 	"       break;\n"
   6073 	"    case 1:\n"
   6074 	"       gl_Position = vec4( 1.0, -1.0, 0.0, 1.0);\n"
   6075 	"       break;\n"
   6076 	"    case 2:\n"
   6077 	"       gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
   6078 	"       break;\n"
   6079 	"    case 3:\n"
   6080 	"       gl_Position = vec4( 1.0,  1.0, 0.0, 1.0);\n"
   6081 	"       break;\n"
   6082 	"    }\n"
   6083 	"}\n";
   6084 
   6085 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBInstanced::s_vertex_shader_draw =
   6086 	"#version 140\n"
   6087 	"\n"
   6088 	"uniform MatrixBlock\n"
   6089 	"{\n"
   6090 	"    mat4 transformation_0;\n"
   6091 	"    mat4 transformation_1;\n"
   6092 	"    mat4 transformation_2;\n"
   6093 	"    mat4 transformation_3;\n"
   6094 	"};\n"
   6095 	"\n"
   6096 	"in vec4 position;\n"
   6097 	"\n"
   6098 	"void main()\n"
   6099 	"{\n"
   6100 	"    switch(gl_InstanceID % 4)\n"
   6101 	"    {\n"
   6102 	"    case 0:\n"
   6103 	"       gl_Position = position * transformation_0;\n"
   6104 	"       break;\n"
   6105 	"    case 1:\n"
   6106 	"       gl_Position = position * transformation_1;\n"
   6107 	"       break;\n"
   6108 	"    case 2:\n"
   6109 	"       gl_Position = position * transformation_2;\n"
   6110 	"       break;\n"
   6111 	"    case 3:\n"
   6112 	"       gl_Position = position * transformation_3;\n"
   6113 	"       break;\n"
   6114 	"    }\n"
   6115 	"}\n";
   6116 
   6117 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBInstanced::s_fragment_shader = "#version 130\n"
   6118 																					"\n"
   6119 																					"out vec4 pixel;\n"
   6120 																					"\n"
   6121 																					"void main()\n"
   6122 																					"{\n"
   6123 																					"    pixel = vec4(1.0);\n"
   6124 																					"}\n";
   6125 
   6126 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBInstanced::s_xfb_varying = "gl_Position";
   6127 
   6128 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBInstanced::s_uniform = "MatrixBlock";
   6129 
   6130 const glw::GLuint gl3cts::TransformFeedback::DrawXFBInstanced::s_bo_xfb_size =
   6131 	4 /* vertex count */ * 4 /* vec4 components */
   6132 	* sizeof(glw::GLfloat) /* data type size */;
   6133 
   6134 const glw::GLfloat gl3cts::TransformFeedback::DrawXFBInstanced::s_bo_uniform_data[] = {
   6135 	0.5f, 0.0f, 0.0f, 0.5f,  0.0f, 0.5f, 0.0f, 0.5f,  0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
   6136 
   6137 	0.5f, 0.0f, 0.0f, -0.5f, 0.0f, 0.5f, 0.0f, 0.5f,  0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
   6138 
   6139 	0.5f, 0.0f, 0.0f, -0.5f, 0.0f, 0.5f, 0.0f, -0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
   6140 
   6141 	0.5f, 0.0f, 0.0f, 0.5f,  0.0f, 0.5f, 0.0f, -0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f
   6142 };
   6143 
   6144 const glw::GLuint gl3cts::TransformFeedback::DrawXFBInstanced::s_bo_uniform_size = sizeof(s_bo_uniform_data);
   6145 
   6146 const glw::GLuint gl3cts::TransformFeedback::DrawXFBInstanced::s_view_size = 4;
   6147 
   6148 /*-----------------------------------------------------------------------------------------------*/
   6149 
   6150 gl3cts::TransformFeedback::DrawXFBStreamInstanced::DrawXFBStreamInstanced(deqp::Context& context, const char* test_name,
   6151 																		  const char* test_description)
   6152 	: deqp::TestCase(context, test_name, test_description)
   6153 	, m_context(context)
   6154 	, m_program_id_generate(0)
   6155 	, m_program_id_draw(0)
   6156 	, m_vao_id(0)
   6157 	, m_xfb_id(0)
   6158 	, m_bo_id_xfb_position(0)
   6159 	, m_bo_id_xfb_color(0)
   6160 	, m_bo_id_uniform(0)
   6161 	, m_fbo_id(0)
   6162 	, m_rbo_id(0)
   6163 	, m_glGetUniformBlockIndex(DE_NULL)
   6164 	, m_glUniformBlockBinding(DE_NULL)
   6165 {
   6166 }
   6167 
   6168 gl3cts::TransformFeedback::DrawXFBStreamInstanced::~DrawXFBStreamInstanced(void)
   6169 {
   6170 }
   6171 
   6172 tcu::TestNode::IterateResult gl3cts::TransformFeedback::DrawXFBStreamInstanced::iterate(void)
   6173 {
   6174 	/* Initializations. */
   6175 	bool is_at_least_gl_31   = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(3, 1)));
   6176 	bool is_at_least_gl_40   = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 0)));
   6177 	bool is_at_least_gl_42   = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 2)));
   6178 	bool is_arb_tf_instanced = m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback_instanced");
   6179 	bool is_arb_ubo			 = m_context.getContextInfo().isExtensionSupported("GL_ARB_uniform_buffer_object");
   6180 	bool is_arb_gpu_shader5  = m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader5");
   6181 
   6182 	bool is_ok		= true;
   6183 	bool test_error = false;
   6184 
   6185 	if (is_arb_ubo)
   6186 	{
   6187 		m_glGetUniformBlockIndex =
   6188 			(GetUniformBlockIndex_ProcAddress)m_context.getRenderContext().getProcAddress("glGetUniformBlockIndex");
   6189 
   6190 		m_glUniformBlockBinding =
   6191 			(UniformBlockBinding_ProcAddress)m_context.getRenderContext().getProcAddress("glUniformBlockBinding");
   6192 
   6193 		if (DE_NULL == m_glGetUniformBlockIndex || DE_NULL == m_glUniformBlockBinding)
   6194 		{
   6195 			throw 0;
   6196 		}
   6197 	}
   6198 
   6199 	/* Test. */
   6200 	try
   6201 	{
   6202 		if (is_at_least_gl_42 || ((is_at_least_gl_31 || is_arb_ubo) && is_arb_gpu_shader5 && is_arb_tf_instanced) ||
   6203 			(is_at_least_gl_40 && is_arb_tf_instanced))
   6204 		{
   6205 			prepareObjects();
   6206 			drawForXFB();
   6207 			drawStreamInstanced();
   6208 
   6209 			is_ok = is_ok && check();
   6210 		}
   6211 	}
   6212 	catch (...)
   6213 	{
   6214 		is_ok	  = false;
   6215 		test_error = true;
   6216 	}
   6217 
   6218 	/* Clean GL objects */
   6219 	clean();
   6220 
   6221 	/* Result's setup. */
   6222 	if (is_ok)
   6223 	{
   6224 		/* Log success. */
   6225 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB Stream Instanced have passed."
   6226 											<< tcu::TestLog::EndMessage;
   6227 
   6228 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   6229 	}
   6230 	else
   6231 	{
   6232 		if (test_error)
   6233 		{
   6234 			/* Log error. */
   6235 			m_context.getTestContext().getLog() << tcu::TestLog::Message
   6236 												<< "Draw XFB Stream Instanced have approached error."
   6237 												<< tcu::TestLog::EndMessage;
   6238 
   6239 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   6240 		}
   6241 		else
   6242 		{
   6243 			/* Log fail. */
   6244 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB Stream Instanced have failed."
   6245 												<< tcu::TestLog::EndMessage;
   6246 
   6247 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   6248 		}
   6249 	}
   6250 
   6251 	return STOP;
   6252 }
   6253 
   6254 void gl3cts::TransformFeedback::DrawXFBStreamInstanced::prepareObjects()
   6255 {
   6256 	/* Functions handler */
   6257 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   6258 
   6259 	/* Prepare programs. */
   6260 	m_program_id_generate = gl3cts::TransformFeedback::Utilities::buildProgram(
   6261 		gl, m_context.getTestContext().getLog(), s_geometry_shader_generate, NULL, NULL, s_vertex_shader_blank,
   6262 		s_fragment_shader_blank, s_xfb_varyings, s_xfb_varyings_count, GL_INTERLEAVED_ATTRIBS);
   6263 
   6264 	if (0 == m_program_id_generate)
   6265 	{
   6266 		throw 0;
   6267 	}
   6268 
   6269 	m_program_id_draw = gl3cts::TransformFeedback::Utilities::buildProgram(
   6270 		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, s_vertex_shader_draw, s_fragment_shader_draw, NULL,
   6271 		0, GL_INTERLEAVED_ATTRIBS);
   6272 
   6273 	if (0 == m_program_id_draw)
   6274 	{
   6275 		throw 0;
   6276 	}
   6277 
   6278 	/* Prepare transform feedbacks. */
   6279 	gl.genTransformFeedbacks(1, &m_xfb_id);
   6280 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTransformFeedbacks call failed.");
   6281 
   6282 	gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_xfb_id);
   6283 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedbacks call failed.");
   6284 
   6285 	/* Create empty Vertex Array Object */
   6286 	gl.genVertexArrays(1, &m_vao_id);
   6287 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
   6288 
   6289 	gl.bindVertexArray(m_vao_id);
   6290 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   6291 
   6292 	/* Prepare xfb buffer objects. */
   6293 	gl.genBuffers(1, &m_bo_id_xfb_position);
   6294 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   6295 
   6296 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id_xfb_position);
   6297 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   6298 
   6299 	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, s_bo_xfb_size, NULL, GL_DYNAMIC_COPY); /* allocation */
   6300 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
   6301 
   6302 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_id_xfb_position);
   6303 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferRange call failed.");
   6304 
   6305 	gl.genBuffers(1, &m_bo_id_xfb_color);
   6306 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   6307 
   6308 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id_xfb_color);
   6309 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   6310 
   6311 	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, s_bo_xfb_size, NULL, GL_DYNAMIC_COPY); /* allocation */
   6312 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
   6313 
   6314 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 1, m_bo_id_xfb_color);
   6315 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferRange call failed.");
   6316 
   6317 	/* Prepare uniform buffer object. */
   6318 	gl.genBuffers(1, &m_bo_id_uniform);
   6319 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   6320 
   6321 	gl.bindBuffer(GL_UNIFORM_BUFFER, m_bo_id_uniform);
   6322 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   6323 
   6324 	gl.bufferData(GL_UNIFORM_BUFFER, s_bo_uniform_size, s_bo_uniform_data, GL_DYNAMIC_COPY); /* allocation */
   6325 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
   6326 
   6327 	gl.bindBufferBase(GL_UNIFORM_BUFFER, 0, m_bo_id_uniform);
   6328 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferRange call failed.");
   6329 
   6330 	glw::GLuint uniform_index = m_glGetUniformBlockIndex(m_program_id_draw, s_uniform);
   6331 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformBlockIndex call failed.");
   6332 
   6333 	if (GL_INVALID_INDEX == uniform_index)
   6334 	{
   6335 		throw 0;
   6336 	}
   6337 
   6338 	m_glUniformBlockBinding(m_program_id_draw, uniform_index, 0);
   6339 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniformBlockBinding call failed.");
   6340 
   6341 	/* Prepare framebuffer. */
   6342 	gl.clearColor(0.f, 0.f, 0.f, 1.f);
   6343 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");
   6344 
   6345 	gl.genFramebuffers(1, &m_fbo_id);
   6346 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
   6347 
   6348 	gl.genRenderbuffers(1, &m_rbo_id);
   6349 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
   6350 
   6351 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id);
   6352 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
   6353 
   6354 	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_id);
   6355 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
   6356 
   6357 	gl.renderbufferStorage(GL_RENDERBUFFER, GL_R8, s_view_size, s_view_size);
   6358 	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed.");
   6359 
   6360 	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo_id);
   6361 	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed.");
   6362 
   6363 	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
   6364 	{
   6365 		throw 0;
   6366 	}
   6367 
   6368 	gl.viewport(0, 0, s_view_size, s_view_size);
   6369 	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
   6370 }
   6371 
   6372 void gl3cts::TransformFeedback::DrawXFBStreamInstanced::drawForXFB()
   6373 {
   6374 	/* Functions handler */
   6375 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   6376 
   6377 	gl.useProgram(m_program_id_generate);
   6378 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
   6379 
   6380 	gl.enable(GL_RASTERIZER_DISCARD);
   6381 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable call failed.");
   6382 
   6383 	gl.beginTransformFeedback(GL_POINTS);
   6384 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
   6385 
   6386 	gl.drawArrays(GL_POINTS, 0, 4 /* quad vertex count */);
   6387 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
   6388 
   6389 	gl.endTransformFeedback();
   6390 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
   6391 
   6392 	gl.disable(GL_RASTERIZER_DISCARD);
   6393 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable call failed.");
   6394 }
   6395 
   6396 void gl3cts::TransformFeedback::DrawXFBStreamInstanced::drawStreamInstanced()
   6397 {
   6398 	/* Functions handler */
   6399 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   6400 
   6401 	gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id_xfb_position);
   6402 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   6403 
   6404 	glw::GLuint position_location = gl.getAttribLocation(m_program_id_draw, "position");
   6405 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation call failed.");
   6406 
   6407 	gl.vertexAttribPointer(position_location, 4, GL_FLOAT, GL_FALSE, 0, NULL);
   6408 	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed.");
   6409 
   6410 	gl.enableVertexAttribArray(position_location);
   6411 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
   6412 
   6413 	gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id_xfb_color);
   6414 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   6415 
   6416 	glw::GLuint color_location = gl.getAttribLocation(m_program_id_draw, "color");
   6417 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation call failed.");
   6418 
   6419 	gl.vertexAttribPointer(color_location, 4, GL_FLOAT, GL_FALSE, 0, NULL);
   6420 	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed.");
   6421 
   6422 	gl.enableVertexAttribArray(color_location);
   6423 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
   6424 
   6425 	gl.useProgram(m_program_id_draw);
   6426 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
   6427 
   6428 	gl.drawTransformFeedbackStreamInstanced(GL_TRIANGLE_STRIP, m_xfb_id, 0, 4);
   6429 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
   6430 }
   6431 
   6432 bool gl3cts::TransformFeedback::DrawXFBStreamInstanced::check()
   6433 {
   6434 	/* Functions handler */
   6435 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   6436 
   6437 	/* Number of pixels. */
   6438 	const glw::GLuint number_of_pixels = s_view_size * s_view_size;
   6439 
   6440 	/* Fetch framebuffer. */
   6441 	std::vector<glw::GLfloat> pixels(number_of_pixels);
   6442 
   6443 	gl.readPixels(0, 0, s_view_size, s_view_size, GL_RED, GL_FLOAT, &pixels[0]);
   6444 	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");
   6445 
   6446 	/* Check results. */
   6447 	for (glw::GLuint i = 0; i < number_of_pixels; ++i)
   6448 	{
   6449 		if (fabs(pixels[i] - 1.f) > 0.0625 /* precision, expected result == 1.0 */)
   6450 		{
   6451 			return false;
   6452 		}
   6453 	}
   6454 
   6455 	return true;
   6456 }
   6457 
   6458 void gl3cts::TransformFeedback::DrawXFBStreamInstanced::clean()
   6459 {
   6460 	/* Functions handler */
   6461 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   6462 
   6463 	gl.useProgram(0);
   6464 
   6465 	if (m_program_id_generate)
   6466 	{
   6467 		gl.deleteProgram(m_program_id_generate);
   6468 
   6469 		m_program_id_generate = 0;
   6470 	}
   6471 
   6472 	if (m_program_id_draw)
   6473 	{
   6474 		glw::GLuint position_location = gl.getAttribLocation(m_program_id_draw, "position");
   6475 
   6476 		gl.disableVertexAttribArray(position_location);
   6477 
   6478 		glw::GLuint color_location = gl.getAttribLocation(m_program_id_draw, "color");
   6479 
   6480 		gl.disableVertexAttribArray(color_location);
   6481 
   6482 		gl.deleteProgram(m_program_id_draw);
   6483 
   6484 		m_program_id_draw = 0;
   6485 	}
   6486 
   6487 	if (m_xfb_id)
   6488 	{
   6489 		gl.deleteTransformFeedbacks(1, &m_xfb_id);
   6490 
   6491 		m_xfb_id = 0;
   6492 	}
   6493 
   6494 	if (m_bo_id_xfb_position)
   6495 	{
   6496 		gl.deleteBuffers(1, &m_bo_id_xfb_position);
   6497 
   6498 		m_bo_id_xfb_position = 0;
   6499 	}
   6500 
   6501 	if (m_bo_id_xfb_color)
   6502 	{
   6503 		gl.deleteBuffers(1, &m_bo_id_xfb_color);
   6504 
   6505 		m_bo_id_xfb_position = 0;
   6506 	}
   6507 
   6508 	if (m_bo_id_uniform)
   6509 	{
   6510 		gl.deleteBuffers(1, &m_bo_id_uniform);
   6511 
   6512 		m_bo_id_uniform = 0;
   6513 	}
   6514 
   6515 	if (m_vao_id)
   6516 	{
   6517 		gl.deleteVertexArrays(1, &m_vao_id);
   6518 
   6519 		m_vao_id = 0;
   6520 	}
   6521 
   6522 	if (m_fbo_id)
   6523 	{
   6524 		gl.deleteFramebuffers(1, &m_fbo_id);
   6525 
   6526 		m_fbo_id = 0;
   6527 	}
   6528 
   6529 	if (m_rbo_id)
   6530 	{
   6531 		gl.deleteRenderbuffers(1, &m_rbo_id);
   6532 
   6533 		m_rbo_id = 0;
   6534 	}
   6535 }
   6536 
   6537 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_vertex_shader_blank = "#version 140\n"
   6538 																							  "\n"
   6539 																							  "void main()\n"
   6540 																							  "{\n"
   6541 																							  "}\n";
   6542 
   6543 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_geometry_shader_generate =
   6544 	"#version 400\n"
   6545 	"\n"
   6546 	"layout(points) in;\n"
   6547 	"layout(points, max_vertices = 8) out;\n"
   6548 	"\n"
   6549 	"layout(stream = 1) out vec4 color;\n"
   6550 	"\n"
   6551 	"void main()\n"
   6552 	"{\n"
   6553 	"    gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
   6554 	"    EmitStreamVertex(0);\n"
   6555 	"    gl_Position = vec4( 1.0, -1.0, 0.0, 1.0);\n"
   6556 	"    EmitStreamVertex(0);\n"
   6557 	"    gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
   6558 	"    EmitStreamVertex(0);\n"
   6559 	"    gl_Position = vec4( 1.0,  1.0, 0.0, 1.0);\n"
   6560 	"    EmitStreamVertex(0);\n"
   6561 	"\n"
   6562 	"    color = vec4(1.0, 1.0, 1.0, 1.0);\n"
   6563 	"    EmitStreamVertex(1);\n"
   6564 	"    color = vec4(1.0, 1.0, 1.0, 1.0);\n"
   6565 	"    EmitStreamVertex(1);\n"
   6566 	"    color = vec4(1.0, 1.0, 1.0, 1.0);\n"
   6567 	"    EmitStreamVertex(1);\n"
   6568 	"    color = vec4(1.0, 1.0, 1.0, 1.0);\n"
   6569 	"    EmitStreamVertex(1);\n"
   6570 	"}\n";
   6571 
   6572 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_vertex_shader_draw =
   6573 	"#version 140\n"
   6574 	"\n"
   6575 	"uniform MatrixBlock\n"
   6576 	"{\n"
   6577 	"    mat4 transformation_0;\n"
   6578 	"    mat4 transformation_1;\n"
   6579 	"    mat4 transformation_2;\n"
   6580 	"    mat4 transformation_3;\n"
   6581 	"};\n"
   6582 	"\n"
   6583 	"in  vec4 position;\n"
   6584 	"in  vec4 color;\n"
   6585 	"out vec4 colour;\n"
   6586 	"\n"
   6587 	"void main()\n"
   6588 	"{\n"
   6589 	"    switch(gl_InstanceID % 4)\n"
   6590 	"    {\n"
   6591 	"    case 0:\n"
   6592 	"       gl_Position = position * transformation_0;\n"
   6593 	"       break;\n"
   6594 	"    case 1:\n"
   6595 	"       gl_Position = position * transformation_1;\n"
   6596 	"       break;\n"
   6597 	"    case 2:\n"
   6598 	"       gl_Position = position * transformation_2;\n"
   6599 	"       break;\n"
   6600 	"    case 3:\n"
   6601 	"       gl_Position = position * transformation_3;\n"
   6602 	"       break;\n"
   6603 	"    }\n"
   6604 	"    colour = color;\n"
   6605 	"}\n";
   6606 
   6607 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_fragment_shader_blank =
   6608 	"#version 130\n"
   6609 	"\n"
   6610 	"out vec4 pixel;\n"
   6611 	"\n"
   6612 	"void main()\n"
   6613 	"{\n"
   6614 	"    pixel = vec4(1.0);\n"
   6615 	"}\n";
   6616 
   6617 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_fragment_shader_draw = "#version 130\n"
   6618 																							   "\n"
   6619 																							   "in vec4 colour;\n"
   6620 																							   "out vec4 pixel;\n"
   6621 																							   "\n"
   6622 																							   "void main()\n"
   6623 																							   "{\n"
   6624 																							   "    pixel = colour;\n"
   6625 																							   "}\n";
   6626 
   6627 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_xfb_varyings[] = { "gl_Position",
   6628 																						   "gl_NextBuffer", "color" };
   6629 
   6630 const glw::GLuint gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_xfb_varyings_count =
   6631 	sizeof(s_xfb_varyings) / sizeof(s_xfb_varyings[0]);
   6632 
   6633 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_uniform = "MatrixBlock";
   6634 
   6635 const glw::GLuint gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_bo_xfb_size =
   6636 	4 /* vertex count */ * 4 /* vec4 components */
   6637 	* sizeof(glw::GLfloat) /* data type size */;
   6638 
   6639 const glw::GLfloat gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_bo_uniform_data[] = {
   6640 	0.5f, 0.0f, 0.0f, 0.5f,  0.0f, 0.5f, 0.0f, 0.5f,  0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
   6641 
   6642 	0.5f, 0.0f, 0.0f, -0.5f, 0.0f, 0.5f, 0.0f, 0.5f,  0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
   6643 
   6644 	0.5f, 0.0f, 0.0f, -0.5f, 0.0f, 0.5f, 0.0f, -0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
   6645 
   6646 	0.5f, 0.0f, 0.0f, 0.5f,  0.0f, 0.5f, 0.0f, -0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f
   6647 };
   6648 
   6649 const glw::GLuint gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_bo_uniform_size = sizeof(s_bo_uniform_data);
   6650 
   6651 const glw::GLuint gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_view_size = 4;
   6652 
   6653 /*-----------------------------------------------------------------------------------------------*/
   6654 
   6655 glw::GLuint gl3cts::TransformFeedback::Utilities::buildProgram(
   6656 	glw::Functions const& gl, tcu::TestLog& log, glw::GLchar const* const geometry_shader_source,
   6657 	glw::GLchar const* const tessellation_control_shader_source,
   6658 	glw::GLchar const* const tessellation_evaluation_shader_source, glw::GLchar const* const vertex_shader_source,
   6659 	glw::GLchar const* const fragment_shader_source, glw::GLchar const* const* const transform_feedback_varyings,
   6660 	glw::GLsizei const transform_feedback_varyings_count, glw::GLenum const transform_feedback_varyings_mode,
   6661 	bool const do_not_detach, glw::GLint* linking_status)
   6662 {
   6663 	glw::GLuint program = 0;
   6664 
   6665 	struct Shader
   6666 	{
   6667 		glw::GLchar const* const source;
   6668 		glw::GLenum const		 type;
   6669 		glw::GLuint				 id;
   6670 	} shader[] = { { geometry_shader_source, GL_GEOMETRY_SHADER, 0 },
   6671 				   { tessellation_control_shader_source, GL_TESS_CONTROL_SHADER, 0 },
   6672 				   { tessellation_evaluation_shader_source, GL_TESS_EVALUATION_SHADER, 0 },
   6673 				   { vertex_shader_source, GL_VERTEX_SHADER, 0 },
   6674 				   { fragment_shader_source, GL_FRAGMENT_SHADER, 0 } };
   6675 
   6676 	glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);
   6677 
   6678 	try
   6679 	{
   6680 		/* Create program. */
   6681 		program = gl.createProgram();
   6682 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");
   6683 
   6684 		/* Shader compilation. */
   6685 
   6686 		for (glw::GLuint i = 0; i < shader_count; ++i)
   6687 		{
   6688 			if (DE_NULL != shader[i].source)
   6689 			{
   6690 				shader[i].id = gl.createShader(shader[i].type);
   6691 
   6692 				GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");
   6693 
   6694 				gl.attachShader(program, shader[i].id);
   6695 
   6696 				GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");
   6697 
   6698 				gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL);
   6699 
   6700 				GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");
   6701 
   6702 				gl.compileShader(shader[i].id);
   6703 
   6704 				GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");
   6705 
   6706 				glw::GLint status = GL_FALSE;
   6707 
   6708 				gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
   6709 				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
   6710 
   6711 				if (GL_FALSE == status)
   6712 				{
   6713 					glw::GLint log_size = 0;
   6714 					gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
   6715 					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
   6716 
   6717 					glw::GLchar* log_text = new glw::GLchar[log_size];
   6718 
   6719 					gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);
   6720 
   6721 					log << tcu::TestLog::Message << "Shader compilation has failed.\n"
   6722 						<< "Shader type: " << glu::getShaderTypeStr(shader[i].type) << "\n"
   6723 						<< "Shader compilation error log:\n"
   6724 						<< log_text << "\n"
   6725 						<< "Shader source code:\n"
   6726 						<< shader[i].source << "\n"
   6727 						<< tcu::TestLog::EndMessage;
   6728 
   6729 					delete[] log_text;
   6730 
   6731 					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");
   6732 
   6733 					throw 0;
   6734 				}
   6735 			}
   6736 		}
   6737 
   6738 		/* Link. */
   6739 		if (transform_feedback_varyings_count)
   6740 		{
   6741 			gl.transformFeedbackVaryings(program, transform_feedback_varyings_count, transform_feedback_varyings,
   6742 										 transform_feedback_varyings_mode);
   6743 			GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
   6744 		}
   6745 
   6746 		gl.linkProgram(program);
   6747 
   6748 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
   6749 
   6750 		glw::GLint status = GL_FALSE;
   6751 
   6752 		gl.getProgramiv(program, GL_LINK_STATUS, &status);
   6753 
   6754 		if (DE_NULL != linking_status)
   6755 		{
   6756 			*linking_status = status;
   6757 		}
   6758 
   6759 		if (GL_TRUE == status)
   6760 		{
   6761 			if (!do_not_detach)
   6762 			{
   6763 				for (glw::GLuint i = 0; i < shader_count; ++i)
   6764 				{
   6765 					if (shader[i].id)
   6766 					{
   6767 						gl.detachShader(program, shader[i].id);
   6768 
   6769 						GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
   6770 					}
   6771 				}
   6772 			}
   6773 		}
   6774 		else
   6775 		{
   6776 			glw::GLint log_size = 0;
   6777 
   6778 			gl.getProgramiv(program, GL_INFO_LOG_LENGTH, &log_size);
   6779 
   6780 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");
   6781 
   6782 			glw::GLchar* log_text = new glw::GLchar[log_size];
   6783 
   6784 			gl.getProgramInfoLog(program, log_size, NULL, &log_text[0]);
   6785 
   6786 			log << tcu::TestLog::Message << "Program linkage has failed due to:\n"
   6787 				<< log_text << "\n"
   6788 				<< tcu::TestLog::EndMessage;
   6789 
   6790 			delete[] log_text;
   6791 
   6792 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");
   6793 
   6794 			throw 0;
   6795 		}
   6796 	}
   6797 	catch (...)
   6798 	{
   6799 		if (program)
   6800 		{
   6801 			gl.deleteProgram(program);
   6802 
   6803 			program = 0;
   6804 		}
   6805 	}
   6806 
   6807 	for (glw::GLuint i = 0; i < shader_count; ++i)
   6808 	{
   6809 		if (0 != shader[i].id)
   6810 		{
   6811 			gl.deleteShader(shader[i].id);
   6812 
   6813 			shader[i].id = 0;
   6814 		}
   6815 	}
   6816 
   6817 	return program;
   6818 }
   6819 
   6820 /** @brief Substitute key with value within source code.
   6821  *
   6822  *  @param [in] source      Source code to be prerocessed.
   6823  *  @param [in] key         Key to be substituted.
   6824  *  @param [in] value       Value to be inserted.
   6825  *
   6826  *  @return Resulting string.
   6827  */
   6828 std::string gl3cts::TransformFeedback::Utilities::preprocessCode(std::string source, std::string key, std::string value)
   6829 {
   6830 	std::string destination = source;
   6831 
   6832 	while (true)
   6833 	{
   6834 		/* Find token in source code. */
   6835 		size_t position = destination.find(key, 0);
   6836 
   6837 		/* No more occurences of this key. */
   6838 		if (position == std::string::npos)
   6839 		{
   6840 			break;
   6841 		}
   6842 
   6843 		/* Replace token with sub_code. */
   6844 		destination.replace(position, key.size(), value);
   6845 	}
   6846 
   6847 	return destination;
   6848 }
   6849 
   6850 /** @brief Convert an integer to a string.
   6851  *
   6852  *  @param [in] i       Integer to be converted.
   6853  *
   6854  *  @return String representing integer.
   6855  */
   6856 std::string gl3cts::TransformFeedback::Utilities::itoa(glw::GLint i)
   6857 {
   6858 	std::stringstream stream;
   6859 
   6860 	stream << i;
   6861 
   6862 	return stream.str();
   6863 }
   6864 
   6865 /** @brief Convert an float to a string.
   6866  *
   6867  *  @param [in] f       Float to be converted.
   6868  *
   6869  *  @return String representing integer.
   6870  */
   6871 std::string gl3cts::TransformFeedback::Utilities::ftoa(glw::GLfloat f)
   6872 {
   6873 	std::stringstream stream;
   6874 
   6875 	stream << f;
   6876 
   6877 	return stream.str();
   6878 }
   6879