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 by DrawTransformFeedbackInstanced and
   1581 	 DrawTransformFeedbackStreamInstanced if a non-zero buffer object name is
   1582 	 bound to an enabled array and the buffer object's data store is currently
   1583 	 mapped */
   1584 
   1585 	gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_transform_feedback_object_0);
   1586 
   1587 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedback call failed.");
   1588 
   1589 	gl.useProgram(m_program_id_with_input_output);
   1590 
   1591 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
   1592 
   1593 	gl.bindVertexArray(m_vertex_array_object);
   1594 
   1595 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   1596 
   1597 	gl.bindBuffer(GL_ARRAY_BUFFER, m_buffer_1);
   1598 
   1599 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   1600 
   1601 	glw::GLint location = gl.getAttribLocation(m_program_id_with_input_output, (glw::GLchar*)"v_input");
   1602 
   1603 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation call failed.");
   1604 
   1605 	if (location < 0)
   1606 	{
   1607 		throw 0;
   1608 	}
   1609 
   1610 	gl.vertexAttribPointer(location, 1, GL_FLOAT, GL_FALSE, 0, NULL);
   1611 
   1612 	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribLPointer call failed.");
   1613 
   1614 	gl.enableVertexAttribArray(0);
   1615 
   1616 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
   1617 
   1618 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer_0);
   1619 
   1620 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed.");
   1621 
   1622 	gl.beginTransformFeedback(GL_POINTS);
   1623 
   1624 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
   1625 
   1626 	gl.drawArrays(GL_POINTS, 0, 1);
   1627 
   1628 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
   1629 
   1630 	gl.endTransformFeedback();
   1631 
   1632 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
   1633 
   1634 	glw::GLvoid* pointer UNUSED = gl.mapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
   1635 
   1636 	GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed.");
   1637 
   1638 	gl.drawTransformFeedbackInstanced(GL_POINTS, m_transform_feedback_object_0, 1);
   1639 
   1640 	if (GL_INVALID_OPERATION != gl.getError())
   1641 	{
   1642 		m_context.getTestContext().getLog()
   1643 			<< tcu::TestLog::Message << "INVALID_OPERATION was not generated by DrawTransformFeedbackInstanced and "
   1644 										"DrawTransformFeedbackStreamInstanced if <mode> did not match geometry shader."
   1645 			<< tcu::TestLog::EndMessage;
   1646 
   1647 		gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   1648 
   1649 		gl.disableVertexAttribArray(location);
   1650 
   1651 		return false;
   1652 	}
   1653 
   1654 	gl.drawTransformFeedbackStreamInstanced(GL_POINTS, m_transform_feedback_object_0, 0, 1);
   1655 
   1656 	if (GL_INVALID_OPERATION != gl.getError())
   1657 	{
   1658 		m_context.getTestContext().getLog()
   1659 			<< tcu::TestLog::Message << "INVALID_OPERATION was not generated by DrawTransformFeedbackInstanced and "
   1660 										"DrawTransformFeedbackStreamInstanced if <mode> did not match geometry shader."
   1661 			<< tcu::TestLog::EndMessage;
   1662 
   1663 		gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   1664 
   1665 		gl.disableVertexAttribArray(location);
   1666 
   1667 		return false;
   1668 	}
   1669 
   1670 	gl.unmapBuffer(GL_ARRAY_BUFFER);
   1671 
   1672 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");
   1673 
   1674 	pointer = DE_NULL;
   1675 
   1676 	gl.disableVertexAttribArray(location);
   1677 
   1678 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray call failed.");
   1679 
   1680 	/*  INVALID_OPERATION is generated if by DrawTransformFeedbackStreamInstanced
   1681 	 if EndTransformFeedback was never called for the object named <id>.
   1682 	 return true */
   1683 
   1684 	gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_transform_feedback_object_1);
   1685 
   1686 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedback call failed.");
   1687 
   1688 	gl.drawTransformFeedbackStreamInstanced(GL_PATCHES, m_transform_feedback_object_1, 0, 1);
   1689 
   1690 	if (GL_INVALID_OPERATION != gl.getError())
   1691 	{
   1692 		m_context.getTestContext().getLog()
   1693 			<< tcu::TestLog::Message << "INVALID_OPERATION was not generated by DrawTransformFeedbackInstanced and "
   1694 										"DrawTransformFeedbackStreamInstanced if <mode> did not match geometry shader."
   1695 			<< tcu::TestLog::EndMessage;
   1696 
   1697 		gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   1698 
   1699 		gl.disableVertexAttribArray(location);
   1700 
   1701 		return false;
   1702 	}
   1703 
   1704 	return true;
   1705 }
   1706 
   1707 const glw::GLchar* gl3cts::TransformFeedback::APIErrors::m_tessellation_control_shader =
   1708 	"#version 400\n"
   1709 	"\n"
   1710 	"layout (vertices = 2 ) out;\n"
   1711 	"\n"
   1712 	"void main()\n"
   1713 	"{\n"
   1714 	"    gl_TessLevelOuter[1]                = 3.0;\n"
   1715 	"    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
   1716 	"}\n";
   1717 
   1718 const glw::GLchar* gl3cts::TransformFeedback::APIErrors::m_tessellation_evaluation_shader =
   1719 	"#version 400\n"
   1720 	"\n"
   1721 	"layout(isolines, equal_spacing, ccw) in;\n"
   1722 	"\n"
   1723 	"out float result;\n"
   1724 	"\n"
   1725 	"void main()\n"
   1726 	"{\n"
   1727 	"    result      = 0.5;\n"
   1728 	"    gl_Position = gl_in[0].gl_Position + gl_in[1].gl_Position + gl_in[2].gl_Position;\n"
   1729 	"}\n";
   1730 
   1731 const glw::GLchar* gl3cts::TransformFeedback::APIErrors::m_geometry_shader =
   1732 	"#version 150\n"
   1733 	"\n"
   1734 	"layout(points) in;\n"
   1735 	"layout(points, max_vertices = 2) out;\n"
   1736 	"\n"
   1737 	"out float result;\n"
   1738 	"\n"
   1739 	"void main()\n"
   1740 	"{\n"
   1741 	"    gl_Position = gl_in[0].gl_Position + vec4(0.0, 0.0, 0.0, 0.0);\n"
   1742 	"    result = 0.0;\n"
   1743 	"    EmitVertex();\n"
   1744 	"\n"
   1745 	"    gl_Position = gl_in[0].gl_Position + vec4(1.0, 0.0, 0.0, 0.0);\n"
   1746 	"    result = 1.0;\n"
   1747 	"    EmitVertex();\n"
   1748 	"}\n";
   1749 
   1750 const glw::GLchar* gl3cts::TransformFeedback::APIErrors::s_vertex_shader_with_output =
   1751 	"#version 130\n"
   1752 	"\n"
   1753 	"out float result;\n"
   1754 	"\n"
   1755 	"void main()\n"
   1756 	"{\n"
   1757 	"    result      = float(gl_VertexID);\n"
   1758 	"    gl_Position = vec4(1.0);\n"
   1759 	"}\n";
   1760 
   1761 const glw::GLchar* gl3cts::TransformFeedback::APIErrors::s_vertex_shader_with_input_output =
   1762 	"#version 130\n"
   1763 	"\n"
   1764 	"in float v_input;\n"
   1765 	"\n"
   1766 	"out float result;\n"
   1767 	"\n"
   1768 	"void main()\n"
   1769 	"{\n"
   1770 	"    result      = float(gl_VertexID);\n"
   1771 	"    gl_Position = vec4(v_input);\n"
   1772 	"}\n";
   1773 
   1774 const glw::GLchar* gl3cts::TransformFeedback::APIErrors::s_vertex_shader_without_output =
   1775 	"#version 130\n"
   1776 	"\n"
   1777 	"void main()\n"
   1778 	"{\n"
   1779 	"    gl_Position = vec4(1.0);\n"
   1780 	"}\n";
   1781 
   1782 const glw::GLchar* gl3cts::TransformFeedback::APIErrors::s_fragment_shader = "#version 130\n"
   1783 																			 "\n"
   1784 																			 "out vec4 color;\n"
   1785 																			 "\n"
   1786 																			 "void main()\n"
   1787 																			 "{\n"
   1788 																			 "    color = vec4(1.0);\n"
   1789 																			 "}\n";
   1790 
   1791 const glw::GLchar* gl3cts::TransformFeedback::APIErrors::m_varying_name = "result";
   1792 
   1793 const glw::GLfloat gl3cts::TransformFeedback::APIErrors::m_buffer_1_data[] = { 3.14159265359f, 2.7182818f };
   1794 
   1795 const glw::GLsizei gl3cts::TransformFeedback::APIErrors::m_buffer_1_size =
   1796 	sizeof(gl3cts::TransformFeedback::APIErrors::m_buffer_1_data);
   1797 
   1798 /*-----------------------------------------------------------------------------------------------*/
   1799 
   1800 gl3cts::TransformFeedback::LinkingErrors::LinkingErrors(deqp::Context& context)
   1801 	: deqp::TestCase(context, "linking_errors_test", "Transform Feedback Linking Errors Test"), m_context(context)
   1802 {
   1803 	/* Left intentionally blank. */
   1804 }
   1805 
   1806 gl3cts::TransformFeedback::LinkingErrors::~LinkingErrors(void)
   1807 {
   1808 }
   1809 
   1810 tcu::TestNode::IterateResult gl3cts::TransformFeedback::LinkingErrors::iterate(void)
   1811 {
   1812 	bool is_ok		= true;
   1813 	bool test_error = false;
   1814 
   1815 	try
   1816 	{
   1817 		is_ok = is_ok && testNoVertexNoGeometry();
   1818 		is_ok = is_ok && testInvalidVarying();
   1819 		is_ok = is_ok && testRepeatedVarying();
   1820 		is_ok = is_ok && testTooManyVaryings();
   1821 	}
   1822 	catch (...)
   1823 	{
   1824 		is_ok	  = false;
   1825 		test_error = true;
   1826 	}
   1827 
   1828 	/* Result's setup. */
   1829 	if (is_ok)
   1830 	{
   1831 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   1832 	}
   1833 	else
   1834 	{
   1835 		if (test_error)
   1836 		{
   1837 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   1838 		}
   1839 		else
   1840 		{
   1841 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   1842 		}
   1843 	}
   1844 
   1845 	return STOP;
   1846 }
   1847 
   1848 bool gl3cts::TransformFeedback::LinkingErrors::testNoVertexNoGeometry(void)
   1849 {
   1850 	/* Functions handler */
   1851 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1852 
   1853 	/*  Check if link process fails under the following conditions:
   1854 	 <count> specified by TransformFeedbackVaryings is non-zero and program has
   1855 	 neither vertex nor geometry shader; */
   1856 
   1857 	glw::GLint linking_status = 1;
   1858 
   1859 	glw::GLuint program = gl3cts::TransformFeedback::Utilities::buildProgram(
   1860 		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, NULL, s_fragment_shader,
   1861 		&s_valid_transform_feedback_varying, 1, GL_INTERLEAVED_ATTRIBS, false, &linking_status);
   1862 
   1863 	if ((GL_FALSE != linking_status) || program)
   1864 	{
   1865 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1866 											<< "Linking unexpectedly succeded when Transform Feedback varying was "
   1867 											   "specified but program had neither vertex nor geometry shader stages."
   1868 											<< tcu::TestLog::EndMessage;
   1869 
   1870 		if (program)
   1871 		{
   1872 			gl.deleteProgram(program);
   1873 		}
   1874 
   1875 		return false;
   1876 	}
   1877 
   1878 	/* Log success. */
   1879 	m_context.getTestContext().getLog() << tcu::TestLog::Message
   1880 										<< "Linking failed as expected when Transform Feedback varying was specified "
   1881 										   "but program had neither vertex nor geometry shader stages."
   1882 										<< tcu::TestLog::EndMessage;
   1883 
   1884 	return true;
   1885 }
   1886 
   1887 bool gl3cts::TransformFeedback::LinkingErrors::testInvalidVarying(void)
   1888 {
   1889 	/* Functions handler */
   1890 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1891 
   1892 	/*  Check if link process fails under the following conditions:
   1893 	 <varyings> specified by TransformFeedbackVaryings contains name of
   1894 	 variable that is not available for capture; */
   1895 
   1896 	std::string vertex_shader(s_vertex_shader_template);
   1897 
   1898 	vertex_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(
   1899 		vertex_shader, "TEMPLATE_INPUT_OUTPUT_DECLARATIONS", "in float data;\n");
   1900 	vertex_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(vertex_shader, "TEMPLATE_OUTPUT_SETTERS", "");
   1901 
   1902 	glw::GLint linking_status = 1;
   1903 
   1904 	glw::GLuint program = gl3cts::TransformFeedback::Utilities::buildProgram(
   1905 		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, vertex_shader.c_str(), s_fragment_shader,
   1906 		&s_invalid_transform_feedback_varying, 1, GL_INTERLEAVED_ATTRIBS, false, &linking_status);
   1907 
   1908 	if ((GL_FALSE != linking_status) || program)
   1909 	{
   1910 		m_context.getTestContext().getLog()
   1911 			<< tcu::TestLog::Message
   1912 			<< "Linking unexpectedly succeded when Transform Feedback varying was specified with name of variable ("
   1913 			<< s_invalid_transform_feedback_varying << ") that is not available for capture."
   1914 			<< tcu::TestLog::EndMessage;
   1915 
   1916 		if (program)
   1917 		{
   1918 			gl.deleteProgram(program);
   1919 		}
   1920 
   1921 		return false;
   1922 	}
   1923 
   1924 	/* Log success. */
   1925 	m_context.getTestContext().getLog()
   1926 		<< tcu::TestLog::Message
   1927 		<< "Linking failed as expected when Transform Feedback varying was specified with name of variable ("
   1928 		<< s_invalid_transform_feedback_varying << ") that is not available for capture." << tcu::TestLog::EndMessage;
   1929 
   1930 	return true;
   1931 }
   1932 
   1933 bool gl3cts::TransformFeedback::LinkingErrors::testRepeatedVarying(void)
   1934 {
   1935 	/* Functions handler */
   1936 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1937 
   1938 	/*  Check if link process fails under the following conditions:
   1939 	 <varyings> specified by TransformFeedbackVaryings contains name of
   1940 	 variable more than once; */
   1941 
   1942 	std::string vertex_shader(s_vertex_shader_template);
   1943 
   1944 	vertex_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(
   1945 		vertex_shader, "TEMPLATE_INPUT_OUTPUT_DECLARATIONS", "out float result;\n");
   1946 	vertex_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(vertex_shader, "TEMPLATE_OUTPUT_SETTERS",
   1947 																		 "    result = 0.577215664901532;\n");
   1948 
   1949 	glw::GLint linking_status = 1;
   1950 
   1951 	glw::GLuint program = gl3cts::TransformFeedback::Utilities::buildProgram(
   1952 		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, vertex_shader.c_str(), s_fragment_shader,
   1953 		s_repeated_transform_feedback_varying, s_repeated_transform_feedback_varying_count, GL_INTERLEAVED_ATTRIBS,
   1954 		false, &linking_status);
   1955 
   1956 	if ((GL_FALSE != linking_status) || program)
   1957 	{
   1958 		m_context.getTestContext().getLog()
   1959 			<< tcu::TestLog::Message
   1960 			<< "Linking unexpectedly succeded when Transform Feedback varying was specified twice."
   1961 			<< tcu::TestLog::EndMessage;
   1962 
   1963 		if (program)
   1964 		{
   1965 			gl.deleteProgram(program);
   1966 		}
   1967 
   1968 		return false;
   1969 	}
   1970 
   1971 	/* Log success. */
   1972 	m_context.getTestContext().getLog()
   1973 		<< tcu::TestLog::Message << "Linking failed as expected when Transform Feedback varying was specified twice."
   1974 		<< tcu::TestLog::EndMessage;
   1975 
   1976 	return true;
   1977 }
   1978 
   1979 bool gl3cts::TransformFeedback::LinkingErrors::testTooManyVaryings(void)
   1980 {
   1981 	/* Functions handler */
   1982 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1983 
   1984 	/*  Check if link process fails under the following conditions:
   1985 	 number of components specified to capture exceeds limits
   1986 	 MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS or
   1987 	 MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS. */
   1988 
   1989 	/* Fetching limits. */
   1990 	glw::GLint max_transform_feedback_separate_components	= 0;
   1991 	glw::GLint max_transform_feedback_interleaved_components = 0;
   1992 
   1993 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_transform_feedback_separate_components);
   1994 
   1995 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   1996 
   1997 	if (max_transform_feedback_separate_components == 0)
   1998 	{
   1999 		throw 0;
   2000 	}
   2001 
   2002 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components);
   2003 
   2004 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   2005 
   2006 	if (max_transform_feedback_interleaved_components == 0)
   2007 	{
   2008 		throw 0;
   2009 	}
   2010 
   2011 	glw::GLint more_than_max_transform_feedback_components =
   2012 		deMax32(max_transform_feedback_separate_components, max_transform_feedback_interleaved_components) + 1;
   2013 
   2014 	/* Preparing source code. */
   2015 	std::string						vertex_shader(s_vertex_shader_template);
   2016 	std::string						transform_feedback_variable_declarations("");
   2017 	std::string						transform_feedback_variable_setters("");
   2018 	std::vector<std::string>		transform_feedback_varyings(more_than_max_transform_feedback_components);
   2019 	std::vector<const glw::GLchar*> transform_feedback_varyings_c(more_than_max_transform_feedback_components);
   2020 
   2021 	for (glw::GLint i = 0; i < more_than_max_transform_feedback_components; ++i)
   2022 	{
   2023 		std::string varying = "result_";
   2024 		varying.append(gl3cts::TransformFeedback::Utilities::itoa(i));
   2025 
   2026 		transform_feedback_varyings[i] = varying;
   2027 
   2028 		transform_feedback_varyings_c[i] = transform_feedback_varyings[i].c_str();
   2029 
   2030 		transform_feedback_variable_declarations.append("out float ");
   2031 		transform_feedback_variable_declarations.append(varying);
   2032 		transform_feedback_variable_declarations.append(";\n");
   2033 
   2034 		transform_feedback_variable_setters.append("    ");
   2035 		transform_feedback_variable_setters.append(varying);
   2036 		transform_feedback_variable_setters.append(" = ");
   2037 		transform_feedback_variable_setters.append(gl3cts::TransformFeedback::Utilities::itoa(i * i));
   2038 		transform_feedback_variable_setters.append(".0;\n");
   2039 	}
   2040 
   2041 	vertex_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(
   2042 		vertex_shader, "TEMPLATE_INPUT_OUTPUT_DECLARATIONS", transform_feedback_variable_declarations);
   2043 	vertex_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(vertex_shader, "TEMPLATE_OUTPUT_SETTERS",
   2044 																		 transform_feedback_variable_setters);
   2045 
   2046 	glw::GLuint program = gl3cts::TransformFeedback::Utilities::buildProgram(
   2047 		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, vertex_shader.c_str(), s_fragment_shader,
   2048 		&transform_feedback_varyings_c[0], more_than_max_transform_feedback_components, GL_INTERLEAVED_ATTRIBS);
   2049 
   2050 	/* Note: we check for program as not only linking shall fail, but also glTransformFeedbackVaryings shall return an error. */
   2051 
   2052 	if (program)
   2053 	{
   2054 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   2055 											<< "Linking unexpectedly succeded when too many Transform Feedback varying "
   2056 											   "were specified in INTERLEAVED mode."
   2057 											<< tcu::TestLog::EndMessage;
   2058 
   2059 		if (program)
   2060 		{
   2061 			gl.deleteProgram(program);
   2062 		}
   2063 
   2064 		return false;
   2065 	}
   2066 
   2067 	program = gl3cts::TransformFeedback::Utilities::buildProgram(
   2068 		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, vertex_shader.c_str(), s_fragment_shader,
   2069 		&transform_feedback_varyings_c[0], more_than_max_transform_feedback_components, GL_SEPARATE_ATTRIBS);
   2070 
   2071 	if (program)
   2072 	{
   2073 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   2074 											<< "Linking unexpectedly succeded when too many Transform Feedback "
   2075 											   "varyings were specified in SEPARATE mode."
   2076 											<< tcu::TestLog::EndMessage;
   2077 
   2078 		if (program)
   2079 		{
   2080 			gl.deleteProgram(program);
   2081 		}
   2082 
   2083 		return false;
   2084 	}
   2085 
   2086 	/* Log success. */
   2087 	m_context.getTestContext().getLog()
   2088 		<< tcu::TestLog::Message
   2089 		<< "Linking failed as expected when too many Transform Feedback varyings were specified."
   2090 		<< tcu::TestLog::EndMessage;
   2091 
   2092 	return true;
   2093 }
   2094 
   2095 const glw::GLchar* gl3cts::TransformFeedback::LinkingErrors::s_fragment_shader = "#version 130\n"
   2096 																				 "\n"
   2097 																				 "out vec4 color;\n"
   2098 																				 "\n"
   2099 																				 "void main()\n"
   2100 																				 "{\n"
   2101 																				 "    color = vec4(1.0);\n"
   2102 																				 "}\n";
   2103 
   2104 const glw::GLchar* gl3cts::TransformFeedback::LinkingErrors::s_vertex_shader_template =
   2105 	"#version 130\n"
   2106 	"\n"
   2107 	"TEMPLATE_INPUT_OUTPUT_DECLARATIONS"
   2108 	"\n"
   2109 	"void main()\n"
   2110 	"{\n"
   2111 	"TEMPLATE_OUTPUT_SETTERS"
   2112 	"\n"
   2113 	"    gl_Position = vec4(1.618033988749);\n"
   2114 	"}\n";
   2115 
   2116 const glw::GLchar* gl3cts::TransformFeedback::LinkingErrors::s_valid_transform_feedback_varying = "result";
   2117 
   2118 const glw::GLchar* gl3cts::TransformFeedback::LinkingErrors::s_invalid_transform_feedback_varying = "data";
   2119 
   2120 const glw::GLchar* gl3cts::TransformFeedback::LinkingErrors::s_repeated_transform_feedback_varying[] = { "result",
   2121 																										 "result" };
   2122 
   2123 const glw::GLsizei gl3cts::TransformFeedback::LinkingErrors::s_repeated_transform_feedback_varying_count =
   2124 	sizeof(s_repeated_transform_feedback_varying) / sizeof(s_repeated_transform_feedback_varying[0]);
   2125 
   2126 /*-----------------------------------------------------------------------------------------------*/
   2127 
   2128 const glw::GLint gl3cts::TransformFeedback::Limits::s_min_value_of_max_transform_feedback_interleaved_components = 64;
   2129 const glw::GLint gl3cts::TransformFeedback::Limits::s_min_value_of_max_transform_feedback_separate_attribs		 = 4;
   2130 const glw::GLint gl3cts::TransformFeedback::Limits::s_min_value_of_max_transform_feedback_separate_components	= 4;
   2131 const glw::GLint gl3cts::TransformFeedback::Limits::s_min_value_of_max_transform_feedback_buffers				 = 4;
   2132 const glw::GLint gl3cts::TransformFeedback::Limits::s_min_value_of_max_vertex_streams							 = 1;
   2133 
   2134 gl3cts::TransformFeedback::Limits::Limits(deqp::Context& context)
   2135 	: deqp::TestCase(context, "limits_test", "Transform Feedback Limits Test"), m_context(context)
   2136 {
   2137 }
   2138 
   2139 gl3cts::TransformFeedback::Limits::~Limits(void)
   2140 {
   2141 }
   2142 
   2143 tcu::TestNode::IterateResult gl3cts::TransformFeedback::Limits::iterate(void)
   2144 {
   2145 	/* Initializations. */
   2146 	bool is_at_least_gl_30 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(3, 0)));
   2147 	bool is_at_least_gl_40 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 0)));
   2148 
   2149 	bool is_ext_tf_1 = m_context.getContextInfo().isExtensionSupported("GL_EXT_transform_feedback");
   2150 	bool is_arb_tf_3 = m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback3");
   2151 
   2152 	bool is_ok		= true;
   2153 	bool test_error = false;
   2154 
   2155 	/* Tests. */
   2156 	try
   2157 	{
   2158 		if (is_at_least_gl_30 || is_ext_tf_1)
   2159 		{
   2160 			is_ok = is_ok && test_max_transform_feedback_interleaved_components();
   2161 			is_ok = is_ok && test_max_transform_feedback_separate_attribs();
   2162 			is_ok = is_ok && test_max_transform_feedback_separate_components();
   2163 		}
   2164 
   2165 		if (is_at_least_gl_40 || is_arb_tf_3)
   2166 		{
   2167 			is_ok = is_ok && test_max_transform_feedback_buffers();
   2168 			is_ok = is_ok && test_max_vertex_streams();
   2169 		}
   2170 	}
   2171 	catch (...)
   2172 	{
   2173 		is_ok	  = false;
   2174 		test_error = true;
   2175 	}
   2176 
   2177 	/* Result's setup. */
   2178 	if (is_ok)
   2179 	{
   2180 		/* Log success. */
   2181 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Limits are in range of specification."
   2182 											<< tcu::TestLog::EndMessage;
   2183 
   2184 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   2185 	}
   2186 	else
   2187 	{
   2188 		if (test_error)
   2189 		{
   2190 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   2191 		}
   2192 		else
   2193 		{
   2194 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   2195 		}
   2196 	}
   2197 
   2198 	return STOP;
   2199 }
   2200 
   2201 bool gl3cts::TransformFeedback::Limits::test_max_transform_feedback_interleaved_components(void)
   2202 {
   2203 	/* Functions handler */
   2204 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2205 
   2206 	/* Check that MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS is at least 64. */
   2207 	glw::GLint max_transform_feedback_interleaved_components = 0;
   2208 
   2209 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &max_transform_feedback_interleaved_components);
   2210 
   2211 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   2212 
   2213 	if (max_transform_feedback_interleaved_components < s_min_value_of_max_transform_feedback_interleaved_components)
   2214 	{
   2215 		m_context.getTestContext().getLog()
   2216 			<< tcu::TestLog::Message << "GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS is equal to "
   2217 			<< max_transform_feedback_interleaved_components << " which is less than expected "
   2218 			<< s_min_value_of_max_transform_feedback_interleaved_components << "." << tcu::TestLog::EndMessage;
   2219 		return false;
   2220 	}
   2221 
   2222 	return true;
   2223 }
   2224 
   2225 bool gl3cts::TransformFeedback::Limits::test_max_transform_feedback_separate_attribs(void)
   2226 {
   2227 	/* Functions handler */
   2228 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2229 
   2230 	/* Check that MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS is at least 4. */
   2231 	glw::GLint max_transform_feedback_separate_attribs = 0;
   2232 
   2233 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &max_transform_feedback_separate_attribs);
   2234 
   2235 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   2236 
   2237 	if (max_transform_feedback_separate_attribs < s_min_value_of_max_transform_feedback_separate_attribs)
   2238 	{
   2239 		m_context.getTestContext().getLog()
   2240 			<< tcu::TestLog::Message << "GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS is equal to "
   2241 			<< max_transform_feedback_separate_attribs << " which is less than expected "
   2242 			<< s_min_value_of_max_transform_feedback_separate_attribs << "." << tcu::TestLog::EndMessage;
   2243 		return false;
   2244 	}
   2245 
   2246 	return true;
   2247 }
   2248 
   2249 bool gl3cts::TransformFeedback::Limits::test_max_transform_feedback_separate_components(void)
   2250 {
   2251 	/* Functions handler */
   2252 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2253 
   2254 	/* Check that MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS is at least 4. */
   2255 	glw::GLint max_transform_feedback_separate_components = 0;
   2256 
   2257 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_transform_feedback_separate_components);
   2258 
   2259 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   2260 
   2261 	if (max_transform_feedback_separate_components < s_min_value_of_max_transform_feedback_separate_components)
   2262 	{
   2263 		m_context.getTestContext().getLog()
   2264 			<< tcu::TestLog::Message << "GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS is equal to "
   2265 			<< max_transform_feedback_separate_components << " which is less than expected "
   2266 			<< s_min_value_of_max_transform_feedback_separate_components << "." << tcu::TestLog::EndMessage;
   2267 		return false;
   2268 	}
   2269 
   2270 	return true;
   2271 }
   2272 
   2273 bool gl3cts::TransformFeedback::Limits::test_max_transform_feedback_buffers(void)
   2274 {
   2275 	/* Functions handler */
   2276 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2277 
   2278 	/* Check that MAX_TRANSFORM_FEEDBACK_BUFFERS is at least 4. */
   2279 	glw::GLint max_transform_feedback_buffers = 0;
   2280 
   2281 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers);
   2282 
   2283 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   2284 
   2285 	if (max_transform_feedback_buffers < s_min_value_of_max_transform_feedback_buffers)
   2286 	{
   2287 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "MAX_TRANSFORM_FEEDBACK_BUFFERS is equal to "
   2288 											<< max_transform_feedback_buffers << " which is less than expected "
   2289 											<< s_min_value_of_max_transform_feedback_buffers << "."
   2290 											<< tcu::TestLog::EndMessage;
   2291 		return false;
   2292 	}
   2293 
   2294 	return true;
   2295 }
   2296 
   2297 bool gl3cts::TransformFeedback::Limits::test_max_vertex_streams(void)
   2298 {
   2299 	/* Functions handler */
   2300 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2301 
   2302 	/* Check that MAX_VERTEX_STREAMS is at least 1. */
   2303 	glw::GLint max_vertex_streams = 0;
   2304 
   2305 	gl.getIntegerv(GL_MAX_VERTEX_STREAMS, &max_vertex_streams);
   2306 
   2307 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   2308 
   2309 	if (max_vertex_streams < s_min_value_of_max_vertex_streams)
   2310 	{
   2311 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "MAX_VERTEX_STREAMS is equal to "
   2312 											<< max_vertex_streams << " which is less than expected "
   2313 											<< s_min_value_of_max_vertex_streams << "." << tcu::TestLog::EndMessage;
   2314 		return false;
   2315 	}
   2316 
   2317 	return true;
   2318 }
   2319 
   2320 /*-----------------------------------------------------------------------------------------------*/
   2321 
   2322 gl3cts::TransformFeedback::CaptureVertexInterleaved::CaptureVertexInterleaved(deqp::Context& context,
   2323 																			  const char*	test_name,
   2324 																			  const char*	test_description)
   2325 	: deqp::TestCase(context, test_name, test_description)
   2326 	, m_context(context)
   2327 	, m_program(0)
   2328 	, m_framebuffer(0)
   2329 	, m_renderbuffer(0)
   2330 	, m_buffer(0)
   2331 	, m_buffer_size(0)
   2332 	, m_vertex_array_object(0)
   2333 	, m_max_transform_feedback_components(0)
   2334 	, m_attrib_type(GL_INTERLEAVED_ATTRIBS)
   2335 	, m_max_vertices_drawn(8)
   2336 	, m_glBindBufferOffsetEXT(DE_NULL)
   2337 {
   2338 }
   2339 
   2340 gl3cts::TransformFeedback::CaptureVertexInterleaved::~CaptureVertexInterleaved(void)
   2341 {
   2342 }
   2343 
   2344 tcu::TestNode::IterateResult gl3cts::TransformFeedback::CaptureVertexInterleaved::iterate(void)
   2345 {
   2346 	/* Functions handler */
   2347 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2348 
   2349 	/* Initializations. */
   2350 	bool is_at_least_gl_30 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(3, 0)));
   2351 	bool is_ext_tf_1	   = m_context.getContextInfo().isExtensionSupported("GL_EXT_transform_feedback");
   2352 
   2353 	bool is_ok		= true;
   2354 	bool test_error = false;
   2355 
   2356 	try
   2357 	{
   2358 		if (is_ext_tf_1)
   2359 		{
   2360 			/* Extension query. */
   2361 			m_glBindBufferOffsetEXT =
   2362 				(BindBufferOffsetEXT_ProcAddress)m_context.getRenderContext().getProcAddress("glBindBufferOffsetEXT");
   2363 
   2364 			if (DE_NULL == m_glBindBufferOffsetEXT)
   2365 			{
   2366 				throw 0;
   2367 			}
   2368 		}
   2369 
   2370 		if (is_at_least_gl_30 || is_ext_tf_1)
   2371 		{
   2372 			fetchLimits();
   2373 			buildProgram();
   2374 			createFramebuffer();
   2375 			createTransformFeedbackBuffer();
   2376 			createVertexArrayObject();
   2377 
   2378 			gl.useProgram(m_program);
   2379 
   2380 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
   2381 
   2382 			for (glw::GLint i_bind_case = 0; (i_bind_case < BIND_BUFFER_CASES_COUNT) && is_ok; ++i_bind_case)
   2383 			{
   2384 				if ((i_bind_case == BIND_BUFFER_OFFSET_CASE) && (DE_NULL == m_glBindBufferOffsetEXT))
   2385 				{
   2386 					continue;
   2387 				}
   2388 
   2389 				bindBuffer((BindBufferCase)i_bind_case);
   2390 
   2391 				for (glw::GLuint i_primitive_case = 0; (i_primitive_case < s_primitive_cases_count) && is_ok;
   2392 					 ++i_primitive_case)
   2393 				{
   2394 					draw(i_primitive_case);
   2395 
   2396 					is_ok = is_ok && checkFramebuffer(s_primitive_cases[i_primitive_case]);
   2397 					is_ok = is_ok && checkTransformFeedbackBuffer((BindBufferCase)i_bind_case,
   2398 																  s_primitive_cases[i_primitive_case]);
   2399 				}
   2400 			}
   2401 		}
   2402 	}
   2403 	catch (...)
   2404 	{
   2405 		is_ok	  = false;
   2406 		test_error = true;
   2407 	}
   2408 
   2409 	/* Clean objects. */
   2410 	clean();
   2411 
   2412 	/* Result's setup. */
   2413 	if (is_ok)
   2414 	{
   2415 		/* Log success. */
   2416 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Capture Vertex have passed."
   2417 											<< tcu::TestLog::EndMessage;
   2418 
   2419 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   2420 	}
   2421 	else
   2422 	{
   2423 		if (test_error)
   2424 		{
   2425 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   2426 		}
   2427 		else
   2428 		{
   2429 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   2430 		}
   2431 	}
   2432 
   2433 	return STOP;
   2434 }
   2435 
   2436 void gl3cts::TransformFeedback::CaptureVertexInterleaved::fetchLimits(void)
   2437 {
   2438 	/* Functions handler */
   2439 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2440 
   2441 	/* Fetching limits. */
   2442 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &m_max_transform_feedback_components);
   2443 
   2444 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   2445 
   2446 	if (m_max_transform_feedback_components == 0)
   2447 	{
   2448 		throw 0;
   2449 	}
   2450 
   2451 	glw::GLint max_varyings_components = 0;
   2452 
   2453 	gl.getIntegerv(GL_MAX_VARYING_COMPONENTS, &max_varyings_components);
   2454 
   2455 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   2456 
   2457 	if (max_varyings_components == 0)
   2458 	{
   2459 		throw 0;
   2460 	}
   2461 
   2462 	if (m_max_transform_feedback_components > max_varyings_components)
   2463 	{
   2464 		m_max_transform_feedback_components = max_varyings_components;
   2465 	}
   2466 }
   2467 
   2468 void gl3cts::TransformFeedback::CaptureVertexInterleaved::buildProgram(void)
   2469 {
   2470 	/* Functions handler */
   2471 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2472 
   2473 	/* Preparing source code. */
   2474 	std::string vertex_shader(s_vertex_shader_source_code_template); /* Storage for vertex shader source code. */
   2475 	std::string transform_feedback_variable_declarations(
   2476 		""); /* String to contain all custom outputs from vertex shader. */
   2477 	std::string transform_feedback_variable_setters(
   2478 		""); /* String containing all initializations of custom outputs from vertex shader. */
   2479 	std::vector<std::string> transform_feedback_varyings(m_max_transform_feedback_components); /* Varyings array. */
   2480 	std::vector<const glw::GLchar*> transform_feedback_varyings_c(
   2481 		m_max_transform_feedback_components); /* Varyings array in C form to pass to the GL. */
   2482 
   2483 	glw::GLint user_defined_transform_feedback_interleaved_varyings_count =
   2484 		m_max_transform_feedback_components /* total max to be written by the shader */
   2485 			/ 4								/* components per vec4 */
   2486 		- 1 /* gl_Position */;
   2487 
   2488 	glw::GLint all_transform_feedback_interleaved_varyings_count =
   2489 		user_defined_transform_feedback_interleaved_varyings_count + 1 /* gl_Position */;
   2490 
   2491 	/* Most of varyings is declarated output variables. */
   2492 	for (glw::GLint i = 0; i < user_defined_transform_feedback_interleaved_varyings_count; ++i)
   2493 	{
   2494 		std::string varying = "result_";
   2495 		varying.append(gl3cts::TransformFeedback::Utilities::itoa(i));
   2496 
   2497 		transform_feedback_varyings[i] = varying;
   2498 
   2499 		transform_feedback_varyings_c[i] = transform_feedback_varyings[i].c_str();
   2500 
   2501 		transform_feedback_variable_declarations.append("out vec4 ");
   2502 		transform_feedback_variable_declarations.append(varying);
   2503 		transform_feedback_variable_declarations.append(";\n");
   2504 
   2505 		transform_feedback_variable_setters.append("    ");
   2506 		transform_feedback_variable_setters.append(varying);
   2507 		transform_feedback_variable_setters.append(" = vec4(");
   2508 		transform_feedback_variable_setters.append(gl3cts::TransformFeedback::Utilities::itoa(i * 4));
   2509 		transform_feedback_variable_setters.append(".0, ");
   2510 		transform_feedback_variable_setters.append(gl3cts::TransformFeedback::Utilities::itoa(i * 4 + 1));
   2511 		transform_feedback_variable_setters.append(".0, ");
   2512 		transform_feedback_variable_setters.append(gl3cts::TransformFeedback::Utilities::itoa(i * 4 + 2));
   2513 		transform_feedback_variable_setters.append(".0, ");
   2514 		transform_feedback_variable_setters.append(gl3cts::TransformFeedback::Utilities::itoa(i * 4 + 3));
   2515 		transform_feedback_variable_setters.append(".0);\n");
   2516 	}
   2517 
   2518 	/* Last four varying components are gl_Position components. */
   2519 	transform_feedback_varyings[user_defined_transform_feedback_interleaved_varyings_count] = "gl_Position";
   2520 
   2521 	transform_feedback_varyings_c[user_defined_transform_feedback_interleaved_varyings_count] =
   2522 		transform_feedback_varyings[user_defined_transform_feedback_interleaved_varyings_count].c_str();
   2523 
   2524 	/* Preprocess vertex shader source code template. */
   2525 	vertex_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(
   2526 		vertex_shader, "TEMPLATE_INPUT_OUTPUT_DECLARATIONS", transform_feedback_variable_declarations);
   2527 	vertex_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(vertex_shader, "TEMPLATE_OUTPUT_SETTERS",
   2528 																		 transform_feedback_variable_setters);
   2529 	vertex_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(
   2530 		vertex_shader, "TEMPLATE_RASTERIZATION_EPSILON",
   2531 		gl3cts::TransformFeedback::Utilities::ftoa(s_rasterization_epsilon));
   2532 
   2533 	/* Compile, link and check. */
   2534 	m_program = gl3cts::TransformFeedback::Utilities::buildProgram(
   2535 		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, vertex_shader.c_str(), s_fragment_shader_source_code,
   2536 		&transform_feedback_varyings_c[0], all_transform_feedback_interleaved_varyings_count, m_attrib_type);
   2537 
   2538 	if (0 == m_program)
   2539 	{
   2540 		throw 0;
   2541 	}
   2542 }
   2543 
   2544 void gl3cts::TransformFeedback::CaptureVertexInterleaved::createFramebuffer(void)
   2545 {
   2546 	/* Functions handler */
   2547 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2548 
   2549 	/* Setting clear color */
   2550 	gl.clearColor(0.f, 0.f, 0.f, 1.f);
   2551 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");
   2552 
   2553 	/* Creating framebuffer */
   2554 	gl.genFramebuffers(1, &m_framebuffer);
   2555 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
   2556 
   2557 	gl.genRenderbuffers(1, &m_renderbuffer);
   2558 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
   2559 
   2560 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
   2561 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
   2562 
   2563 	gl.bindRenderbuffer(GL_RENDERBUFFER, m_renderbuffer);
   2564 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
   2565 
   2566 	gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32F, s_framebuffer_size, s_framebuffer_size);
   2567 	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed.");
   2568 
   2569 	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_renderbuffer);
   2570 	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed.");
   2571 
   2572 	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
   2573 	{
   2574 		throw 0;
   2575 	}
   2576 
   2577 	gl.viewport(0, 0, s_framebuffer_size, s_framebuffer_size);
   2578 	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
   2579 }
   2580 
   2581 void gl3cts::TransformFeedback::CaptureVertexInterleaved::createTransformFeedbackBuffer(void)
   2582 {
   2583 	/* Functions handler */
   2584 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2585 
   2586 	/* Creating xfb buffer */
   2587 	gl.genBuffers(1, &m_buffer);
   2588 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   2589 
   2590 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_buffer);
   2591 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   2592 
   2593 	m_buffer_size =
   2594 		static_cast<glw::GLuint>(m_max_transform_feedback_components * m_max_vertices_drawn * sizeof(glw::GLfloat));
   2595 
   2596 	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, m_buffer_size, NULL, GL_DYNAMIC_READ);
   2597 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
   2598 }
   2599 
   2600 void gl3cts::TransformFeedback::CaptureVertexInterleaved::createVertexArrayObject(void)
   2601 {
   2602 	/* Functions handler */
   2603 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2604 
   2605 	/* VAO Creations */
   2606 	gl.genVertexArrays(1, &m_vertex_array_object);
   2607 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
   2608 
   2609 	gl.bindVertexArray(m_vertex_array_object);
   2610 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   2611 }
   2612 
   2613 void gl3cts::TransformFeedback::CaptureVertexInterleaved::draw(glw::GLuint primitive_case)
   2614 {
   2615 	/* Functions handler */
   2616 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2617 
   2618 	/* Draw */
   2619 	gl.clear(GL_COLOR_BUFFER_BIT);
   2620 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed.");
   2621 
   2622 	gl.beginTransformFeedback(s_primitive_cases_xfb[primitive_case]);
   2623 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedbac call failed.");
   2624 
   2625 	gl.drawElements(s_primitive_cases[primitive_case], s_element_indices_counts[primitive_case], GL_UNSIGNED_INT,
   2626 					s_element_indices[primitive_case]);
   2627 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawElements call failed.");
   2628 
   2629 	gl.endTransformFeedback();
   2630 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedbac call failed.");
   2631 }
   2632 
   2633 bool gl3cts::TransformFeedback::CaptureVertexInterleaved::checkFramebuffer(glw::GLenum primitive_type UNUSED)
   2634 {
   2635 	/* Functions handler */
   2636 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2637 
   2638 	/* Fetch framebuffer. */
   2639 	std::vector<glw::GLfloat> pixels(s_framebuffer_size * s_framebuffer_size);
   2640 
   2641 	if ((s_framebuffer_size > 0) && (s_framebuffer_size > 0))
   2642 	{
   2643 		gl.readPixels(0, 0, s_framebuffer_size, s_framebuffer_size, GL_RED, GL_FLOAT, pixels.data());
   2644 		GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");
   2645 	}
   2646 
   2647 	/* Check results.
   2648 	 Note: assuming that s_buffer_size == 2 -> then all points shall be drawn. */
   2649 	for (std::vector<glw::GLfloat>::iterator i = pixels.begin(); i != pixels.end(); ++i)
   2650 	{
   2651 		if (fabs(*i - 0.5f) > 0.0625f /* precision */)
   2652 		{
   2653 			return false;
   2654 		}
   2655 	}
   2656 
   2657 	return true;
   2658 }
   2659 
   2660 bool gl3cts::TransformFeedback::CaptureVertexInterleaved::checkTransformFeedbackBuffer(BindBufferCase bind_case UNUSED,
   2661 																					   glw::GLenum primitive_type)
   2662 {
   2663 	/* Functions handler */
   2664 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2665 
   2666 	/* Check */
   2667 	glw::GLuint number_of_vertices = 0;
   2668 
   2669 	switch (primitive_type)
   2670 	{
   2671 	case GL_POINTS:
   2672 		number_of_vertices = 4;
   2673 		break;
   2674 	case GL_LINES:
   2675 		number_of_vertices = 4;
   2676 		break;
   2677 	case GL_LINE_LOOP:
   2678 		number_of_vertices = 8;
   2679 		break;
   2680 	case GL_LINE_STRIP:
   2681 		number_of_vertices = 6;
   2682 		break;
   2683 	case GL_TRIANGLES:
   2684 		number_of_vertices = 6;
   2685 		break;
   2686 	case GL_TRIANGLE_STRIP:
   2687 		number_of_vertices = 6;
   2688 		break;
   2689 	case GL_TRIANGLE_FAN:
   2690 		number_of_vertices = 6;
   2691 		break;
   2692 	default:
   2693 		throw 0;
   2694 	}
   2695 
   2696 	glw::GLfloat* results = (glw::GLfloat*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
   2697 	GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed.");
   2698 
   2699 	bool is_ok = true;
   2700 
   2701 	for (glw::GLuint j = 0; (j < number_of_vertices) && is_ok; ++j)
   2702 	{
   2703 		for (glw::GLint i = 0; i < m_max_transform_feedback_components - 4; ++i)
   2704 		{
   2705 			glw::GLfloat result	= results[i + j * m_max_transform_feedback_components];
   2706 			glw::GLfloat reference = (glw::GLfloat)(i);
   2707 
   2708 			if (fabs(result - reference) > 0.125 /* precision */)
   2709 			{
   2710 				is_ok = false;
   2711 
   2712 				break;
   2713 			}
   2714 		}
   2715 
   2716 		/* gl_Position */
   2717 		glw::GLfloat result[4] = { results[(j + 1) * m_max_transform_feedback_components - 4],
   2718 								   results[(j + 1) * m_max_transform_feedback_components - 3],
   2719 								   results[(j + 1) * m_max_transform_feedback_components - 2],
   2720 								   results[(j + 1) * m_max_transform_feedback_components - 1] };
   2721 
   2722 		if ((fabs(fabs(result[0]) - 1.0 + s_rasterization_epsilon) > 0.125 /* precision */) ||
   2723 			(fabs(fabs(result[1]) - 1.0 + s_rasterization_epsilon) > 0.125 /* precision */) ||
   2724 			(fabs(result[2]) > 0.125 /* precision */) || (fabs(result[3] - 1.0) > 0.125 /* precision */))
   2725 		{
   2726 			is_ok = false;
   2727 
   2728 			break;
   2729 		}
   2730 	}
   2731 
   2732 	gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   2733 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");
   2734 
   2735 	return is_ok;
   2736 }
   2737 
   2738 void gl3cts::TransformFeedback::CaptureVertexInterleaved::bindBuffer(BindBufferCase bind_case)
   2739 {
   2740 	/* Functions handler */
   2741 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2742 
   2743 	switch (bind_case)
   2744 	{
   2745 	case BIND_BUFFER_BASE_CASE:
   2746 		gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer);
   2747 		break;
   2748 	case BIND_BUFFER_RANGE_CASE:
   2749 		gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer, 0, m_buffer_size);
   2750 		break;
   2751 	case BIND_BUFFER_OFFSET_CASE:
   2752 		if (DE_NULL == m_glBindBufferOffsetEXT)
   2753 		{
   2754 			throw 0;
   2755 		}
   2756 		m_glBindBufferOffsetEXT(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer, 0);
   2757 		break;
   2758 	default:
   2759 		throw 0;
   2760 	}
   2761 }
   2762 
   2763 void gl3cts::TransformFeedback::CaptureVertexInterleaved::clean(void)
   2764 {
   2765 	/* Functions handler */
   2766 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2767 
   2768 	if (m_program)
   2769 	{
   2770 		gl.deleteProgram(m_program);
   2771 
   2772 		m_program = 0;
   2773 	}
   2774 
   2775 	if (m_framebuffer)
   2776 	{
   2777 		gl.deleteFramebuffers(1, &m_framebuffer);
   2778 
   2779 		m_framebuffer = 0;
   2780 	}
   2781 
   2782 	if (m_renderbuffer)
   2783 	{
   2784 		gl.deleteRenderbuffers(1, &m_renderbuffer);
   2785 
   2786 		m_renderbuffer = 0;
   2787 	}
   2788 
   2789 	cleanBuffer();
   2790 
   2791 	if (m_vertex_array_object)
   2792 	{
   2793 		gl.deleteVertexArrays(1, &m_vertex_array_object);
   2794 
   2795 		m_vertex_array_object = 0;
   2796 	}
   2797 }
   2798 
   2799 void gl3cts::TransformFeedback::CaptureVertexInterleaved::cleanBuffer(void)
   2800 {
   2801 	/* Functions handler */
   2802 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2803 
   2804 	if (m_buffer)
   2805 	{
   2806 		gl.deleteBuffers(1, &m_buffer);
   2807 
   2808 		m_buffer = 0;
   2809 	}
   2810 }
   2811 
   2812 const glw::GLchar* gl3cts::TransformFeedback::CaptureVertexInterleaved::s_vertex_shader_source_code_template =
   2813 	"#version 130\n"
   2814 	"\n"
   2815 	"TEMPLATE_INPUT_OUTPUT_DECLARATIONS"
   2816 	"\n"
   2817 	"void main()\n"
   2818 	"{\n"
   2819 	"TEMPLATE_OUTPUT_SETTERS"
   2820 	"\n"
   2821 	"    vec4 position = vec4(0.0);\n"
   2822 	"\n"
   2823 	"    /* Note: The points are moved 0.0625 from the borders to\n"
   2824 	"             reduce non-XFB related rasterization problems. */\n"
   2825 	"    switch(gl_VertexID)\n"
   2826 	"    {\n"
   2827 	"        case 0:\n"
   2828 	"            position = vec4(-1.0 + TEMPLATE_RASTERIZATION_EPSILON,  1.0 - TEMPLATE_RASTERIZATION_EPSILON,  0.0,  "
   2829 	"1.0);\n"
   2830 	"            break;\n"
   2831 	"        case 1:\n"
   2832 	"            position = vec4( 1.0 - TEMPLATE_RASTERIZATION_EPSILON,  1.0 - TEMPLATE_RASTERIZATION_EPSILON,  0.0,  "
   2833 	"1.0);\n"
   2834 	"            break;\n"
   2835 	"        case 2:\n"
   2836 	"            position = vec4(-1.0 + TEMPLATE_RASTERIZATION_EPSILON, -1.0 + TEMPLATE_RASTERIZATION_EPSILON,  0.0,  "
   2837 	"1.0);\n"
   2838 	"            break;\n"
   2839 	"        case 3:\n"
   2840 	"            position = vec4( 1.0 - TEMPLATE_RASTERIZATION_EPSILON, -1.0 + TEMPLATE_RASTERIZATION_EPSILON,  0.0,  "
   2841 	"1.0);\n"
   2842 	"            break;\n"
   2843 	"    }\n"
   2844 	"\n"
   2845 	"    gl_Position = position;\n"
   2846 	"}\n";
   2847 
   2848 const glw::GLchar* gl3cts::TransformFeedback::CaptureVertexInterleaved::s_fragment_shader_source_code =
   2849 	"#version 130\n"
   2850 	"\n"
   2851 	"out vec4 color;\n"
   2852 	"\n"
   2853 	"void main()\n"
   2854 	"{\n"
   2855 	"    color = vec4(0.5);\n"
   2856 	"}\n";
   2857 
   2858 const glw::GLuint
   2859 	gl3cts::TransformFeedback::CaptureVertexInterleaved::s_element_indices[][s_max_element_indices_count] = {
   2860 		{ 0, 1, 2, 3 },		  { 0, 1, 2, 3 }, { 0, 1, 3, 2 }, { 0, 1, 3, 2 },
   2861 		{ 2, 0, 1, 2, 1, 3 }, { 0, 1, 2, 3 }, { 2, 0, 1, 3 }
   2862 	};
   2863 
   2864 const glw::GLuint gl3cts::TransformFeedback::CaptureVertexInterleaved::s_primitive_cases_count =
   2865 	sizeof(s_element_indices) / sizeof(s_element_indices[0]);
   2866 
   2867 const glw::GLenum gl3cts::TransformFeedback::CaptureVertexInterleaved::s_primitive_cases[] = {
   2868 	GL_POINTS, GL_LINES, GL_LINE_LOOP, GL_LINE_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN
   2869 };
   2870 
   2871 const glw::GLenum gl3cts::TransformFeedback::CaptureVertexInterleaved::s_primitive_cases_xfb[] = {
   2872 	GL_POINTS, GL_LINES, GL_LINES, GL_LINES, GL_TRIANGLES, GL_TRIANGLES, GL_TRIANGLES
   2873 };
   2874 
   2875 const glw::GLuint gl3cts::TransformFeedback::CaptureVertexInterleaved::s_element_indices_counts[] = { 4, 4, 4, 4,
   2876 																									  6, 4, 4 };
   2877 
   2878 const glw::GLuint gl3cts::TransformFeedback::CaptureVertexInterleaved::s_framebuffer_size =
   2879 	2; /* If you change this, update checkFramebuffer function according. */
   2880 
   2881 const glw::GLfloat gl3cts::TransformFeedback::CaptureVertexInterleaved::s_rasterization_epsilon = 0.0625;
   2882 
   2883 /*-----------------------------------------------------------------------------------------------*/
   2884 
   2885 gl3cts::TransformFeedback::CaptureGeometryInterleaved::CaptureGeometryInterleaved(deqp::Context& context,
   2886 																				  const char*	test_name,
   2887 																				  const char*	test_description)
   2888 	: CaptureVertexInterleaved(context, test_name, test_description)
   2889 {
   2890 }
   2891 
   2892 gl3cts::TransformFeedback::CaptureGeometryInterleaved::~CaptureGeometryInterleaved(void)
   2893 {
   2894 }
   2895 
   2896 tcu::TestNode::IterateResult gl3cts::TransformFeedback::CaptureGeometryInterleaved::iterate(void)
   2897 {
   2898 	/* Functions handler */
   2899 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2900 
   2901 	/* Initializations. */
   2902 	bool is_at_least_gl_30 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(3, 0)));
   2903 	bool is_at_least_gl_32 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(3, 2)));
   2904 	bool is_ext_tf_1	   = m_context.getContextInfo().isExtensionSupported("GL_EXT_transform_feedback");
   2905 	bool is_arb_gs_4	   = m_context.getContextInfo().isExtensionSupported("GL_ARB_geometry_shader4");
   2906 
   2907 	bool is_ok		= true;
   2908 	bool test_error = false;
   2909 
   2910 	/* Tests. */
   2911 	try
   2912 	{
   2913 		if ((is_at_least_gl_30 || is_ext_tf_1) && (is_at_least_gl_32 || is_arb_gs_4))
   2914 		{
   2915 			fetchLimits();
   2916 			createFramebuffer();
   2917 			createTransformFeedbackBuffer();
   2918 			createVertexArrayObject();
   2919 
   2920 			for (glw::GLuint i_primitive_case = 0;
   2921 				 (i_primitive_case < s_geometry_interleaved_primitive_cases_count) && is_ok; ++i_primitive_case)
   2922 			{
   2923 				buildProgram(i_primitive_case);
   2924 
   2925 				gl.useProgram(m_program);
   2926 
   2927 				GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
   2928 
   2929 				for (glw::GLint i_bind_case = 0; (i_bind_case < BIND_BUFFER_CASES_COUNT) && is_ok; ++i_bind_case)
   2930 				{
   2931 					if ((i_bind_case == BIND_BUFFER_OFFSET_CASE) && (DE_NULL == m_glBindBufferOffsetEXT))
   2932 					{
   2933 						continue;
   2934 					}
   2935 
   2936 					bindBuffer((BindBufferCase)i_bind_case);
   2937 
   2938 					draw(i_primitive_case);
   2939 
   2940 					is_ok = is_ok && checkFramebuffer(s_primitive_cases[i_primitive_case]);
   2941 					is_ok = is_ok &&
   2942 							checkTransformFeedbackBuffer((BindBufferCase)i_bind_case,
   2943 														 s_geometry_interleaved_primitive_cases_xfb[i_primitive_case]);
   2944 				}
   2945 
   2946 				gl.deleteProgram(m_program);
   2947 
   2948 				m_program = 0;
   2949 
   2950 				GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteProgram call failed.");
   2951 			}
   2952 		}
   2953 	}
   2954 	catch (...)
   2955 	{
   2956 		is_ok	  = false;
   2957 		test_error = true;
   2958 	}
   2959 
   2960 	/* Clean objects. */
   2961 	clean();
   2962 
   2963 	/* Result's setup. */
   2964 	if (is_ok)
   2965 	{
   2966 		/* Log success. */
   2967 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Capture Geometry have passed."
   2968 											<< tcu::TestLog::EndMessage;
   2969 
   2970 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   2971 	}
   2972 	else
   2973 	{
   2974 		if (test_error)
   2975 		{
   2976 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   2977 		}
   2978 		else
   2979 		{
   2980 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   2981 		}
   2982 	}
   2983 
   2984 	return STOP;
   2985 }
   2986 
   2987 void gl3cts::TransformFeedback::CaptureGeometryInterleaved::fetchLimits(void)
   2988 {
   2989 	/* Functions handler */
   2990 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2991 
   2992 	/* Fetching limits. */
   2993 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &m_max_transform_feedback_components);
   2994 
   2995 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   2996 
   2997 	if (m_max_transform_feedback_components == 0)
   2998 	{
   2999 		throw 0;
   3000 	}
   3001 
   3002 	glw::GLint max_geometry_total_components = 0;
   3003 
   3004 	gl.getIntegerv(GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS, &max_geometry_total_components);
   3005 
   3006 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   3007 
   3008 	if (max_geometry_total_components == 0)
   3009 	{
   3010 		throw 0;
   3011 	}
   3012 
   3013 	if (m_max_transform_feedback_components * 4 > max_geometry_total_components)
   3014 	{
   3015 		m_max_transform_feedback_components = max_geometry_total_components / 4;
   3016 	}
   3017 }
   3018 
   3019 void gl3cts::TransformFeedback::CaptureGeometryInterleaved::buildProgram(glw::GLuint primitive_case)
   3020 {
   3021 	/* Functions handler */
   3022 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3023 
   3024 	/* Preparing source code. */
   3025 	std::string geometry_shader(s_geometry_shader_source_code_template); /* Storage for vertex shader source code. */
   3026 	std::string transform_feedback_variable_declarations(
   3027 		""); /* String to contain all custom outputs from vertex shader. */
   3028 	std::string transform_feedback_variable_setters(
   3029 		""); /* String containing all initializations of custom outputs from vertex shader. */
   3030 	std::vector<std::string> transform_feedback_varyings(m_max_transform_feedback_components); /* Varyings array. */
   3031 	std::vector<const glw::GLchar*> transform_feedback_varyings_c(
   3032 		m_max_transform_feedback_components); /* Varyings array in C form to pass to the GL. */
   3033 
   3034 	glw::GLint user_defined_transform_feedback_interleaved_varyings_count =
   3035 		m_max_transform_feedback_components /* total max to be written by the shader */
   3036 			/ 4								/* components per vec4 */
   3037 		//                                                                          / 4 /* number of vertices */
   3038 		- 1 /* gl_Position */;
   3039 
   3040 	glw::GLint all_transform_feedback_interleaved_varyings_count =
   3041 		user_defined_transform_feedback_interleaved_varyings_count + 1 /* gl_Position */;
   3042 
   3043 	/* Most of varyings is declarated output variables. */
   3044 	for (glw::GLint i = 0; i < user_defined_transform_feedback_interleaved_varyings_count; ++i)
   3045 	{
   3046 		/* Preparing variable name. */
   3047 		std::string varying = "result_";
   3048 		varying.append(gl3cts::TransformFeedback::Utilities::itoa(i));
   3049 
   3050 		transform_feedback_varyings[i] = varying;
   3051 
   3052 		transform_feedback_varyings_c[i] = transform_feedback_varyings[i].c_str();
   3053 
   3054 		/* Preparing variable declaration. */
   3055 		transform_feedback_variable_declarations.append("out vec4 ");
   3056 		transform_feedback_variable_declarations.append(varying);
   3057 		transform_feedback_variable_declarations.append(";\n");
   3058 
   3059 		/* Preparing variable setters. */
   3060 		transform_feedback_variable_setters.append("    ");
   3061 		transform_feedback_variable_setters.append(varying);
   3062 		transform_feedback_variable_setters.append(" = vec4(");
   3063 		transform_feedback_variable_setters.append(gl3cts::TransformFeedback::Utilities::itoa(i * 4));
   3064 		transform_feedback_variable_setters.append(".0, ");
   3065 		transform_feedback_variable_setters.append(gl3cts::TransformFeedback::Utilities::itoa(i * 4 + 1));
   3066 		transform_feedback_variable_setters.append(".0, ");
   3067 		transform_feedback_variable_setters.append(gl3cts::TransformFeedback::Utilities::itoa(i * 4 + 2));
   3068 		transform_feedback_variable_setters.append(".0, ");
   3069 		transform_feedback_variable_setters.append(gl3cts::TransformFeedback::Utilities::itoa(i * 4 + 3));
   3070 		transform_feedback_variable_setters.append(".0);\n");
   3071 	}
   3072 
   3073 	/* Last four varying components are gl_Position components. */
   3074 	transform_feedback_varyings[user_defined_transform_feedback_interleaved_varyings_count /* gl_Position */] =
   3075 		"gl_Position";
   3076 
   3077 	transform_feedback_varyings_c[user_defined_transform_feedback_interleaved_varyings_count /* gl_Position */] =
   3078 		transform_feedback_varyings[user_defined_transform_feedback_interleaved_varyings_count /* gl_Position */]
   3079 			.c_str();
   3080 
   3081 	/* Preprocess vertex shader source code template. */
   3082 	geometry_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(
   3083 		geometry_shader, "TEMPLATE_PRIMITIVE_TYPE", s_geometry_interleaved_primitive_cases[primitive_case]);
   3084 	geometry_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(
   3085 		geometry_shader, "TEMPLATE_INPUT_OUTPUT_DECLARATIONS", transform_feedback_variable_declarations);
   3086 	geometry_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(geometry_shader, "TEMPLATE_OUTPUT_SETTERS",
   3087 																		   transform_feedback_variable_setters);
   3088 	geometry_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(
   3089 		geometry_shader, "TEMPLATE_RASTERIZATION_EPSILON",
   3090 		gl3cts::TransformFeedback::Utilities::ftoa(s_rasterization_epsilon));
   3091 
   3092 	/* Compile, link and check. */
   3093 	m_program = gl3cts::TransformFeedback::Utilities::buildProgram(
   3094 		gl, m_context.getTestContext().getLog(), geometry_shader.c_str(), NULL, NULL, s_blank_vertex_shader_source_code,
   3095 		s_fragment_shader_source_code, &transform_feedback_varyings_c[0],
   3096 		all_transform_feedback_interleaved_varyings_count, m_attrib_type);
   3097 
   3098 	if (0 == m_program)
   3099 	{
   3100 		throw 0;
   3101 	}
   3102 }
   3103 
   3104 void gl3cts::TransformFeedback::CaptureGeometryInterleaved::draw(glw::GLuint primitive_case)
   3105 {
   3106 	/* Functions handler */
   3107 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3108 
   3109 	gl.clear(GL_COLOR_BUFFER_BIT);
   3110 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed.");
   3111 
   3112 	gl.beginTransformFeedback(s_geometry_interleaved_primitive_cases_xfb[primitive_case]);
   3113 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
   3114 
   3115 	gl.drawArrays(GL_POINTS, 0, 1);
   3116 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
   3117 
   3118 	gl.endTransformFeedback();
   3119 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedbac call failed.");
   3120 }
   3121 
   3122 const glw::GLchar* gl3cts::TransformFeedback::CaptureGeometryInterleaved::s_geometry_shader_source_code_template =
   3123 	"#version 150\n"
   3124 	"\n"
   3125 	"layout(points) in;\n"
   3126 	"layout(TEMPLATE_PRIMITIVE_TYPE, max_vertices = 4) out;\n"
   3127 	"\n"
   3128 	"TEMPLATE_INPUT_OUTPUT_DECLARATIONS"
   3129 	"\n"
   3130 	"void main()\n"
   3131 	"{\n"
   3132 	"    /* Note: The points are moved 0.0625 from the borders to\n"
   3133 	"             reduce non-XFB related rasterization problems. */\n"
   3134 	"\n"
   3135 	"    gl_Position = vec4(-1.0 + TEMPLATE_RASTERIZATION_EPSILON,  1.0 - TEMPLATE_RASTERIZATION_EPSILON,  0.0,  "
   3136 	"1.0);\n"
   3137 	"TEMPLATE_OUTPUT_SETTERS"
   3138 	"    EmitVertex();\n"
   3139 	"\n"
   3140 	"    gl_Position = vec4( 1.0 - TEMPLATE_RASTERIZATION_EPSILON,  1.0 - TEMPLATE_RASTERIZATION_EPSILON,  0.0,  "
   3141 	"1.0);\n"
   3142 	"TEMPLATE_OUTPUT_SETTERS"
   3143 	"    EmitVertex();\n"
   3144 	"\n"
   3145 	"    gl_Position = vec4(-1.0 + TEMPLATE_RASTERIZATION_EPSILON, -1.0 + TEMPLATE_RASTERIZATION_EPSILON,  0.0,  "
   3146 	"1.0);\n"
   3147 	"TEMPLATE_OUTPUT_SETTERS"
   3148 	"    EmitVertex();\n"
   3149 	"\n"
   3150 	"    gl_Position = vec4( 1.0 - TEMPLATE_RASTERIZATION_EPSILON, -1.0 + TEMPLATE_RASTERIZATION_EPSILON,  0.0,  "
   3151 	"1.0);\n"
   3152 	"TEMPLATE_OUTPUT_SETTERS"
   3153 	"    EmitVertex();\n"
   3154 	"}\n";
   3155 
   3156 const glw::GLchar* gl3cts::TransformFeedback::CaptureGeometryInterleaved::s_blank_vertex_shader_source_code =
   3157 	"#version 130\n"
   3158 	"\n"
   3159 	"void main()\n"
   3160 	"{\n"
   3161 	"}\n";
   3162 
   3163 const glw::GLchar* gl3cts::TransformFeedback::CaptureGeometryInterleaved::s_geometry_interleaved_primitive_cases[] = {
   3164 	"points", "line_strip", "triangle_strip"
   3165 };
   3166 
   3167 const glw::GLenum gl3cts::TransformFeedback::CaptureGeometryInterleaved::s_geometry_interleaved_primitive_cases_xfb[] =
   3168 	{ GL_POINTS, GL_LINES, GL_TRIANGLES };
   3169 
   3170 const glw::GLuint gl3cts::TransformFeedback::CaptureGeometryInterleaved::s_geometry_interleaved_primitive_cases_count =
   3171 	sizeof(s_geometry_interleaved_primitive_cases) / sizeof(s_geometry_interleaved_primitive_cases[0]);
   3172 
   3173 /*-----------------------------------------------------------------------------------------------*/
   3174 
   3175 gl3cts::TransformFeedback::CaptureVertexSeparate::CaptureVertexSeparate(deqp::Context& context, const char* test_name,
   3176 																		const char* test_description)
   3177 	: CaptureVertexInterleaved(context, test_name, test_description)
   3178 	, m_buffers(DE_NULL)
   3179 	, m_max_transform_feedback_separate_attribs(0)
   3180 {
   3181 	m_attrib_type = GL_SEPARATE_ATTRIBS;
   3182 }
   3183 
   3184 void gl3cts::TransformFeedback::CaptureVertexSeparate::fetchLimits(void)
   3185 {
   3186 	/* Functions handler */
   3187 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3188 
   3189 	/* Fetching limits. */
   3190 	glw::GLint max_transform_feedback_separate_components;
   3191 
   3192 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &max_transform_feedback_separate_components);
   3193 
   3194 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   3195 
   3196 	if (max_transform_feedback_separate_components < 4)
   3197 	{
   3198 		throw 0;
   3199 	}
   3200 
   3201 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &m_max_transform_feedback_separate_attribs);
   3202 
   3203 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   3204 
   3205 	if (m_max_transform_feedback_separate_attribs == 0)
   3206 	{
   3207 		throw 0;
   3208 	}
   3209 
   3210 	m_max_transform_feedback_components = m_max_transform_feedback_separate_attribs * 4 /* vec4 is used */;
   3211 
   3212 	glw::GLint max_varyings_components = 0;
   3213 
   3214 	gl.getIntegerv(GL_MAX_VARYING_COMPONENTS, &max_varyings_components);
   3215 
   3216 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   3217 
   3218 	if (max_varyings_components == 0)
   3219 	{
   3220 		throw 0;
   3221 	}
   3222 
   3223 	if (m_max_transform_feedback_components > max_varyings_components)
   3224 	{
   3225 		m_max_transform_feedback_components = max_varyings_components;
   3226 	}
   3227 }
   3228 
   3229 void gl3cts::TransformFeedback::CaptureVertexSeparate::createTransformFeedbackBuffer(void)
   3230 {
   3231 	/* Functions handler */
   3232 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3233 
   3234 	m_buffers = new glw::GLuint[m_max_transform_feedback_components];
   3235 
   3236 	if (DE_NULL == m_buffers)
   3237 	{
   3238 		throw 0;
   3239 	}
   3240 
   3241 	gl.genBuffers(m_max_transform_feedback_separate_attribs, m_buffers);
   3242 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   3243 
   3244 	m_buffer_size = static_cast<glw::GLuint>(m_max_vertices_drawn * 4 /* vec4 */ * sizeof(glw::GLfloat));
   3245 
   3246 	for (glw::GLint i = 0; i < m_max_transform_feedback_separate_attribs; ++i)
   3247 	{
   3248 		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_buffers[i]);
   3249 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   3250 
   3251 		gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, m_buffer_size, NULL, GL_DYNAMIC_READ);
   3252 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
   3253 	}
   3254 }
   3255 
   3256 void gl3cts::TransformFeedback::CaptureVertexSeparate::bindBuffer(BindBufferCase bind_case)
   3257 {
   3258 	/* Functions handler */
   3259 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3260 
   3261 	switch (bind_case)
   3262 	{
   3263 	case BIND_BUFFER_BASE_CASE:
   3264 		for (glw::GLint i = 0; i < m_max_transform_feedback_separate_attribs; ++i)
   3265 		{
   3266 			gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, i, m_buffers[i]);
   3267 		}
   3268 		break;
   3269 	case BIND_BUFFER_RANGE_CASE:
   3270 		for (glw::GLint i = 0; i < m_max_transform_feedback_separate_attribs; ++i)
   3271 		{
   3272 			gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, i, m_buffers[i], 0, m_buffer_size);
   3273 		}
   3274 		break;
   3275 	case BIND_BUFFER_OFFSET_CASE:
   3276 		for (glw::GLint i = 0; i < m_max_transform_feedback_separate_attribs; ++i)
   3277 		{
   3278 			m_glBindBufferOffsetEXT(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffers[i], 0);
   3279 		}
   3280 		break;
   3281 	default:
   3282 		throw 0;
   3283 	}
   3284 }
   3285 
   3286 void gl3cts::TransformFeedback::CaptureVertexSeparate::cleanBuffer(void)
   3287 {
   3288 	/* Functions handler */
   3289 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3290 
   3291 	if (DE_NULL != m_buffers)
   3292 	{
   3293 		gl.deleteBuffers(m_max_transform_feedback_separate_attribs, m_buffers);
   3294 
   3295 		delete[] m_buffers;
   3296 
   3297 		m_buffers = DE_NULL;
   3298 	}
   3299 }
   3300 
   3301 bool gl3cts::TransformFeedback::CaptureVertexSeparate::checkTransformFeedbackBuffer(BindBufferCase bind_case UNUSED,
   3302 																					glw::GLenum primitive_type)
   3303 {
   3304 	/* Functions handler */
   3305 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3306 
   3307 	glw::GLuint number_of_vertices = 0;
   3308 
   3309 	switch (primitive_type)
   3310 	{
   3311 	case GL_POINTS:
   3312 		number_of_vertices = 4;
   3313 		break;
   3314 	case GL_LINES:
   3315 		number_of_vertices = 4;
   3316 		break;
   3317 	case GL_LINE_LOOP:
   3318 		number_of_vertices = 8;
   3319 		break;
   3320 	case GL_LINE_STRIP:
   3321 		number_of_vertices = 6;
   3322 		break;
   3323 	case GL_TRIANGLES:
   3324 		number_of_vertices = 6;
   3325 		break;
   3326 	case GL_TRIANGLE_STRIP:
   3327 		number_of_vertices = 6;
   3328 		break;
   3329 	case GL_TRIANGLE_FAN:
   3330 		number_of_vertices = 6;
   3331 		break;
   3332 	default:
   3333 		throw 0;
   3334 	}
   3335 
   3336 	bool is_ok = true;
   3337 
   3338 	for (glw::GLint i = 0; i < m_max_transform_feedback_separate_attribs - 1; ++i)
   3339 	{
   3340 		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_buffers[i]);
   3341 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   3342 
   3343 		glw::GLfloat* results = (glw::GLfloat*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
   3344 		GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed.");
   3345 
   3346 		for (glw::GLuint j = 0; (j < number_of_vertices) && is_ok; ++j)
   3347 		{
   3348 			for (glw::GLuint k = 0; k < 4 /* vec4 */; ++k)
   3349 			{
   3350 				glw::GLfloat result	= results[j * 4 + k];
   3351 				glw::GLfloat reference = (glw::GLfloat)(i * 4 + k);
   3352 
   3353 				if (fabs(result - reference) > 0.125 /* precision */)
   3354 				{
   3355 					is_ok = false;
   3356 
   3357 					break;
   3358 				}
   3359 			}
   3360 		}
   3361 
   3362 		gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   3363 		GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");
   3364 	}
   3365 
   3366 	/* gl_Position */
   3367 	if (is_ok)
   3368 	{
   3369 		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_buffers[m_max_transform_feedback_separate_attribs - 1]);
   3370 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   3371 
   3372 		glw::GLfloat* results = (glw::GLfloat*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
   3373 		GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed.");
   3374 
   3375 		for (glw::GLuint j = 0; (j < number_of_vertices) && is_ok; ++j)
   3376 		{
   3377 			glw::GLfloat result[4] = { results[j * 4], results[j * 4 + 1], results[j * 4 + 2], results[j * 4 + 3] };
   3378 
   3379 			if ((fabs(fabs(result[0]) - 1.0 + s_rasterization_epsilon) > 0.125 /* precision */) ||
   3380 				(fabs(fabs(result[1]) - 1.0 + s_rasterization_epsilon) > 0.125 /* precision */) ||
   3381 				(fabs(result[2]) > 0.125 /* precision */) || (fabs(result[3] - 1.0) > 0.125 /* precision */))
   3382 			{
   3383 				is_ok = false;
   3384 
   3385 				break;
   3386 			}
   3387 		}
   3388 
   3389 		gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   3390 		GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");
   3391 	}
   3392 
   3393 	return is_ok;
   3394 }
   3395 
   3396 /*-----------------------------------------------------------------------------------------------*/
   3397 
   3398 gl3cts::TransformFeedback::CaptureGeometrySeparate::CaptureGeometrySeparate(deqp::Context& context,
   3399 																			const char*	test_name,
   3400 																			const char*	test_description)
   3401 	: CaptureVertexInterleaved(context, test_name, test_description)
   3402 	, CaptureVertexSeparate(context, test_name, test_description)
   3403 	, CaptureGeometryInterleaved(context, test_name, test_description)
   3404 	, m_buffers(DE_NULL)
   3405 	, m_max_transform_feedback_separate_attribs(0)
   3406 {
   3407 }
   3408 
   3409 /*-----------------------------------------------------------------------------------------------*/
   3410 
   3411 gl3cts::TransformFeedback::CheckGetXFBVarying::CheckGetXFBVarying(deqp::Context& context, const char* test_name,
   3412 																  const char* test_description)
   3413 	: deqp::TestCase(context, test_name, test_description)
   3414 	, m_context(context)
   3415 	, m_max_xfb_interleaved_components(0)
   3416 	, m_max_xfb_separate_attributes(0)
   3417 	, m_max_xfb_separate_components(0)
   3418 	, m_max_varying_components(0)
   3419 	, m_max_varying_vectors(0)
   3420 	, m_max_geometry_total_output_components(0)
   3421 {
   3422 }
   3423 
   3424 gl3cts::TransformFeedback::CheckGetXFBVarying::~CheckGetXFBVarying(void)
   3425 {
   3426 }
   3427 
   3428 void gl3cts::TransformFeedback::CheckGetXFBVarying::fetchLimits(void)
   3429 {
   3430 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3431 
   3432 	/* Fetching limits. */
   3433 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &m_max_xfb_interleaved_components);
   3434 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &m_max_xfb_separate_attributes);
   3435 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &m_max_xfb_separate_components);
   3436 	gl.getIntegerv(GL_MAX_VARYING_COMPONENTS, &m_max_varying_components);
   3437 	gl.getIntegerv(GL_MAX_VARYING_VECTORS, &m_max_varying_vectors);
   3438 	gl.getIntegerv(GL_MAX_GEOMETRY_OUTPUT_COMPONENTS, &m_max_geometry_total_output_components);
   3439 
   3440 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   3441 }
   3442 
   3443 glw::GLuint gl3cts::TransformFeedback::CheckGetXFBVarying::numberOfAttributes(glw::GLuint capture_way,
   3444 																			  glw::GLuint shader_case,
   3445 																			  glw::GLuint varying_type)
   3446 {
   3447 	/* Setup limits of the case. */
   3448 	const glw::GLuint max_total_components =
   3449 		((s_shader_cases[shader_case].geometry_shader == DE_NULL) ? m_max_varying_components :
   3450 																	m_max_geometry_total_output_components) -
   3451 		4 /* gl_Position is not captured */;
   3452 
   3453 	const glw::GLuint attribute_components = s_varying_types[varying_type].components_count;
   3454 	const glw::GLuint max_xfb_components   = (s_capture_ways[capture_way] == GL_INTERLEAVED_ATTRIBS) ?
   3455 											   m_max_xfb_interleaved_components :
   3456 											   (attribute_components * m_max_xfb_separate_components);
   3457 
   3458 	if (s_capture_ways[capture_way] == GL_SEPARATE_ATTRIBS)
   3459 	{
   3460 		if (attribute_components > glw::GLuint(m_max_xfb_separate_components))
   3461 		{
   3462 			return 0;
   3463 		}
   3464 	}
   3465 
   3466 	/* Setup number of attributes. */
   3467 	glw::GLuint number_of_attributes = max_xfb_components / attribute_components;
   3468 
   3469 	if (s_capture_ways[capture_way] == GL_SEPARATE_ATTRIBS &&
   3470 		number_of_attributes > glw::GLuint(m_max_xfb_separate_attributes))
   3471 	{
   3472 		number_of_attributes = m_max_xfb_separate_attributes;
   3473 	}
   3474 
   3475 	/* Clamp to limits. */
   3476 	if (number_of_attributes * attribute_components > max_total_components)
   3477 	{
   3478 		number_of_attributes = max_total_components / attribute_components;
   3479 	}
   3480 
   3481 	/* Vectors limit. */
   3482 	if (attribute_components <= 4)
   3483 	{
   3484 		if (number_of_attributes > glw::GLuint(m_max_varying_vectors))
   3485 		{
   3486 			number_of_attributes = m_max_varying_vectors;
   3487 		}
   3488 	}
   3489 	else
   3490 	{
   3491 		if (number_of_attributes > glw::GLuint(m_max_varying_vectors) / 4)
   3492 		{
   3493 			number_of_attributes = glw::GLuint(m_max_varying_vectors) / 4;
   3494 		}
   3495 	}
   3496 
   3497 	/* Return. */
   3498 	return number_of_attributes;
   3499 }
   3500 
   3501 tcu::TestNode::IterateResult gl3cts::TransformFeedback::CheckGetXFBVarying::iterate(void)
   3502 {
   3503 	/* Functions handler */
   3504 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3505 
   3506 	/* Initializations. */
   3507 	bool is_at_least_gl_30 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(3, 0)));
   3508 	bool is_ext_tf_1	   = m_context.getContextInfo().isExtensionSupported("GL_EXT_transform_feedback");
   3509 
   3510 	bool is_ok		= true;
   3511 	bool test_error = false;
   3512 
   3513 	glw::GLuint program = 0;
   3514 
   3515 	/* Tests. */
   3516 	try
   3517 	{
   3518 		if (is_at_least_gl_30 || is_ext_tf_1)
   3519 		{
   3520 			fetchLimits();
   3521 
   3522 			for (glw::GLuint i = 0; (i < s_capture_ways_count) && is_ok; ++i)
   3523 			{
   3524 				for (glw::GLuint j = 0; (j < s_shader_cases_count) && is_ok; ++j)
   3525 				{
   3526 					for (glw::GLuint k = 0; (k < s_varying_types_count) && is_ok; ++k)
   3527 					{
   3528 						glw::GLuint n = numberOfAttributes(i, j, k);
   3529 
   3530 						if (n)
   3531 						{
   3532 							program = buildProgram(i, j, k, n);
   3533 
   3534 							is_ok = is_ok && (program != 0);
   3535 
   3536 							is_ok = is_ok && check(program, i, j, k, n);
   3537 
   3538 							gl.deleteProgram(program);
   3539 
   3540 							GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteProgram call failed.");
   3541 
   3542 							program = 0;
   3543 						}
   3544 					}
   3545 				}
   3546 			}
   3547 		}
   3548 	}
   3549 	catch (...)
   3550 	{
   3551 		is_ok	  = false;
   3552 		test_error = true;
   3553 
   3554 		if (program)
   3555 		{
   3556 			gl.deleteProgram(program);
   3557 
   3558 			program = 0;
   3559 		}
   3560 	}
   3561 
   3562 	/* Result's setup. */
   3563 	if (is_ok)
   3564 	{
   3565 		/* Log success. */
   3566 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   3567 											<< "Test checking Get Transform Feedback Varying have passed."
   3568 											<< tcu::TestLog::EndMessage;
   3569 
   3570 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   3571 	}
   3572 	else
   3573 	{
   3574 		if (test_error)
   3575 		{
   3576 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   3577 		}
   3578 		else
   3579 		{
   3580 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   3581 		}
   3582 	}
   3583 
   3584 	return STOP;
   3585 }
   3586 
   3587 glw::GLuint gl3cts::TransformFeedback::CheckGetXFBVarying::buildProgram(glw::GLuint capture_way,
   3588 																		glw::GLuint shader_case,
   3589 																		glw::GLuint varying_type,
   3590 																		glw::GLuint number_of_attributes)
   3591 {
   3592 	/* Functions handler */
   3593 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3594 
   3595 	/* Preparing source code. */
   3596 	std::string						xfb_variable_declarations("");
   3597 	std::string						xfb_variable_setters("");
   3598 	std::vector<std::string>		xfb_varyings(number_of_attributes);
   3599 	std::vector<const glw::GLchar*> xfb_varyings_c(number_of_attributes);
   3600 
   3601 	/* Most of varyings is declarated output variables. */
   3602 	for (glw::GLuint i = 0; i < number_of_attributes; ++i)
   3603 	{
   3604 		/* Varying name: result_# */
   3605 		std::string varying = "result_";
   3606 		varying.append(gl3cts::TransformFeedback::Utilities::itoa(i));
   3607 
   3608 		xfb_varyings[i]   = varying;
   3609 		xfb_varyings_c[i] = xfb_varyings[i].c_str();
   3610 
   3611 		/* Varying declaration: out TYPE result_#;*/
   3612 		xfb_variable_declarations.append("out ");
   3613 		xfb_variable_declarations.append(s_varying_types[varying_type].name);
   3614 		xfb_variable_declarations.append(" ");
   3615 		xfb_variable_declarations.append(varying);
   3616 		xfb_variable_declarations.append(";\n");
   3617 
   3618 		/* Varying setter: result_# = TYPE(#); */
   3619 		xfb_variable_setters.append("    ");
   3620 		xfb_variable_setters.append(varying);
   3621 		xfb_variable_setters.append(" = ");
   3622 		xfb_variable_setters.append(s_varying_types[varying_type].name);
   3623 		xfb_variable_setters.append("(");
   3624 		xfb_variable_setters.append("2"); //gl3cts::TransformFeedback::Utilities::itoa(i));
   3625 		if (s_varying_types[varying_type].float_component)
   3626 		{
   3627 			/* if varying is float varying setter is: result_# = TYPE(#.0); */
   3628 			xfb_variable_setters.append(".0");
   3629 		}
   3630 		xfb_variable_setters.append(");\n");
   3631 	}
   3632 
   3633 	/* Preprocess vertex shader source code template. */
   3634 	const glw::GLchar* vertex_shader   = s_shader_cases[shader_case].vertex_shader;
   3635 	const glw::GLchar* geometry_shader = s_shader_cases[shader_case].geometry_shader;
   3636 
   3637 	std::string xfb_shader;
   3638 
   3639 	if (DE_NULL == s_shader_cases[shader_case].geometry_shader)
   3640 	{
   3641 		/* XFB tested in vertex shader. */
   3642 		xfb_shader = vertex_shader;
   3643 	}
   3644 	else
   3645 	{
   3646 		/* XFB tested in geometry shader. */
   3647 		xfb_shader = geometry_shader;
   3648 	}
   3649 
   3650 	/* Preprocess shader. */
   3651 	xfb_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(xfb_shader, "TEMPLATE_OUTPUT_DECLARATIONS",
   3652 																	  xfb_variable_declarations);
   3653 	xfb_shader = gl3cts::TransformFeedback::Utilities::preprocessCode(xfb_shader, "TEMPLATE_OUTPUT_SETTERS",
   3654 																	  xfb_variable_setters);
   3655 
   3656 	if (DE_NULL == s_shader_cases[shader_case].geometry_shader)
   3657 	{
   3658 		/* XFB tested in vertex shader. */
   3659 		vertex_shader = xfb_shader.c_str();
   3660 	}
   3661 	else
   3662 	{
   3663 		/* XFB tested in geometry shader. */
   3664 		geometry_shader = xfb_shader.c_str();
   3665 	}
   3666 
   3667 	/* Compile, link and check. */
   3668 	glw::GLuint program = gl3cts::TransformFeedback::Utilities::buildProgram(
   3669 		gl, m_context.getTestContext().getLog(), geometry_shader, NULL, NULL, vertex_shader, s_generic_fragment_shader,
   3670 		&xfb_varyings_c[0], number_of_attributes, s_capture_ways[capture_way]);
   3671 
   3672 	/* Check compilation status. */
   3673 	if (0 == program)
   3674 	{
   3675 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Building program has failed.\nVertex shader:\n"
   3676 											<< vertex_shader << "Geometry shader:\n"
   3677 											<< ((DE_NULL == geometry_shader) ? "" : geometry_shader)
   3678 											<< "Fragment shader:\n"
   3679 											<< s_generic_fragment_shader << tcu::TestLog::EndMessage;
   3680 
   3681 		throw 0;
   3682 	}
   3683 
   3684 	return program;
   3685 }
   3686 
   3687 bool gl3cts::TransformFeedback::CheckGetXFBVarying::check(glw::GLuint program, glw::GLuint capture_way,
   3688 														  glw::GLuint shader_case UNUSED, glw::GLuint varying_type,
   3689 														  glw::GLuint number_of_attributes)
   3690 {
   3691 	/* Functions handler */
   3692 	const glw::Functions& gl		 = m_context.getRenderContext().getFunctions();
   3693 	glw::GLuint			  max_length = 0;
   3694 
   3695 	/* Inspect glGetTransformFeedbackVarying. */
   3696 	for (glw::GLuint i = 0; i < number_of_attributes; ++i)
   3697 	{
   3698 		const glw::GLsizei bufSize  = 18;
   3699 		glw::GLsizei	   length   = 0;
   3700 		glw::GLsizei	   size		= 0;
   3701 		glw::GLenum		   type		= GL_NONE;
   3702 		glw::GLchar		   name[18] = { 0 }; /* Size of bufSize. */
   3703 
   3704 		gl.getTransformFeedbackVarying(program, i, bufSize, &length, &size, &type, name);
   3705 
   3706 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbackVarying call failed.");
   3707 
   3708 		max_length = deMaxu32(max_length, glw::GLuint(length));
   3709 
   3710 		/* Check name. */
   3711 		if (length)
   3712 		{
   3713 			std::string varying		= name;
   3714 			std::string varying_ref = "result_";
   3715 			varying_ref.append(gl3cts::TransformFeedback::Utilities::itoa(i));
   3716 
   3717 			if (0 != varying.compare(varying_ref))
   3718 			{
   3719 				return false;
   3720 			}
   3721 		}
   3722 		else
   3723 		{
   3724 			return false;
   3725 		}
   3726 
   3727 		/* Check size. */
   3728 		const glw::GLuint size_ref = 1;
   3729 
   3730 		if (size != size_ref)
   3731 		{
   3732 			return false;
   3733 		}
   3734 
   3735 		/* Check type. */
   3736 		if (type != s_varying_types[varying_type].type)
   3737 		{
   3738 			return false;
   3739 		}
   3740 	}
   3741 
   3742 	/* Inspect glGetProgramiv. */
   3743 	glw::GLint xfb_varyings			  = 0;
   3744 	glw::GLint xfb_mode				  = 0;
   3745 	glw::GLint xfb_varying_max_length = 0;
   3746 
   3747 	gl.getProgramiv(program, GL_TRANSFORM_FEEDBACK_VARYINGS, &xfb_varyings);
   3748 	gl.getProgramiv(program, GL_TRANSFORM_FEEDBACK_BUFFER_MODE, &xfb_mode);
   3749 	gl.getProgramiv(program, GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, &xfb_varying_max_length);
   3750 
   3751 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");
   3752 
   3753 	if (glw::GLuint(xfb_varyings) != number_of_attributes)
   3754 	{
   3755 		return false;
   3756 	}
   3757 
   3758 	if (glw::GLenum(xfb_mode) != s_capture_ways[capture_way])
   3759 	{
   3760 		return false;
   3761 	}
   3762 
   3763 	if (glw::GLuint(xfb_varying_max_length) < max_length)
   3764 	{
   3765 		return false;
   3766 	}
   3767 
   3768 	return true;
   3769 }
   3770 
   3771 const glw::GLchar* gl3cts::TransformFeedback::CheckGetXFBVarying::s_generic_fragment_shader = "#version 130\n"
   3772 																							  "\n"
   3773 																							  "out vec4 color;\n"
   3774 																							  "\n"
   3775 																							  "void main()\n"
   3776 																							  "{\n"
   3777 																							  "    color = vec4(1.0);\n"
   3778 																							  "}\n";
   3779 
   3780 const struct gl3cts::TransformFeedback::CheckGetXFBVarying::ShaderCase
   3781 	gl3cts::TransformFeedback::CheckGetXFBVarying::s_shader_cases[] = { { /* Vertex Shader. */
   3782 																		  "#version 130\n"
   3783 																		  "\n"
   3784 																		  "TEMPLATE_OUTPUT_DECLARATIONS"
   3785 																		  "\n"
   3786 																		  "void main()\n"
   3787 																		  "{\n"
   3788 																		  "    gl_Position = vec4(1.0);\n"
   3789 																		  "TEMPLATE_OUTPUT_SETTERS"
   3790 																		  "}\n",
   3791 
   3792 																		  /* Geometry Shader. */
   3793 																		  NULL },
   3794 																		{ /* Vertex Shader. */
   3795 																		  "#version 130\n"
   3796 																		  "\n"
   3797 																		  "void main()\n"
   3798 																		  "{\n"
   3799 																		  "}\n",
   3800 
   3801 																		  /* Geometry Shader. */
   3802 																		  "#version 150\n"
   3803 																		  "\n"
   3804 																		  "layout(points) in;\n"
   3805 																		  "layout(points, max_vertices = 1) out;\n"
   3806 																		  "\n"
   3807 																		  "TEMPLATE_OUTPUT_DECLARATIONS"
   3808 																		  "\n"
   3809 																		  "void main()\n"
   3810 																		  "{\n"
   3811 																		  "    gl_Position = vec4(1.0);\n"
   3812 																		  "TEMPLATE_OUTPUT_SETTERS"
   3813 																		  "    EmitVertex();\n"
   3814 																		  "}\n" } };
   3815 
   3816 const glw::GLuint gl3cts::TransformFeedback::CheckGetXFBVarying::s_shader_cases_count =
   3817 	sizeof(s_shader_cases) / sizeof(s_shader_cases[0]);
   3818 
   3819 const struct gl3cts::TransformFeedback::CheckGetXFBVarying::VaryingType
   3820 	gl3cts::TransformFeedback::CheckGetXFBVarying::s_varying_types[] = {
   3821 		/* type,				name,		#components,	is component float */
   3822 		{ GL_FLOAT, "float", 1, true },
   3823 		{ GL_FLOAT_VEC2, "vec2", 2, true },
   3824 		{ GL_FLOAT_VEC3, "vec3", 3, true },
   3825 		{ GL_FLOAT_VEC4, "vec4", 4, true },
   3826 		{ GL_INT, "int", 1, false },
   3827 		{ GL_INT_VEC2, "ivec2", 2, false },
   3828 		{ GL_INT_VEC3, "ivec3", 3, false },
   3829 		{ GL_INT_VEC4, "ivec4", 4, false },
   3830 		{ GL_UNSIGNED_INT, "uint", 1, false },
   3831 		{ GL_UNSIGNED_INT_VEC2, "uvec2", 2, false },
   3832 		{ GL_UNSIGNED_INT_VEC3, "uvec3", 3, false },
   3833 		{ GL_UNSIGNED_INT_VEC4, "uvec4", 4, false },
   3834 		{ GL_FLOAT_MAT2, "mat2", 4, true },
   3835 		{ GL_FLOAT_MAT3, "mat3", 9, true },
   3836 		{ GL_FLOAT_MAT4, "mat4", 16, true }
   3837 	};
   3838 
   3839 const glw::GLuint gl3cts::TransformFeedback::CheckGetXFBVarying::s_varying_types_count =
   3840 	sizeof(s_varying_types) / sizeof(s_varying_types[0]);
   3841 
   3842 const glw::GLenum gl3cts::TransformFeedback::CheckGetXFBVarying::s_capture_ways[] = { GL_INTERLEAVED_ATTRIBS,
   3843 																					  GL_SEPARATE_ATTRIBS };
   3844 
   3845 const glw::GLuint gl3cts::TransformFeedback::CheckGetXFBVarying::s_capture_ways_count =
   3846 	sizeof(s_capture_ways) / sizeof(s_capture_ways[0]);
   3847 
   3848 /*-----------------------------------------------------------------------------------------------*/
   3849 
   3850 gl3cts::TransformFeedback::QueryVertexInterleaved::QueryVertexInterleaved(deqp::Context& context, const char* test_name,
   3851 																		  const char* test_description)
   3852 	: CaptureVertexInterleaved(context, test_name, test_description), m_query_object(0)
   3853 {
   3854 	m_max_vertices_drawn = 3; /* Make buffer smaller up to 3 vertices. */
   3855 }
   3856 
   3857 void gl3cts::TransformFeedback::QueryVertexInterleaved::createTransformFeedbackBuffer(void)
   3858 {
   3859 	/* Functions handler */
   3860 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3861 
   3862 	/* Create buffer object. */
   3863 	gl3cts::TransformFeedback::CaptureVertexInterleaved::createTransformFeedbackBuffer();
   3864 
   3865 	/* Create query object. */
   3866 	gl.genQueries(1, &m_query_object);
   3867 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenQueries call failed.");
   3868 }
   3869 
   3870 void gl3cts::TransformFeedback::QueryVertexInterleaved::draw(glw::GLuint primitive_case)
   3871 {
   3872 	/* Functions handler */
   3873 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3874 
   3875 	gl.beginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, m_query_object);
   3876 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginQuery call failed.");
   3877 
   3878 	gl3cts::TransformFeedback::CaptureVertexInterleaved::draw(primitive_case);
   3879 
   3880 	gl.endQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
   3881 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndQuery call failed.");
   3882 }
   3883 
   3884 bool gl3cts::TransformFeedback::QueryVertexInterleaved::checkTransformFeedbackBuffer(BindBufferCase bind_case UNUSED,
   3885 																					 glw::GLenum primitive_type)
   3886 {
   3887 	/* Functions handler */
   3888 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3889 
   3890 	glw::GLuint number_of_primitives;
   3891 
   3892 	gl.getQueryObjectuiv(m_query_object, GL_QUERY_RESULT, &number_of_primitives);
   3893 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryObjectuiv call failed.");
   3894 
   3895 	/* expected result */
   3896 	glw::GLuint number_of_primitives_reference = (primitive_type == GL_POINTS) ? 3 : 1; /* m_max_vertices_drawn == 3 */
   3897 
   3898 	if (number_of_primitives_reference != number_of_primitives)
   3899 	{
   3900 		return false;
   3901 	}
   3902 
   3903 	return true;
   3904 }
   3905 
   3906 void gl3cts::TransformFeedback::QueryVertexInterleaved::clean(void)
   3907 {
   3908 	/* Functions handler */
   3909 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3910 
   3911 	/* Delete query object. */
   3912 	gl.deleteQueries(1, &m_query_object);
   3913 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteQueries call failed.");
   3914 
   3915 	/* Other */
   3916 	gl3cts::TransformFeedback::CaptureVertexInterleaved::clean();
   3917 }
   3918 
   3919 /*-----------------------------------------------------------------------------------------------*/
   3920 
   3921 gl3cts::TransformFeedback::QueryGeometryInterleaved::QueryGeometryInterleaved(deqp::Context& context,
   3922 																			  const char*	test_name,
   3923 																			  const char*	test_description)
   3924 	: CaptureVertexInterleaved(context, test_name, test_description)
   3925 	, CaptureGeometryInterleaved(context, test_name, test_description)
   3926 {
   3927 	m_query_object		 = 0;
   3928 	m_max_vertices_drawn = 3; /* Make buffer smaller up to 3 vertices. */
   3929 }
   3930 
   3931 void gl3cts::TransformFeedback::QueryGeometryInterleaved::createTransformFeedbackBuffer(void)
   3932 {
   3933 	/* Functions handler */
   3934 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3935 
   3936 	/* Create buffer object. */
   3937 	gl3cts::TransformFeedback::CaptureGeometryInterleaved::createTransformFeedbackBuffer();
   3938 
   3939 	/* Create query object. */
   3940 	gl.genQueries(1, &m_query_object);
   3941 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenQueries call failed.");
   3942 }
   3943 
   3944 void gl3cts::TransformFeedback::QueryGeometryInterleaved::draw(glw::GLuint primitive_case)
   3945 {
   3946 	/* Functions handler */
   3947 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3948 
   3949 	gl.beginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, m_query_object);
   3950 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginQuery call failed.");
   3951 
   3952 	gl3cts::TransformFeedback::CaptureGeometryInterleaved::draw(primitive_case);
   3953 
   3954 	gl.endQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
   3955 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndQuery call failed.");
   3956 }
   3957 
   3958 bool gl3cts::TransformFeedback::QueryGeometryInterleaved::checkTransformFeedbackBuffer(BindBufferCase bind_case UNUSED,
   3959 																					   glw::GLenum primitive_type)
   3960 {
   3961 	/* Functions handler */
   3962 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3963 
   3964 	glw::GLuint number_of_primitives;
   3965 
   3966 	gl.getQueryObjectuiv(m_query_object, GL_QUERY_RESULT, &number_of_primitives);
   3967 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryObjectuiv call failed.");
   3968 
   3969 	/* expected result */
   3970 	glw::GLuint number_of_primitives_reference = (primitive_type == GL_POINTS) ? 3 : 1; /* m_max_vertices_drawn == 3 */
   3971 
   3972 	if (number_of_primitives_reference != number_of_primitives)
   3973 	{
   3974 		return false;
   3975 	}
   3976 
   3977 	return true;
   3978 }
   3979 
   3980 void gl3cts::TransformFeedback::QueryGeometryInterleaved::clean(void)
   3981 {
   3982 	/* Functions handler */
   3983 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3984 
   3985 	/* Delete query object. */
   3986 	gl.deleteQueries(1, &m_query_object);
   3987 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteQueries call failed.");
   3988 
   3989 	/* Other. */
   3990 	gl3cts::TransformFeedback::CaptureGeometryInterleaved::clean();
   3991 }
   3992 
   3993 /*-----------------------------------------------------------------------------------------------*/
   3994 
   3995 gl3cts::TransformFeedback::QueryVertexSeparate::QueryVertexSeparate(deqp::Context& context, const char* test_name,
   3996 																	const char* test_description)
   3997 	: CaptureVertexInterleaved(context, test_name, test_description)
   3998 	, CaptureVertexSeparate(context, test_name, test_description)
   3999 {
   4000 	m_query_object		 = 0;
   4001 	m_max_vertices_drawn = 3; /* Make buffer smaller up to 3 vertices. */
   4002 }
   4003 
   4004 void gl3cts::TransformFeedback::QueryVertexSeparate::createTransformFeedbackBuffer(void)
   4005 {
   4006 	/* Functions handler */
   4007 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4008 
   4009 	/* Create buffer object. */
   4010 	gl3cts::TransformFeedback::CaptureVertexSeparate::createTransformFeedbackBuffer();
   4011 
   4012 	/* Create query object. */
   4013 	gl.genQueries(1, &m_query_object);
   4014 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenQueries call failed.");
   4015 }
   4016 
   4017 void gl3cts::TransformFeedback::QueryVertexSeparate::draw(glw::GLuint primitive_case)
   4018 {
   4019 	/* Functions handler */
   4020 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4021 
   4022 	gl.beginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, m_query_object);
   4023 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginQuery call failed.");
   4024 
   4025 	gl3cts::TransformFeedback::CaptureVertexSeparate::draw(primitive_case);
   4026 
   4027 	gl.endQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
   4028 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndQuery call failed.");
   4029 }
   4030 
   4031 bool gl3cts::TransformFeedback::QueryVertexSeparate::checkTransformFeedbackBuffer(BindBufferCase bind_case UNUSED,
   4032 																				  glw::GLenum primitive_type)
   4033 {
   4034 	/* Functions handler */
   4035 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4036 
   4037 	glw::GLuint number_of_primitives;
   4038 
   4039 	gl.getQueryObjectuiv(m_query_object, GL_QUERY_RESULT, &number_of_primitives);
   4040 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryObjectuiv call failed.");
   4041 
   4042 	/* expected result */
   4043 	glw::GLuint number_of_primitives_reference = (primitive_type == GL_POINTS) ? 3 : 1; /* m_max_vertices_drawn == 3 */
   4044 
   4045 	if (number_of_primitives_reference != number_of_primitives)
   4046 	{
   4047 		return false;
   4048 	}
   4049 
   4050 	return true;
   4051 }
   4052 
   4053 void gl3cts::TransformFeedback::QueryVertexSeparate::clean(void)
   4054 {
   4055 	/* Functions handler */
   4056 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4057 
   4058 	/* Delete query object. */
   4059 	gl.deleteQueries(1, &m_query_object);
   4060 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteQueries call failed.");
   4061 
   4062 	/* Other */
   4063 	gl3cts::TransformFeedback::CaptureVertexSeparate::clean();
   4064 }
   4065 
   4066 /*-----------------------------------------------------------------------------------------------*/
   4067 
   4068 gl3cts::TransformFeedback::QueryGeometrySeparate::QueryGeometrySeparate(deqp::Context& context, const char* test_name,
   4069 																		const char* test_description)
   4070 	: CaptureVertexInterleaved(context, test_name, test_description)
   4071 	, CaptureVertexSeparate(context, test_name, test_description)
   4072 	, CaptureGeometrySeparate(context, test_name, test_description)
   4073 {
   4074 	m_query_object		 = 0;
   4075 	m_max_vertices_drawn = 3; /* Make buffer smaller up to 3 vertices. */
   4076 }
   4077 
   4078 void gl3cts::TransformFeedback::QueryGeometrySeparate::createTransformFeedbackBuffer(void)
   4079 {
   4080 	/* Functions handler */
   4081 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4082 
   4083 	/* Create buffer object. */
   4084 	gl3cts::TransformFeedback::CaptureGeometrySeparate::createTransformFeedbackBuffer();
   4085 
   4086 	/* Create query object. */
   4087 	gl.genQueries(1, &m_query_object);
   4088 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenQueries call failed.");
   4089 }
   4090 
   4091 void gl3cts::TransformFeedback::QueryGeometrySeparate::draw(glw::GLuint primitive_case)
   4092 {
   4093 	/* Functions handler */
   4094 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4095 
   4096 	gl.beginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, m_query_object);
   4097 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginQuery call failed.");
   4098 
   4099 	gl3cts::TransformFeedback::CaptureGeometrySeparate::draw(primitive_case);
   4100 
   4101 	gl.endQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
   4102 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndQuery call failed.");
   4103 }
   4104 
   4105 bool gl3cts::TransformFeedback::QueryGeometrySeparate::checkTransformFeedbackBuffer(BindBufferCase bind_case UNUSED,
   4106 																					glw::GLenum primitive_type)
   4107 {
   4108 	/* Functions handler */
   4109 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4110 
   4111 	glw::GLuint number_of_primitives;
   4112 
   4113 	gl.getQueryObjectuiv(m_query_object, GL_QUERY_RESULT, &number_of_primitives);
   4114 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryObjectuiv call failed.");
   4115 
   4116 	/* expected result */
   4117 	glw::GLuint number_of_primitives_reference = (primitive_type == GL_POINTS) ? 3 : 1; /* m_max_vertices_drawn == 3 */
   4118 
   4119 	if (number_of_primitives_reference != number_of_primitives)
   4120 	{
   4121 		return false;
   4122 	}
   4123 
   4124 	return true;
   4125 }
   4126 
   4127 void gl3cts::TransformFeedback::QueryGeometrySeparate::clean(void)
   4128 {
   4129 	/* Functions handler */
   4130 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4131 
   4132 	/* Delete query object. */
   4133 	gl.deleteQueries(1, &m_query_object);
   4134 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteQueries call failed.");
   4135 
   4136 	/* Other */
   4137 	gl3cts::TransformFeedback::CaptureGeometrySeparate::clean();
   4138 }
   4139 
   4140 /*-----------------------------------------------------------------------------------------------*/
   4141 
   4142 gl3cts::TransformFeedback::DiscardVertex::DiscardVertex(deqp::Context& context, const char* test_name,
   4143 														const char* test_description)
   4144 	: CaptureVertexInterleaved(context, test_name, test_description)
   4145 {
   4146 }
   4147 
   4148 void gl3cts::TransformFeedback::DiscardVertex::draw(glw::GLuint primitive_case)
   4149 {
   4150 	/* Functions handler */
   4151 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4152 
   4153 	/* Must clear before rasterizer discard */
   4154 	gl.clear(GL_COLOR_BUFFER_BIT);
   4155 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed.");
   4156 
   4157 	gl.enable(GL_RASTERIZER_DISCARD);
   4158 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable call failed.");
   4159 
   4160 	gl3cts::TransformFeedback::CaptureVertexInterleaved::draw(primitive_case);
   4161 
   4162 	gl.disable(GL_RASTERIZER_DISCARD);
   4163 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable call failed.");
   4164 }
   4165 
   4166 bool gl3cts::TransformFeedback::DiscardVertex::checkFramebuffer(glw::GLuint primitive_case UNUSED)
   4167 {
   4168 	/* Functions handler */
   4169 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4170 
   4171 	/* Fetch framebuffer. */
   4172 	std::vector<glw::GLfloat> pixels(s_framebuffer_size * s_framebuffer_size);
   4173 
   4174 	if ((s_framebuffer_size > 0) && (s_framebuffer_size > 0))
   4175 	{
   4176 		gl.readPixels(0, 0, s_framebuffer_size, s_framebuffer_size, GL_RED, GL_FLOAT, pixels.data());
   4177 		GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");
   4178 	}
   4179 
   4180 	/* Check results.
   4181 	 Note: assuming that s_buffer_size == 2 -> then all points shall be drawn. */
   4182 	for (std::vector<glw::GLfloat>::iterator i = pixels.begin(); i != pixels.end(); ++i)
   4183 	{
   4184 		if (fabs(*i) > 0.0625f /* precision */)
   4185 		{
   4186 			return false;
   4187 		}
   4188 	}
   4189 
   4190 	return true;
   4191 }
   4192 
   4193 /*-----------------------------------------------------------------------------------------------*/
   4194 
   4195 gl3cts::TransformFeedback::DiscardGeometry::DiscardGeometry(deqp::Context& context, const char* test_name,
   4196 															const char* test_description)
   4197 	: CaptureVertexInterleaved(context, test_name, test_description)
   4198 	, CaptureGeometryInterleaved(context, test_name, test_description)
   4199 {
   4200 }
   4201 
   4202 void gl3cts::TransformFeedback::DiscardGeometry::draw(glw::GLuint primitive_case)
   4203 {
   4204 	/* Functions handler */
   4205 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4206 
   4207 	/* Must clear before rasterizer discard */
   4208 	gl.clear(GL_COLOR_BUFFER_BIT);
   4209 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed.");
   4210 
   4211 	gl.enable(GL_RASTERIZER_DISCARD);
   4212 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable call failed.");
   4213 
   4214 	gl3cts::TransformFeedback::CaptureGeometryInterleaved::draw(primitive_case);
   4215 
   4216 	gl.disable(GL_RASTERIZER_DISCARD);
   4217 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable call failed.");
   4218 }
   4219 
   4220 bool gl3cts::TransformFeedback::DiscardGeometry::checkFramebuffer(glw::GLuint primitive_case UNUSED)
   4221 {
   4222 	/* Functions handler */
   4223 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4224 
   4225 	/* Fetch framebuffer. */
   4226 	std::vector<glw::GLfloat> pixels(s_framebuffer_size * s_framebuffer_size);
   4227 
   4228 	if ((s_framebuffer_size > 0) && (s_framebuffer_size > 0))
   4229 	{
   4230 		gl.readPixels(0, 0, s_framebuffer_size, s_framebuffer_size, GL_RED, GL_FLOAT, pixels.data());
   4231 		GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");
   4232 	}
   4233 
   4234 	/* Check results.
   4235 	 Note: assuming that s_buffer_size == 2 -> then all points shall be drawn. */
   4236 	for (std::vector<glw::GLfloat>::iterator i = pixels.begin(); i != pixels.end(); ++i)
   4237 	{
   4238 		if (fabs(*i) > 0.0625f /* precision */)
   4239 		{
   4240 			return false;
   4241 		}
   4242 	}
   4243 
   4244 	return true;
   4245 }
   4246 
   4247 /*-----------------------------------------------------------------------------------------------*/
   4248 
   4249 gl3cts::TransformFeedback::DrawXFB::DrawXFB(deqp::Context& context, const char* test_name, const char* test_description)
   4250 	: deqp::TestCase(context, test_name, test_description)
   4251 	, m_context(context)
   4252 	, m_program_id_xfb(0)
   4253 	, m_program_id_draw(0)
   4254 	, m_fbo_id(0)
   4255 	, m_rbo_id(0)
   4256 	, m_vao_id(0)
   4257 {
   4258 	memset(m_xfb_id, 0, sizeof(m_xfb_id));
   4259 	memset(m_bo_id, 0, sizeof(m_bo_id));
   4260 }
   4261 
   4262 gl3cts::TransformFeedback::DrawXFB::~DrawXFB(void)
   4263 {
   4264 }
   4265 
   4266 tcu::TestNode::IterateResult gl3cts::TransformFeedback::DrawXFB::iterate(void)
   4267 {
   4268 	/* Initializations. */
   4269 	bool is_at_least_gl_40 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 0)));
   4270 	bool is_arb_tf_2	   = m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback2");
   4271 
   4272 	bool is_ok		= true;
   4273 	bool test_error = false;
   4274 
   4275 	/* Tests. */
   4276 	try
   4277 	{
   4278 		if (is_at_least_gl_40 || is_arb_tf_2)
   4279 		{
   4280 			for (glw::GLuint i = 0; (i < s_capture_modes_count) && is_ok; ++i)
   4281 			{
   4282 				prepare(s_capture_modes[i]);
   4283 
   4284 				bindVAO(m_vao_id);
   4285 				useProgram(m_program_id_xfb);
   4286 
   4287 				for (glw::GLuint j = 0; (j < s_xfb_count) && is_ok; ++j)
   4288 				{
   4289 					bindXFB(m_xfb_id[j]);
   4290 					bindBOForXFB(s_capture_modes[i], m_bo_id[j]);
   4291 					useColour(m_program_id_xfb, s_colours[j][0], s_colours[j][1], s_colours[j][2], s_colours[j][3]);
   4292 					useGeometrySet(m_program_id_xfb, false);
   4293 					drawForCapture(true, true, false, false);
   4294 
   4295 					is_ok = is_ok && inspectXFBState(true, true);
   4296 				}
   4297 
   4298 				for (glw::GLuint j = 0; (j < s_xfb_count) && is_ok; ++j)
   4299 				{
   4300 					bindXFB(m_xfb_id[j]);
   4301 					useColour(m_program_id_xfb, s_colours[j][0], s_colours[j][1], s_colours[j][2], s_colours[j][3]);
   4302 					useGeometrySet(m_program_id_xfb, true);
   4303 					drawForCapture(false, false, true, true);
   4304 
   4305 					is_ok = is_ok && inspectXFBState(false, false);
   4306 				}
   4307 
   4308 				useProgram(m_program_id_draw);
   4309 
   4310 				for (glw::GLuint j = 0; (j < s_xfb_count) && is_ok; ++j)
   4311 				{
   4312 					bindXFB(m_xfb_id[j]);
   4313 					bindBOForDraw(m_program_id_draw, s_capture_modes[i], m_bo_id[j]);
   4314 					drawToFramebuffer(m_xfb_id[j]);
   4315 
   4316 					is_ok =
   4317 						is_ok && checkFramebuffer(s_colours[j][0], s_colours[j][1], s_colours[j][2], s_colours[j][3]);
   4318 				}
   4319 
   4320 				clean();
   4321 			}
   4322 		}
   4323 	}
   4324 	catch (...)
   4325 	{
   4326 		is_ok	  = false;
   4327 		test_error = true;
   4328 		clean();
   4329 	}
   4330 
   4331 	/* Result's setup. */
   4332 	if (is_ok)
   4333 	{
   4334 		/* Log success. */
   4335 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB have passed."
   4336 											<< tcu::TestLog::EndMessage;
   4337 
   4338 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   4339 	}
   4340 	else
   4341 	{
   4342 		if (test_error)
   4343 		{
   4344 			/* Log error. */
   4345 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB have approached error."
   4346 												<< tcu::TestLog::EndMessage;
   4347 
   4348 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   4349 		}
   4350 		else
   4351 		{
   4352 			/* Log fail. */
   4353 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB have failed."
   4354 												<< tcu::TestLog::EndMessage;
   4355 
   4356 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   4357 		}
   4358 	}
   4359 
   4360 	return STOP;
   4361 }
   4362 
   4363 void gl3cts::TransformFeedback::DrawXFB::prepare(glw::GLenum capture_mode)
   4364 {
   4365 	/* Functions handler */
   4366 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4367 
   4368 	/* Prepare programs. */
   4369 	m_program_id_xfb = gl3cts::TransformFeedback::Utilities::buildProgram(
   4370 		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, s_vertex_shader_xfb, s_fragment_shader,
   4371 		s_xfb_varyings, s_xfb_varyings_count, capture_mode);
   4372 
   4373 	if (0 == m_program_id_xfb)
   4374 	{
   4375 		throw 0;
   4376 	}
   4377 
   4378 	m_program_id_draw = gl3cts::TransformFeedback::Utilities::buildProgram(gl, m_context.getTestContext().getLog(),
   4379 																		   NULL, NULL, NULL, s_vertex_shader_draw,
   4380 																		   s_fragment_shader, NULL, 0, capture_mode);
   4381 
   4382 	if (0 == m_program_id_draw)
   4383 	{
   4384 		throw 0;
   4385 	}
   4386 
   4387 	/* Prepare transform feedbacks. */
   4388 	gl.genTransformFeedbacks(s_xfb_count, m_xfb_id);
   4389 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTransformFeedbacks call failed.");
   4390 
   4391 	/* Prepare buffer objects. */
   4392 	gl.genBuffers(s_xfb_count, m_bo_id);
   4393 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   4394 
   4395 	for (glw::GLuint i = 0; i < s_xfb_count; ++i)
   4396 	{
   4397 		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id[i]);
   4398 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   4399 
   4400 		gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, s_capture_size, NULL, GL_DYNAMIC_COPY);
   4401 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
   4402 	}
   4403 
   4404 	/* Prepare framebuffer. */
   4405 	gl.clearColor(0.f, 0.f, 0.f, 1.f);
   4406 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");
   4407 
   4408 	gl.genFramebuffers(1, &m_fbo_id);
   4409 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
   4410 
   4411 	gl.genRenderbuffers(1, &m_rbo_id);
   4412 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
   4413 
   4414 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id);
   4415 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
   4416 
   4417 	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_id);
   4418 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
   4419 
   4420 	gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, s_view_size, s_view_size);
   4421 	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed.");
   4422 
   4423 	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo_id);
   4424 	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed.");
   4425 
   4426 	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
   4427 	{
   4428 		throw 0;
   4429 	}
   4430 
   4431 	gl.viewport(0, 0, s_view_size, s_view_size);
   4432 	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
   4433 
   4434 	/* Create empty Vertex Array Object */
   4435 	gl.genVertexArrays(1, &m_vao_id);
   4436 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
   4437 }
   4438 
   4439 void gl3cts::TransformFeedback::DrawXFB::bindXFB(glw::GLuint xfb_id)
   4440 {
   4441 	/* Functions handler */
   4442 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4443 
   4444 	gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, xfb_id);
   4445 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedback call failed.");
   4446 }
   4447 
   4448 void gl3cts::TransformFeedback::DrawXFB::bindVAO(glw::GLuint vao_id)
   4449 {
   4450 	/* Functions handler */
   4451 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4452 
   4453 	gl.bindVertexArray(vao_id);
   4454 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   4455 }
   4456 
   4457 void gl3cts::TransformFeedback::DrawXFB::bindBOForXFB(glw::GLenum capture_mode, glw::GLuint bo_id)
   4458 {
   4459 	/* Functions handler */
   4460 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4461 
   4462 	switch (capture_mode)
   4463 	{
   4464 	case GL_INTERLEAVED_ATTRIBS:
   4465 		gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, bo_id);
   4466 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed.");
   4467 		break;
   4468 	case GL_SEPARATE_ATTRIBS:
   4469 		for (glw::GLuint i = 0; i < s_xfb_varyings_count; ++i)
   4470 		{
   4471 			gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, i, bo_id, i * s_capture_size / s_xfb_varyings_count,
   4472 							   (i + 1) * s_capture_size / s_xfb_varyings_count);
   4473 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed.");
   4474 		}
   4475 		break;
   4476 	default:
   4477 		throw 0;
   4478 	};
   4479 }
   4480 
   4481 void gl3cts::TransformFeedback::DrawXFB::bindBOForDraw(glw::GLuint program_id, glw::GLenum capture_mode,
   4482 													   glw::GLuint bo_id)
   4483 {
   4484 	/* Functions handler */
   4485 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4486 
   4487 	gl.bindBuffer(GL_ARRAY_BUFFER, bo_id);
   4488 
   4489 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   4490 
   4491 	glw::GLuint position_location = gl.getAttribLocation(program_id, "position");
   4492 	glw::GLuint color_location	= gl.getAttribLocation(program_id, "color");
   4493 
   4494 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation call failed.");
   4495 
   4496 	glw::GLvoid* color_offset = (capture_mode == GL_INTERLEAVED_ATTRIBS) ?
   4497 									(glw::GLvoid*)(4 /* components */ * sizeof(glw::GLfloat)) :
   4498 									(glw::GLvoid*)(4 /* components */ * 6 /* vertices */ * sizeof(glw::GLfloat));
   4499 
   4500 	glw::GLuint stride =
   4501 		static_cast<glw::GLuint>((capture_mode == GL_INTERLEAVED_ATTRIBS) ?
   4502 									 (4 /* components */ * 2 /* position and color */ * sizeof(glw::GLfloat)) :
   4503 									 (4 /* components */ * sizeof(glw::GLfloat)));
   4504 
   4505 	gl.vertexAttribPointer(position_location, 4, GL_FLOAT, GL_FALSE, stride, NULL);
   4506 	gl.vertexAttribPointer(color_location, 4, GL_FLOAT, GL_FALSE, stride, color_offset);
   4507 
   4508 	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed.");
   4509 
   4510 	gl.enableVertexAttribArray(position_location);
   4511 	gl.enableVertexAttribArray(color_location);
   4512 
   4513 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
   4514 }
   4515 
   4516 void gl3cts::TransformFeedback::DrawXFB::useProgram(glw::GLuint program_id)
   4517 {
   4518 	/* Functions handler */
   4519 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4520 
   4521 	gl.useProgram(program_id);
   4522 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
   4523 }
   4524 
   4525 void gl3cts::TransformFeedback::DrawXFB::useColour(glw::GLuint program_id, glw::GLfloat r, glw::GLfloat g,
   4526 												   glw::GLfloat b, glw::GLfloat a)
   4527 {
   4528 	/* Functions handler */
   4529 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4530 
   4531 	glw::GLint location = gl.getUniformLocation(program_id, "color");
   4532 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation call failed.");
   4533 
   4534 	gl.uniform4f(location, r, g, b, a);
   4535 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform4f call failed.");
   4536 }
   4537 
   4538 void gl3cts::TransformFeedback::DrawXFB::useGeometrySet(glw::GLuint program_id, bool invert_sign)
   4539 {
   4540 	/* Functions handler */
   4541 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4542 
   4543 	glw::GLint location = gl.getUniformLocation(program_id, "invert_sign");
   4544 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation call failed.");
   4545 
   4546 	gl.uniform1f(location, invert_sign ? -1.f : 1.f);
   4547 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform4f call failed.");
   4548 }
   4549 
   4550 void gl3cts::TransformFeedback::DrawXFB::clean()
   4551 {
   4552 	/* Functions handler */
   4553 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4554 
   4555 	gl.useProgram(0);
   4556 
   4557 	if (m_program_id_xfb)
   4558 	{
   4559 		gl.deleteProgram(m_program_id_xfb);
   4560 
   4561 		m_program_id_xfb = 0;
   4562 	}
   4563 
   4564 	if (m_program_id_draw)
   4565 	{
   4566 		gl.deleteProgram(m_program_id_draw);
   4567 
   4568 		m_program_id_draw = 1;
   4569 	}
   4570 
   4571 	for (glw::GLuint i = 0; i < s_xfb_count; ++i)
   4572 	{
   4573 		if (m_xfb_id[i])
   4574 		{
   4575 			gl.deleteTransformFeedbacks(1, &m_xfb_id[i]);
   4576 
   4577 			m_xfb_id[i] = 0;
   4578 		}
   4579 	}
   4580 
   4581 	for (glw::GLuint i = 0; i < s_xfb_count; ++i)
   4582 	{
   4583 		if (m_bo_id[i])
   4584 		{
   4585 			gl.deleteBuffers(1, &m_bo_id[i]);
   4586 
   4587 			m_bo_id[i] = 0;
   4588 		}
   4589 	}
   4590 
   4591 	if (m_vao_id)
   4592 	{
   4593 		gl.deleteVertexArrays(1, &m_vao_id);
   4594 
   4595 		m_vao_id = 0;
   4596 	}
   4597 
   4598 	if (m_fbo_id)
   4599 	{
   4600 		gl.deleteFramebuffers(1, &m_fbo_id);
   4601 
   4602 		m_fbo_id = 0;
   4603 	}
   4604 
   4605 	if (m_rbo_id)
   4606 	{
   4607 		gl.deleteRenderbuffers(1, &m_rbo_id);
   4608 
   4609 		m_rbo_id = 0;
   4610 	}
   4611 }
   4612 
   4613 void gl3cts::TransformFeedback::DrawXFB::drawForCapture(bool begin_xfb, bool pause_xfb, bool resume_xfb, bool end_xfb)
   4614 {
   4615 	/* Functions handler */
   4616 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4617 
   4618 	gl.enable(GL_RASTERIZER_DISCARD);
   4619 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable call failed.");
   4620 
   4621 	if (begin_xfb)
   4622 	{
   4623 		gl.beginTransformFeedback(GL_POINTS);
   4624 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
   4625 	}
   4626 
   4627 	if (resume_xfb)
   4628 	{
   4629 		gl.resumeTransformFeedback();
   4630 		GLU_EXPECT_NO_ERROR(gl.getError(), "glResumeTransformFeedback call failed.");
   4631 	}
   4632 
   4633 	gl.drawArrays(GL_POINTS, 0, 3);
   4634 
   4635 	if (pause_xfb)
   4636 	{
   4637 		gl.pauseTransformFeedback();
   4638 		GLU_EXPECT_NO_ERROR(gl.getError(), "glPauseTransformFeedback call failed.");
   4639 	}
   4640 
   4641 	if (end_xfb)
   4642 	{
   4643 		gl.endTransformFeedback();
   4644 		GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
   4645 	}
   4646 
   4647 	gl.disable(GL_RASTERIZER_DISCARD);
   4648 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable call failed.");
   4649 }
   4650 
   4651 void gl3cts::TransformFeedback::DrawXFB::drawToFramebuffer(glw::GLuint xfb_id)
   4652 {
   4653 	/* Functions handler */
   4654 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4655 
   4656 	gl.clearColor(0.f, 0.f, 0.f, 0.f);
   4657 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");
   4658 
   4659 	gl.clear(GL_COLOR_BUFFER_BIT);
   4660 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed.");
   4661 
   4662 	gl.drawTransformFeedback(GL_TRIANGLES, xfb_id);
   4663 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawTransformFeedback call failed.");
   4664 }
   4665 
   4666 bool gl3cts::TransformFeedback::DrawXFB::checkFramebuffer(glw::GLfloat r, glw::GLfloat g, glw::GLfloat b,
   4667 														  glw::GLfloat a)
   4668 {
   4669 	/* Functions handler */
   4670 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4671 
   4672 	/* Number of pixels. */
   4673 	const glw::GLuint number_of_pixels = s_view_size * s_view_size;
   4674 
   4675 	/* Fetch framebuffer. */
   4676 	std::vector<glw::GLubyte> pixels(number_of_pixels * 4 /* components */);
   4677 
   4678 	if ((s_view_size > 0) && (s_view_size > 0))
   4679 	{
   4680 		gl.readPixels(0, 0, s_view_size, s_view_size, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
   4681 		GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");
   4682 	}
   4683 
   4684 	/* Convert color to integer. */
   4685 	glw::GLubyte ir = (glw::GLubyte)(255.f * r);
   4686 	glw::GLubyte ig = (glw::GLubyte)(255.f * g);
   4687 	glw::GLubyte ib = (glw::GLubyte)(255.f * b);
   4688 	glw::GLubyte ia = (glw::GLubyte)(255.f * a);
   4689 
   4690 	/* Check results. */
   4691 	for (glw::GLuint i = 0; i < number_of_pixels; ++i)
   4692 	{
   4693 		if ((pixels[i * 4 /* components */] != ir) || (pixels[i * 4 /* components */ + 1] != ig) ||
   4694 			(pixels[i * 4 /* components */ + 2] != ib) || (pixels[i * 4 /* components */ + 3] != ia))
   4695 		{
   4696 			return false;
   4697 		}
   4698 	}
   4699 
   4700 	return true;
   4701 }
   4702 
   4703 bool gl3cts::TransformFeedback::DrawXFB::inspectXFBState(bool shall_be_paused, bool shall_be_active)
   4704 {
   4705 	/* Functions handler */
   4706 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4707 
   4708 	glw::GLint is_paused = 0;
   4709 	glw::GLint is_active = 0;
   4710 
   4711 	gl.getIntegerv(GL_TRANSFORM_FEEDBACK_PAUSED, &is_paused);
   4712 	gl.getIntegerv(GL_TRANSFORM_FEEDBACK_ACTIVE, &is_active);
   4713 
   4714 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   4715 
   4716 	if ((is_paused == -1) || (is_active == -1))
   4717 	{
   4718 		throw 0;
   4719 	}
   4720 
   4721 	if (shall_be_paused ^ (is_paused == GL_TRUE))
   4722 	{
   4723 		return false;
   4724 	}
   4725 
   4726 	if (shall_be_active ^ (is_active == GL_TRUE))
   4727 	{
   4728 		return false;
   4729 	}
   4730 
   4731 	return true;
   4732 }
   4733 
   4734 const glw::GLchar* gl3cts::TransformFeedback::DrawXFB::s_vertex_shader_xfb =
   4735 	"#version 130\n"
   4736 	"\n"
   4737 	"uniform vec4 color;\n"
   4738 	"uniform float invert_sign;\n"
   4739 	"out     vec4 colour;\n"
   4740 	"\n"
   4741 	"void main()\n"
   4742 	"{\n"
   4743 	"    switch(gl_VertexID)\n"
   4744 	"    {\n"
   4745 	"        case 0:\n"
   4746 	"            gl_Position = vec4(-1.0,               -1.0,              0.0,  1.0);\n"
   4747 	"        break;\n"
   4748 	"        case 1:\n"
   4749 	"            gl_Position = vec4(-1.0 * invert_sign,  1.0,              0.0,  1.0);\n"
   4750 	"        break;\n"
   4751 	"        case 2:\n"
   4752 	"            gl_Position = vec4( 1.0,                1.0 * invert_sign, 0.0,  1.0);\n"
   4753 	"        break;\n"
   4754 	"    }\n"
   4755 	"\n"
   4756 	"    colour = color;\n"
   4757 	"}\n";
   4758 
   4759 const glw::GLchar* gl3cts::TransformFeedback::DrawXFB::s_vertex_shader_draw = "#version 130\n"
   4760 																			  "\n"
   4761 																			  "in  vec4 color;\n"
   4762 																			  "in  vec4 position;\n"
   4763 																			  "out vec4 colour;\n"
   4764 																			  "\n"
   4765 																			  "void main()\n"
   4766 																			  "{\n"
   4767 																			  "    gl_Position = position;\n"
   4768 																			  "    colour      = color;\n"
   4769 																			  "}\n";
   4770 
   4771 const glw::GLchar* gl3cts::TransformFeedback::DrawXFB::s_fragment_shader = "#version 130\n"
   4772 																		   "\n"
   4773 																		   "in  vec4 colour;\n"
   4774 																		   "out vec4 pixel;\n"
   4775 																		   "\n"
   4776 																		   "void main()\n"
   4777 																		   "{\n"
   4778 																		   "    pixel = colour;\n"
   4779 																		   "}\n";
   4780 
   4781 const glw::GLchar* gl3cts::TransformFeedback::DrawXFB::s_xfb_varyings[s_xfb_varyings_count] = { "gl_Position",
   4782 																								"colour" };
   4783 
   4784 const glw::GLenum gl3cts::TransformFeedback::DrawXFB::s_capture_modes[] = { GL_INTERLEAVED_ATTRIBS,
   4785 																			GL_SEPARATE_ATTRIBS };
   4786 const glw::GLuint gl3cts::TransformFeedback::DrawXFB::s_capture_modes_count =
   4787 	sizeof(s_capture_modes) / sizeof(s_capture_modes[0]);
   4788 
   4789 const glw::GLfloat gl3cts::TransformFeedback::DrawXFB::s_colours[s_xfb_count][4] = { { 1.f, 0.f, 0.f, 1.f },
   4790 																					 { 0.f, 1.f, 0.f, 1.f },
   4791 																					 { 0.f, 0.f, 1.f, 1.f } };
   4792 
   4793 /*-----------------------------------------------------------------------------------------------*/
   4794 
   4795 gl3cts::TransformFeedback::DrawXFBFeedback::DrawXFBFeedback(deqp::Context& context, const char* test_name,
   4796 															const char* test_description)
   4797 	: deqp::TestCase(context, test_name, test_description)
   4798 	, m_context(context)
   4799 	, m_program_id(0)
   4800 	, m_xfb_id(0)
   4801 	, m_source_bo_index(0)
   4802 {
   4803 	memset(m_bo_id, 1, sizeof(m_bo_id));
   4804 	memset(m_bo_id, 1, sizeof(m_vao_id));
   4805 }
   4806 
   4807 gl3cts::TransformFeedback::DrawXFBFeedback::~DrawXFBFeedback(void)
   4808 {
   4809 }
   4810 
   4811 tcu::TestNode::IterateResult gl3cts::TransformFeedback::DrawXFBFeedback::iterate(void)
   4812 {
   4813 	/* Initializations. */
   4814 	bool is_at_least_gl_40 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 0)));
   4815 	bool is_arb_tf_2	   = m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback2");
   4816 
   4817 	bool is_ok		= true;
   4818 	bool test_error = false;
   4819 
   4820 	/* Tests. */
   4821 	try
   4822 	{
   4823 		if (is_at_least_gl_40 || is_arb_tf_2)
   4824 		{
   4825 			prepareAndBind();
   4826 			draw(true);
   4827 			swapBuffers();
   4828 			draw(false);
   4829 			swapBuffers();
   4830 			draw(false);
   4831 
   4832 			is_ok = is_ok && check();
   4833 		}
   4834 	}
   4835 	catch (...)
   4836 	{
   4837 		is_ok	  = false;
   4838 		test_error = true;
   4839 	}
   4840 
   4841 	/* Clean GL objects. */
   4842 	clean();
   4843 
   4844 	/* Result's setup. */
   4845 	if (is_ok)
   4846 	{
   4847 		/* Log success. */
   4848 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB Feedback have passed."
   4849 											<< tcu::TestLog::EndMessage;
   4850 
   4851 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   4852 	}
   4853 	else
   4854 	{
   4855 		if (test_error)
   4856 		{
   4857 			/* Log error. */
   4858 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB Feedback have approached error."
   4859 												<< tcu::TestLog::EndMessage;
   4860 
   4861 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   4862 		}
   4863 		else
   4864 		{
   4865 			/* Log fail. */
   4866 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB Feedback have failed."
   4867 												<< tcu::TestLog::EndMessage;
   4868 
   4869 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   4870 		}
   4871 	}
   4872 
   4873 	return STOP;
   4874 }
   4875 
   4876 void gl3cts::TransformFeedback::DrawXFBFeedback::prepareAndBind()
   4877 {
   4878 	/* Functions handler */
   4879 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4880 
   4881 	/* Prepare programs. */
   4882 	m_program_id = gl3cts::TransformFeedback::Utilities::buildProgram(gl, m_context.getTestContext().getLog(), NULL,
   4883 																	  NULL, NULL, s_vertex_shader, s_fragment_shader,
   4884 																	  &s_xfb_varying, 1, GL_INTERLEAVED_ATTRIBS);
   4885 
   4886 	if (0 == m_program_id)
   4887 	{
   4888 		throw 0;
   4889 	}
   4890 
   4891 	gl.useProgram(m_program_id);
   4892 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
   4893 
   4894 	/* Prepare transform feedbacks. */
   4895 	gl.genTransformFeedbacks(1, &m_xfb_id);
   4896 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTransformFeedbacks call failed.");
   4897 
   4898 	gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_xfb_id);
   4899 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedbacks call failed.");
   4900 
   4901 	/* Prepare buffer objects. */
   4902 	gl.genBuffers(s_bo_count, m_bo_id);
   4903 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   4904 
   4905 	gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id[0]);
   4906 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   4907 
   4908 	gl.bufferData(GL_ARRAY_BUFFER, s_bo_size, s_initial_data, GL_DYNAMIC_COPY);
   4909 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
   4910 
   4911 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_id[1]);
   4912 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   4913 
   4914 	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, s_bo_size, NULL, GL_DYNAMIC_COPY);
   4915 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
   4916 
   4917 	/* Setup vertex arrays. */
   4918 	gl.genVertexArrays(s_bo_count, m_vao_id);
   4919 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
   4920 
   4921 	glw::GLuint position_location = gl.getAttribLocation(m_program_id, "position");
   4922 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation call failed.");
   4923 
   4924 	for (glw::GLuint i = 0; i < 2; ++i)
   4925 	{
   4926 		gl.bindVertexArray(m_vao_id[i]);
   4927 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   4928 
   4929 		gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id[i]);
   4930 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   4931 
   4932 		gl.vertexAttribPointer(position_location, 4, GL_FLOAT, GL_FALSE, 0, NULL);
   4933 		GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed.");
   4934 
   4935 		gl.enableVertexAttribArray(position_location);
   4936 		GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
   4937 	}
   4938 
   4939 	gl.bindBuffer(GL_ARRAY_BUFFER, 0);
   4940 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   4941 
   4942 	gl.bindVertexArray(m_vao_id[0]);
   4943 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   4944 }
   4945 
   4946 void gl3cts::TransformFeedback::DrawXFBFeedback::swapBuffers()
   4947 {
   4948 	/* Functions handler */
   4949 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4950 
   4951 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_id[m_source_bo_index]);
   4952 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   4953 
   4954 	m_source_bo_index = (m_source_bo_index + 1) % 2;
   4955 
   4956 	gl.bindVertexArray(m_vao_id[(m_source_bo_index)]);
   4957 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   4958 }
   4959 
   4960 void gl3cts::TransformFeedback::DrawXFBFeedback::draw(bool is_first_draw)
   4961 {
   4962 	/* Functions handler */
   4963 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4964 
   4965 	gl.enable(GL_RASTERIZER_DISCARD);
   4966 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable call failed.");
   4967 
   4968 	gl.beginTransformFeedback(GL_POINTS);
   4969 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
   4970 
   4971 	if (is_first_draw)
   4972 	{
   4973 		gl.drawArrays(GL_POINTS, 0, 1);
   4974 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
   4975 	}
   4976 	else
   4977 	{
   4978 		gl.drawTransformFeedback(GL_POINTS, m_xfb_id);
   4979 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawTransformFeedback call failed.");
   4980 	}
   4981 
   4982 	gl.endTransformFeedback();
   4983 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
   4984 
   4985 	gl.disable(GL_RASTERIZER_DISCARD);
   4986 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable call failed.");
   4987 }
   4988 
   4989 bool gl3cts::TransformFeedback::DrawXFBFeedback::check()
   4990 {
   4991 	/* Functions handler */
   4992 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4993 
   4994 	glw::GLfloat* results =
   4995 		(glw::GLfloat*)gl.mapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, s_bo_size, GL_MAP_READ_BIT);
   4996 	GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange call failed.");
   4997 
   4998 	bool is_ok = false;
   4999 
   5000 	if (results)
   5001 	{
   5002 		if ((results[0] == 8.f) && (results[1] == 16.f) && (results[2] == 24.f) && (results[3] == 32.f))
   5003 		{
   5004 			is_ok = true;
   5005 		}
   5006 
   5007 		gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   5008 		GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");
   5009 	}
   5010 
   5011 	return is_ok;
   5012 }
   5013 
   5014 void gl3cts::TransformFeedback::DrawXFBFeedback::clean()
   5015 {
   5016 	/* Functions handler */
   5017 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5018 
   5019 	gl.useProgram(0);
   5020 
   5021 	if (m_program_id)
   5022 	{
   5023 		gl.deleteProgram(m_program_id);
   5024 
   5025 		m_program_id = 0;
   5026 	}
   5027 
   5028 	if (m_xfb_id)
   5029 	{
   5030 		gl.deleteTransformFeedbacks(1, &m_xfb_id);
   5031 
   5032 		m_xfb_id = 0;
   5033 	}
   5034 
   5035 	for (glw::GLuint i = 0; i < s_bo_count; ++i)
   5036 	{
   5037 		if (m_bo_id[i])
   5038 		{
   5039 			gl.deleteBuffers(1, &m_bo_id[i]);
   5040 
   5041 			m_bo_id[i] = 0;
   5042 		}
   5043 	}
   5044 
   5045 	for (glw::GLuint i = 0; i < s_bo_count; ++i)
   5046 	{
   5047 		if (m_vao_id[i])
   5048 		{
   5049 			gl.deleteVertexArrays(1, &m_vao_id[i]);
   5050 
   5051 			m_vao_id[i] = 0;
   5052 		}
   5053 	}
   5054 }
   5055 
   5056 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBFeedback::s_vertex_shader = "#version 130\n"
   5057 																				 "\n"
   5058 																				 "in  vec4 position;\n"
   5059 																				 "\n"
   5060 																				 "void main()\n"
   5061 																				 "{\n"
   5062 																				 "    gl_Position = position * 2.0;\n"
   5063 																				 "}\n";
   5064 
   5065 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBFeedback::s_fragment_shader = "#version 130\n"
   5066 																				   "\n"
   5067 																				   "out vec4 pixel;\n"
   5068 																				   "\n"
   5069 																				   "void main()\n"
   5070 																				   "{\n"
   5071 																				   "    pixel = vec4(1.0);\n"
   5072 																				   "}\n";
   5073 
   5074 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBFeedback::s_xfb_varying = "gl_Position";
   5075 
   5076 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBFeedback::s_attrib = "position";
   5077 
   5078 const glw::GLfloat gl3cts::TransformFeedback::DrawXFBFeedback::s_initial_data[] = { 1.f, 2.f, 3.f, 4.f };
   5079 
   5080 const glw::GLuint gl3cts::TransformFeedback::DrawXFBFeedback::s_draw_vertex_count =
   5081 	sizeof(s_initial_data) / sizeof(s_initial_data[0]) / 4 /* components */;
   5082 
   5083 const glw::GLuint gl3cts::TransformFeedback::DrawXFBFeedback::s_bo_size = sizeof(s_initial_data);
   5084 
   5085 /*-----------------------------------------------------------------------------------------------*/
   5086 
   5087 gl3cts::TransformFeedback::CaptureSpecialInterleaved::CaptureSpecialInterleaved(deqp::Context& context,
   5088 																				const char*	test_name,
   5089 																				const char*	test_description)
   5090 	: deqp::TestCase(context, test_name, test_description)
   5091 	, m_context(context)
   5092 	, m_program_id(0)
   5093 	, m_vao_id(0)
   5094 	, m_xfb_id(0)
   5095 {
   5096 	memset(m_bo_id, 0, sizeof(m_bo_id));
   5097 }
   5098 
   5099 gl3cts::TransformFeedback::CaptureSpecialInterleaved::~CaptureSpecialInterleaved(void)
   5100 {
   5101 }
   5102 
   5103 tcu::TestNode::IterateResult gl3cts::TransformFeedback::CaptureSpecialInterleaved::iterate(void)
   5104 {
   5105 	/* Initializations. */
   5106 	bool is_at_least_gl_40 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 0)));
   5107 	bool is_arb_tf_3	   = m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback3");
   5108 
   5109 	bool is_ok		= true;
   5110 	bool test_error = false;
   5111 
   5112 	/* Tests. */
   5113 	try
   5114 	{
   5115 		if (is_at_least_gl_40 || is_arb_tf_3)
   5116 		{
   5117 			prepareAndBind();
   5118 			draw();
   5119 
   5120 			is_ok = is_ok && check();
   5121 		}
   5122 	}
   5123 	catch (...)
   5124 	{
   5125 		is_ok	  = false;
   5126 		test_error = true;
   5127 	}
   5128 
   5129 	/* Clean GL objects. */
   5130 	clean();
   5131 
   5132 	/* Result's setup. */
   5133 	if (is_ok)
   5134 	{
   5135 		/* Log success. */
   5136 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Capture Special Interleaved have passed."
   5137 											<< tcu::TestLog::EndMessage;
   5138 
   5139 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   5140 	}
   5141 	else
   5142 	{
   5143 		if (test_error)
   5144 		{
   5145 			/* Log error. */
   5146 			m_context.getTestContext().getLog() << tcu::TestLog::Message
   5147 												<< "Capture Special Interleaved have approached error."
   5148 												<< tcu::TestLog::EndMessage;
   5149 
   5150 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   5151 		}
   5152 		else
   5153 		{
   5154 			/* Log fail. */
   5155 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Capture Special Interleaved have failed."
   5156 												<< tcu::TestLog::EndMessage;
   5157 
   5158 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   5159 		}
   5160 	}
   5161 
   5162 	return STOP;
   5163 }
   5164 
   5165 void gl3cts::TransformFeedback::CaptureSpecialInterleaved::prepareAndBind()
   5166 {
   5167 	/* Functions handler */
   5168 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5169 
   5170 	/* Prepare programs. */
   5171 	m_program_id = gl3cts::TransformFeedback::Utilities::buildProgram(
   5172 		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, s_vertex_shader, s_fragment_shader, s_xfb_varyings,
   5173 		s_xfb_varyings_count, GL_INTERLEAVED_ATTRIBS);
   5174 
   5175 	if (0 == m_program_id)
   5176 	{
   5177 		throw 0;
   5178 	}
   5179 
   5180 	gl.useProgram(m_program_id);
   5181 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
   5182 
   5183 	/* Prepare transform feedbacks. */
   5184 	gl.genTransformFeedbacks(1, &m_xfb_id);
   5185 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTransformFeedbacks call failed.");
   5186 
   5187 	gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_xfb_id);
   5188 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedbacks call failed.");
   5189 
   5190 	/* Create empty Vertex Array Object */
   5191 	gl.genVertexArrays(1, &m_vao_id);
   5192 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
   5193 
   5194 	gl.bindVertexArray(m_vao_id);
   5195 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   5196 
   5197 	/* Prepare buffer objects. */
   5198 	gl.genBuffers(s_bo_ids_count, m_bo_id);
   5199 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   5200 
   5201 	for (glw::GLuint i = 0; i < s_bo_ids_count; ++i)
   5202 	{
   5203 		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id[i]);
   5204 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   5205 
   5206 		gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, s_bo_size, NULL, GL_DYNAMIC_COPY); /* allocation */
   5207 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
   5208 
   5209 		gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, i, m_bo_id[i]);
   5210 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferRange call failed.");
   5211 	}
   5212 }
   5213 
   5214 void gl3cts::TransformFeedback::CaptureSpecialInterleaved::draw()
   5215 {
   5216 	/* Functions handler */
   5217 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5218 
   5219 	gl.enable(GL_RASTERIZER_DISCARD);
   5220 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable call failed.");
   5221 
   5222 	gl.beginTransformFeedback(GL_POINTS);
   5223 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
   5224 
   5225 	gl.drawArrays(GL_POINTS, 0, 1);
   5226 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
   5227 
   5228 	gl.endTransformFeedback();
   5229 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
   5230 
   5231 	gl.disable(GL_RASTERIZER_DISCARD);
   5232 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable call failed.");
   5233 }
   5234 
   5235 bool gl3cts::TransformFeedback::CaptureSpecialInterleaved::check()
   5236 {
   5237 	/* Functions handler */
   5238 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5239 
   5240 	bool is_ok = true;
   5241 
   5242 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id[0]);
   5243 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   5244 
   5245 	glw::GLfloat* results =
   5246 		(glw::GLfloat*)gl.mapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, s_bo_size, GL_MAP_READ_BIT);
   5247 	GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange call failed.");
   5248 
   5249 	if ((results[0] != 1.0) || (results[1] != 2.0) || (results[2] != 3.0) || (results[3] != 4.0) ||
   5250 		/* gl_SkipComponents4 here */
   5251 		(results[8] != 5.0) || (results[9] != 6.0) || (results[10] != 7.0) || (results[11] != 8.0))
   5252 	{
   5253 		is_ok = false;
   5254 	}
   5255 
   5256 	gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   5257 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");
   5258 
   5259 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id[1]);
   5260 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   5261 
   5262 	results = (glw::GLfloat*)gl.mapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, s_bo_size, GL_MAP_READ_BIT);
   5263 	GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange call failed.");
   5264 
   5265 	if ((results[0] != 9.0) || (results[1] != 10.0) || (results[2] != 11.0) || (results[3] != 12.0) ||
   5266 		/* gl_SkipComponents4 here */
   5267 		(results[8] != 13.0) || (results[9] != 14.0) || (results[10] != 15.0) || (results[11] != 16.0))
   5268 	{
   5269 		is_ok = false;
   5270 	}
   5271 
   5272 	gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   5273 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");
   5274 
   5275 	return is_ok;
   5276 }
   5277 
   5278 void gl3cts::TransformFeedback::CaptureSpecialInterleaved::clean()
   5279 {
   5280 	/* Functions handler */
   5281 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5282 
   5283 	gl.useProgram(0);
   5284 
   5285 	if (m_program_id)
   5286 	{
   5287 		gl.deleteProgram(m_program_id);
   5288 
   5289 		m_program_id = 0;
   5290 	}
   5291 
   5292 	if (m_xfb_id)
   5293 	{
   5294 		gl.deleteTransformFeedbacks(1, &m_xfb_id);
   5295 
   5296 		m_xfb_id = 0;
   5297 	}
   5298 
   5299 	for (glw::GLuint i = 0; i < s_bo_ids_count; ++i)
   5300 	{
   5301 		if (m_bo_id[i])
   5302 		{
   5303 			gl.deleteBuffers(1, &m_bo_id[i]);
   5304 
   5305 			m_bo_id[i] = 0;
   5306 		}
   5307 	}
   5308 
   5309 	if (m_vao_id)
   5310 	{
   5311 		gl.deleteVertexArrays(1, &m_vao_id);
   5312 
   5313 		m_vao_id = 0;
   5314 	}
   5315 }
   5316 
   5317 const glw::GLchar* gl3cts::TransformFeedback::CaptureSpecialInterleaved::s_vertex_shader =
   5318 	"#version 130\n"
   5319 	"\n"
   5320 	"out vec4 variable_1;\n"
   5321 	"out vec4 variable_2;\n"
   5322 	"out vec4 variable_3;\n"
   5323 	"out vec4 variable_4;\n"
   5324 	"\n"
   5325 	"void main()\n"
   5326 	"{\n"
   5327 	"    variable_1 = vec4(1.0, 2.0, 3.0, 4.0);\n"
   5328 	"    variable_2 = vec4(5.0, 6.0, 7.0, 8.0);\n"
   5329 	"    variable_3 = vec4(9.0, 10.0, 11.0, 12.0);\n"
   5330 	"    variable_4 = vec4(13.0, 14.0, 15.0, 16.0);\n"
   5331 	"\n"
   5332 	"    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
   5333 	"}\n";
   5334 
   5335 const glw::GLchar* gl3cts::TransformFeedback::CaptureSpecialInterleaved::s_fragment_shader = "#version 130\n"
   5336 																							 "\n"
   5337 																							 "out vec4 pixel;\n"
   5338 																							 "\n"
   5339 																							 "void main()\n"
   5340 																							 "{\n"
   5341 																							 "    pixel = vec4(1.0);\n"
   5342 																							 "}\n";
   5343 
   5344 const glw::GLchar* gl3cts::TransformFeedback::CaptureSpecialInterleaved::s_xfb_varyings[] =
   5345 	{ "variable_1", "gl_SkipComponents4", "variable_2", "gl_NextBuffer",
   5346 	  "variable_3", "gl_SkipComponents4", "variable_4" };
   5347 
   5348 const glw::GLuint gl3cts::TransformFeedback::CaptureSpecialInterleaved::s_xfb_varyings_count =
   5349 	sizeof(s_xfb_varyings) / sizeof(s_xfb_varyings[0]);
   5350 
   5351 const glw::GLuint gl3cts::TransformFeedback::CaptureSpecialInterleaved::s_bo_size =
   5352 	3 /*number of variables / empty places */ * 4 /* vec4 */
   5353 	* sizeof(glw::GLfloat);
   5354 
   5355 /*-----------------------------------------------------------------------------------------------*/
   5356 
   5357 gl3cts::TransformFeedback::DrawXFBStream::DrawXFBStream(deqp::Context& context, const char* test_name,
   5358 														const char* test_description)
   5359 	: deqp::TestCase(context, test_name, test_description)
   5360 	, m_context(context)
   5361 	, m_program_id_generate(0)
   5362 	, m_program_id_draw(0)
   5363 	, m_vao_id(0)
   5364 	, m_xfb_id(0)
   5365 	, m_fbo_id(0)
   5366 	, m_rbo_id(0)
   5367 {
   5368 	memset(m_bo_id, 0, sizeof(m_bo_id));
   5369 	memset(m_qo_id, 0, sizeof(m_qo_id));
   5370 }
   5371 
   5372 gl3cts::TransformFeedback::DrawXFBStream::~DrawXFBStream(void)
   5373 {
   5374 }
   5375 
   5376 tcu::TestNode::IterateResult gl3cts::TransformFeedback::DrawXFBStream::iterate(void)
   5377 {
   5378 	/* Functions handler */
   5379 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5380 
   5381 	/* Initializations. */
   5382 	bool is_at_least_gl_40  = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 0)));
   5383 	bool is_arb_tf_3		= m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback3");
   5384 	bool is_arb_gpu_shader5 = m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader5");
   5385 
   5386 	glw::GLint max_vertex_streams = 0;
   5387 
   5388 	bool is_ok		= true;
   5389 	bool test_error = false;
   5390 
   5391 	/* Tests. */
   5392 	try
   5393 	{
   5394 		if (is_at_least_gl_40 || (is_arb_tf_3 && is_arb_gpu_shader5))
   5395 		{
   5396 			gl.getIntegerv(GL_MAX_VERTEX_STREAMS, &max_vertex_streams);
   5397 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   5398 
   5399 			if (max_vertex_streams >= 2)
   5400 			{
   5401 				prepareObjects();
   5402 
   5403 				useProgram(m_program_id_generate);
   5404 
   5405 				drawForXFB();
   5406 
   5407 				is_ok = is_ok && inspectQueries();
   5408 
   5409 				useProgram(m_program_id_draw);
   5410 
   5411 				setupVertexArray(m_bo_id[0]);
   5412 
   5413 				drawForFramebuffer(0);
   5414 
   5415 				setupVertexArray(m_bo_id[1]);
   5416 
   5417 				drawForFramebuffer(1);
   5418 
   5419 				is_ok = is_ok && check();
   5420 			}
   5421 		}
   5422 	}
   5423 	catch (...)
   5424 	{
   5425 		is_ok	  = false;
   5426 		test_error = true;
   5427 	}
   5428 
   5429 	/* Clean GL objects. */
   5430 	clean();
   5431 
   5432 	/* Result's setup. */
   5433 	if (is_ok)
   5434 	{
   5435 		/* Log success. */
   5436 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB Stream have passed."
   5437 											<< tcu::TestLog::EndMessage;
   5438 
   5439 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   5440 	}
   5441 	else
   5442 	{
   5443 		if (test_error)
   5444 		{
   5445 			/* Log error. */
   5446 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB Stream have approached error."
   5447 												<< tcu::TestLog::EndMessage;
   5448 
   5449 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   5450 		}
   5451 		else
   5452 		{
   5453 			/* Log fail. */
   5454 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB Stream have failed."
   5455 												<< tcu::TestLog::EndMessage;
   5456 
   5457 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   5458 		}
   5459 	}
   5460 
   5461 	return STOP;
   5462 }
   5463 
   5464 void gl3cts::TransformFeedback::DrawXFBStream::prepareObjects()
   5465 {
   5466 	/* Functions handler */
   5467 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5468 
   5469 	/* Prepare programs. */
   5470 	m_program_id_generate = gl3cts::TransformFeedback::Utilities::buildProgram(
   5471 		gl, m_context.getTestContext().getLog(), s_geometry_shader, NULL, NULL, s_vertex_shader_blank,
   5472 		s_fragment_shader, s_xfb_varyings, s_xfb_varyings_count, GL_INTERLEAVED_ATTRIBS);
   5473 
   5474 	if (0 == m_program_id_generate)
   5475 	{
   5476 		throw 0;
   5477 	}
   5478 
   5479 	m_program_id_draw = gl3cts::TransformFeedback::Utilities::buildProgram(
   5480 		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, s_vertex_shader_pass, s_fragment_shader, NULL, 0,
   5481 		GL_INTERLEAVED_ATTRIBS);
   5482 
   5483 	if (0 == m_program_id_draw)
   5484 	{
   5485 		throw 0;
   5486 	}
   5487 
   5488 	/* Prepare transform feedbacks. */
   5489 	gl.genTransformFeedbacks(1, &m_xfb_id);
   5490 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTransformFeedbacks call failed.");
   5491 
   5492 	gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_xfb_id);
   5493 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedbacks call failed.");
   5494 
   5495 	/* Create empty Vertex Array Object */
   5496 	gl.genVertexArrays(1, &m_vao_id);
   5497 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
   5498 
   5499 	gl.bindVertexArray(m_vao_id);
   5500 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   5501 
   5502 	/* Prepare buffer objects. */
   5503 	gl.genBuffers(s_bo_ids_count, m_bo_id);
   5504 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   5505 
   5506 	for (glw::GLuint i = 0; i < s_bo_ids_count; ++i)
   5507 	{
   5508 		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id[i]);
   5509 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   5510 
   5511 		gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, s_bo_size, NULL, GL_DYNAMIC_COPY); /* allocation */
   5512 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
   5513 
   5514 		gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, i, m_bo_id[i]);
   5515 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferRange call failed.");
   5516 	}
   5517 
   5518 	/* Generate queries */
   5519 	gl.genQueries(s_qo_ids_count, m_qo_id);
   5520 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenQueries call failed.");
   5521 
   5522 	/* Prepare framebuffer. */
   5523 	gl.clearColor(0.f, 0.f, 0.f, 1.f);
   5524 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");
   5525 
   5526 	gl.genFramebuffers(1, &m_fbo_id);
   5527 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
   5528 
   5529 	gl.genRenderbuffers(1, &m_rbo_id);
   5530 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
   5531 
   5532 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id);
   5533 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
   5534 
   5535 	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_id);
   5536 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
   5537 
   5538 	gl.renderbufferStorage(GL_RENDERBUFFER, GL_R8, s_view_size, s_view_size);
   5539 	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed.");
   5540 
   5541 	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo_id);
   5542 	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed.");
   5543 
   5544 	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
   5545 	{
   5546 		throw 0;
   5547 	}
   5548 
   5549 	gl.viewport(0, 0, s_view_size, s_view_size);
   5550 	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
   5551 }
   5552 
   5553 void gl3cts::TransformFeedback::DrawXFBStream::setupVertexArray(glw::GLuint bo_id)
   5554 {
   5555 	/* Functions handler */
   5556 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5557 
   5558 	gl.bindBuffer(GL_ARRAY_BUFFER, bo_id);
   5559 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   5560 
   5561 	glw::GLuint position_location = gl.getAttribLocation(m_program_id_draw, "position");
   5562 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation call failed.");
   5563 
   5564 	gl.vertexAttribPointer(position_location, 4, GL_FLOAT, GL_FALSE, 0, NULL);
   5565 	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed.");
   5566 
   5567 	gl.enableVertexAttribArray(position_location);
   5568 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
   5569 }
   5570 
   5571 void gl3cts::TransformFeedback::DrawXFBStream::useProgram(glw::GLuint program_id)
   5572 {
   5573 	/* Functions handler */
   5574 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5575 
   5576 	gl.useProgram(program_id);
   5577 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
   5578 }
   5579 
   5580 void gl3cts::TransformFeedback::DrawXFBStream::drawForXFB()
   5581 {
   5582 	/* Functions handler */
   5583 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5584 
   5585 	gl.enable(GL_RASTERIZER_DISCARD);
   5586 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable call failed.");
   5587 
   5588 	gl.beginTransformFeedback(GL_POINTS);
   5589 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
   5590 
   5591 	gl.beginQueryIndexed(GL_PRIMITIVES_GENERATED, 0, m_qo_id[0]);
   5592 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginQueryIndexed call failed.");
   5593 
   5594 	gl.beginQueryIndexed(GL_PRIMITIVES_GENERATED, 1, m_qo_id[1]);
   5595 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginQueryIndexed call failed.");
   5596 
   5597 	gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, 0, m_qo_id[2]);
   5598 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginQueryIndexed call failed.");
   5599 
   5600 	gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, 1, m_qo_id[3]);
   5601 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginQueryIndexed call failed.");
   5602 
   5603 	gl.drawArrays(GL_POINTS, 0, 1);
   5604 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
   5605 
   5606 	gl.endQueryIndexed(GL_PRIMITIVES_GENERATED, 0);
   5607 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndQueryIndexed call failed.");
   5608 
   5609 	gl.endQueryIndexed(GL_PRIMITIVES_GENERATED, 1);
   5610 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndQueryIndexed call failed.");
   5611 
   5612 	gl.endQueryIndexed(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, 0);
   5613 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndQueryIndexed call failed.");
   5614 
   5615 	gl.endQueryIndexed(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, 1);
   5616 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndQueryIndexed call failed.");
   5617 
   5618 	gl.endTransformFeedback();
   5619 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
   5620 
   5621 	gl.disable(GL_RASTERIZER_DISCARD);
   5622 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable call failed.");
   5623 }
   5624 
   5625 void gl3cts::TransformFeedback::DrawXFBStream::drawForFramebuffer(glw::GLuint stream)
   5626 {
   5627 	/* Functions handler */
   5628 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5629 
   5630 	gl.drawTransformFeedbackStream(GL_TRIANGLES, m_xfb_id, stream);
   5631 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawTransformFeedbackStream call failed.");
   5632 }
   5633 
   5634 bool gl3cts::TransformFeedback::DrawXFBStream::inspectQueries()
   5635 {
   5636 	/* Functions handler */
   5637 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5638 
   5639 	glw::GLint generated_primitives_to_stream_0 = 0;
   5640 	glw::GLint generated_primitives_to_stream_1 = 0;
   5641 
   5642 	gl.getQueryObjectiv(m_qo_id[0], GL_QUERY_RESULT, &generated_primitives_to_stream_0);
   5643 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryIndexediv call failed.");
   5644 
   5645 	gl.getQueryObjectiv(m_qo_id[1], GL_QUERY_RESULT, &generated_primitives_to_stream_1);
   5646 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryIndexediv call failed.");
   5647 
   5648 	glw::GLint primitives_written_to_xfb_to_stream_0 = 0;
   5649 	glw::GLint primitives_written_to_xfb_to_stream_1 = 0;
   5650 
   5651 	gl.getQueryObjectiv(m_qo_id[2], GL_QUERY_RESULT, &primitives_written_to_xfb_to_stream_0);
   5652 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryIndexediv call failed.");
   5653 
   5654 	gl.getQueryObjectiv(m_qo_id[3], GL_QUERY_RESULT, &primitives_written_to_xfb_to_stream_1);
   5655 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryIndexediv call failed.");
   5656 
   5657 	if ((generated_primitives_to_stream_0 == 3) && (generated_primitives_to_stream_1 == 3) &&
   5658 		(primitives_written_to_xfb_to_stream_0 == 3) && (primitives_written_to_xfb_to_stream_1 == 3))
   5659 	{
   5660 		return true;
   5661 	}
   5662 
   5663 	return false;
   5664 }
   5665 
   5666 bool gl3cts::TransformFeedback::DrawXFBStream::check()
   5667 {
   5668 	/* Functions handler */
   5669 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5670 
   5671 	/* Number of pixels. */
   5672 	const glw::GLuint number_of_pixels = s_view_size * s_view_size;
   5673 
   5674 	/* Fetch framebuffer. */
   5675 	std::vector<glw::GLfloat> pixels(number_of_pixels);
   5676 
   5677 	gl.readPixels(0, 0, s_view_size, s_view_size, GL_RED, GL_FLOAT, &pixels[0]);
   5678 	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");
   5679 
   5680 	/* Check results. */
   5681 	for (glw::GLuint i = 0; i < number_of_pixels; ++i)
   5682 	{
   5683 		if (fabs(pixels[i] - 1.f) > 0.0625 /* precision, expected result == 1.0 */)
   5684 		{
   5685 			return false;
   5686 		}
   5687 	}
   5688 
   5689 	return true;
   5690 }
   5691 
   5692 void gl3cts::TransformFeedback::DrawXFBStream::clean()
   5693 {
   5694 	/* Functions handler */
   5695 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5696 
   5697 	gl.useProgram(0);
   5698 
   5699 	if (m_program_id_generate)
   5700 	{
   5701 		gl.deleteProgram(m_program_id_generate);
   5702 
   5703 		m_program_id_generate = 0;
   5704 	}
   5705 
   5706 	if (m_program_id_draw)
   5707 	{
   5708 		glw::GLuint position_location = gl.getAttribLocation(m_program_id_draw, "position");
   5709 
   5710 		gl.disableVertexAttribArray(position_location);
   5711 
   5712 		gl.deleteProgram(m_program_id_draw);
   5713 
   5714 		m_program_id_draw = 0;
   5715 	}
   5716 
   5717 	if (m_xfb_id)
   5718 	{
   5719 		gl.deleteTransformFeedbacks(1, &m_xfb_id);
   5720 
   5721 		m_xfb_id = 0;
   5722 	}
   5723 
   5724 	for (glw::GLuint i = 0; i < s_bo_ids_count; ++i)
   5725 	{
   5726 		if (m_bo_id[i])
   5727 		{
   5728 			gl.deleteBuffers(1, &m_bo_id[i]);
   5729 
   5730 			m_bo_id[i] = 0;
   5731 		}
   5732 	}
   5733 
   5734 	if (m_vao_id)
   5735 	{
   5736 		gl.deleteVertexArrays(1, &m_vao_id);
   5737 
   5738 		m_vao_id = 0;
   5739 	}
   5740 
   5741 	if (m_fbo_id)
   5742 	{
   5743 		gl.deleteFramebuffers(1, &m_fbo_id);
   5744 
   5745 		m_fbo_id = 0;
   5746 	}
   5747 
   5748 	if (m_rbo_id)
   5749 	{
   5750 		gl.deleteRenderbuffers(1, &m_rbo_id);
   5751 
   5752 		m_rbo_id = 0;
   5753 	}
   5754 }
   5755 
   5756 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStream::s_vertex_shader_blank = "#version 130\n"
   5757 																					 "\n"
   5758 																					 "void main()\n"
   5759 																					 "{\n"
   5760 																					 "}\n";
   5761 
   5762 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStream::s_vertex_shader_pass = "#version 130\n"
   5763 																					"\n"
   5764 																					"in vec4 position;\n"
   5765 																					"\n"
   5766 																					"void main()\n"
   5767 																					"{\n"
   5768 																					"    gl_Position = position;\n"
   5769 																					"}\n";
   5770 
   5771 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStream::s_geometry_shader =
   5772 	"#version 400\n"
   5773 	"\n"
   5774 	"layout(points) in;\n"
   5775 	"layout(points, max_vertices = 6) out;\n"
   5776 	"\n"
   5777 	"layout(stream = 1) out vec4 position;\n"
   5778 	"\n"
   5779 	"void main()\n"
   5780 	"{\n"
   5781 	"    gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
   5782 	"    EmitStreamVertex(0);\n"
   5783 	"    gl_Position = vec4( 1.0, -1.0, 0.0, 1.0);\n"
   5784 	"    EmitStreamVertex(0);\n"
   5785 	"    gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
   5786 	"    EmitStreamVertex(0);\n"
   5787 	"\n"
   5788 	"    position = vec4( 1.0, -1.0, 0.0, 1.0);\n"
   5789 	"    EmitStreamVertex(1);\n"
   5790 	"    position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
   5791 	"    EmitStreamVertex(1);\n"
   5792 	"    position = vec4( 1.0,  1.0, 0.0, 1.0);\n"
   5793 	"    EmitStreamVertex(1);\n"
   5794 	"}\n";
   5795 
   5796 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStream::s_fragment_shader = "#version 130\n"
   5797 																				 "\n"
   5798 																				 "out vec4 pixel;\n"
   5799 																				 "\n"
   5800 																				 "void main()\n"
   5801 																				 "{\n"
   5802 																				 "    pixel = vec4(1.0);\n"
   5803 																				 "}\n";
   5804 
   5805 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStream::s_xfb_varyings[] = { "gl_Position", "gl_NextBuffer",
   5806 																				  "position" };
   5807 
   5808 const glw::GLuint gl3cts::TransformFeedback::DrawXFBStream::s_xfb_varyings_count =
   5809 	sizeof(s_xfb_varyings) / sizeof(s_xfb_varyings[0]);
   5810 
   5811 const glw::GLuint gl3cts::TransformFeedback::DrawXFBStream::s_bo_size =
   5812 	3 /* triangles */ * 4 /* vec4 */ * sizeof(glw::GLfloat);
   5813 
   5814 const glw::GLuint gl3cts::TransformFeedback::DrawXFBStream::s_view_size = 2;
   5815 
   5816 /*-----------------------------------------------------------------------------------------------*/
   5817 
   5818 gl3cts::TransformFeedback::DrawXFBInstanced::DrawXFBInstanced(deqp::Context& context, const char* test_name,
   5819 															  const char* test_description)
   5820 	: deqp::TestCase(context, test_name, test_description)
   5821 	, m_context(context)
   5822 	, m_program_id_generate(0)
   5823 	, m_program_id_draw(0)
   5824 	, m_vao_id(0)
   5825 	, m_xfb_id(0)
   5826 	, m_bo_id_xfb(0)
   5827 	, m_bo_id_uniform(0)
   5828 	, m_fbo_id(0)
   5829 	, m_rbo_id(0)
   5830 {
   5831 }
   5832 
   5833 gl3cts::TransformFeedback::DrawXFBInstanced::~DrawXFBInstanced(void)
   5834 {
   5835 }
   5836 
   5837 tcu::TestNode::IterateResult gl3cts::TransformFeedback::DrawXFBInstanced::iterate(void)
   5838 {
   5839 	/* Initializations. */
   5840 	bool is_at_least_gl_42   = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 2)));
   5841 	bool is_at_least_gl_31   = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(3, 1)));
   5842 	bool is_arb_tf_instanced = m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback_instanced");
   5843 	bool is_arb_ubo			 = m_context.getContextInfo().isExtensionSupported("GL_ARB_uniform_buffer_object");
   5844 
   5845 	bool is_ok		= true;
   5846 	bool test_error = false;
   5847 
   5848 	try
   5849 	{
   5850 		if (is_at_least_gl_42 || ((is_at_least_gl_31 || is_arb_ubo) && is_arb_tf_instanced))
   5851 		{
   5852 			prepareObjects();
   5853 			drawForXFB();
   5854 			drawInstanced();
   5855 
   5856 			is_ok = is_ok && check();
   5857 		}
   5858 	}
   5859 	catch (...)
   5860 	{
   5861 		is_ok	  = false;
   5862 		test_error = true;
   5863 	}
   5864 
   5865 	/* Clean GL objects */
   5866 	clean();
   5867 
   5868 	/* Result's setup. */
   5869 	if (is_ok)
   5870 	{
   5871 		/* Log success. */
   5872 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB Instanced have passed."
   5873 											<< tcu::TestLog::EndMessage;
   5874 
   5875 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   5876 	}
   5877 	else
   5878 	{
   5879 		if (test_error)
   5880 		{
   5881 			/* Log error. */
   5882 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB Instanced have approached error."
   5883 												<< tcu::TestLog::EndMessage;
   5884 
   5885 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   5886 		}
   5887 		else
   5888 		{
   5889 			/* Log fail. */
   5890 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB Instanced have failed."
   5891 												<< tcu::TestLog::EndMessage;
   5892 
   5893 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   5894 		}
   5895 	}
   5896 
   5897 	return STOP;
   5898 }
   5899 
   5900 void gl3cts::TransformFeedback::DrawXFBInstanced::prepareObjects()
   5901 {
   5902 	/* Functions handler */
   5903 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5904 
   5905 	/* Prepare programs. */
   5906 	m_program_id_generate = gl3cts::TransformFeedback::Utilities::buildProgram(
   5907 		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, s_vertex_shader_generate, s_fragment_shader,
   5908 		&s_xfb_varying, 1, GL_INTERLEAVED_ATTRIBS);
   5909 
   5910 	if (0 == m_program_id_generate)
   5911 	{
   5912 		throw 0;
   5913 	}
   5914 
   5915 	m_program_id_draw = gl3cts::TransformFeedback::Utilities::buildProgram(
   5916 		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, s_vertex_shader_draw, s_fragment_shader, NULL, 0,
   5917 		GL_INTERLEAVED_ATTRIBS);
   5918 
   5919 	if (0 == m_program_id_draw)
   5920 	{
   5921 		throw 0;
   5922 	}
   5923 
   5924 	/* Prepare transform feedbacks. */
   5925 	gl.genTransformFeedbacks(1, &m_xfb_id);
   5926 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTransformFeedbacks call failed.");
   5927 
   5928 	gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_xfb_id);
   5929 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedbacks call failed.");
   5930 
   5931 	/* Create empty Vertex Array Object */
   5932 	gl.genVertexArrays(1, &m_vao_id);
   5933 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
   5934 
   5935 	gl.bindVertexArray(m_vao_id);
   5936 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   5937 
   5938 	/* Prepare xfb buffer object. */
   5939 	gl.genBuffers(1, &m_bo_id_xfb);
   5940 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   5941 
   5942 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id_xfb);
   5943 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   5944 
   5945 	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, s_bo_xfb_size, NULL, GL_DYNAMIC_COPY); /* allocation */
   5946 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
   5947 
   5948 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_id_xfb);
   5949 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferRange call failed.");
   5950 
   5951 	/* Prepare uniform buffer object. */
   5952 	gl.genBuffers(1, &m_bo_id_uniform);
   5953 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   5954 
   5955 	gl.bindBuffer(GL_UNIFORM_BUFFER, m_bo_id_uniform);
   5956 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   5957 
   5958 	gl.bufferData(GL_UNIFORM_BUFFER, s_bo_uniform_size, s_bo_uniform_data, GL_DYNAMIC_COPY); /* allocation */
   5959 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
   5960 
   5961 	gl.bindBufferBase(GL_UNIFORM_BUFFER, 0, m_bo_id_uniform);
   5962 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferRange call failed.");
   5963 
   5964 	glw::GLuint uniform_index = gl.getUniformBlockIndex(m_program_id_draw, s_uniform);
   5965 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformBlockIndex call failed.");
   5966 
   5967 	if (GL_INVALID_INDEX == uniform_index)
   5968 	{
   5969 		throw 0;
   5970 	}
   5971 
   5972 	gl.uniformBlockBinding(m_program_id_draw, uniform_index, 0);
   5973 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniformBlockBinding call failed.");
   5974 
   5975 	/* Prepare framebuffer. */
   5976 	gl.clearColor(0.f, 0.f, 0.f, 1.f);
   5977 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");
   5978 
   5979 	gl.genFramebuffers(1, &m_fbo_id);
   5980 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
   5981 
   5982 	gl.genRenderbuffers(1, &m_rbo_id);
   5983 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
   5984 
   5985 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id);
   5986 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
   5987 
   5988 	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_id);
   5989 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
   5990 
   5991 	gl.renderbufferStorage(GL_RENDERBUFFER, GL_R8, s_view_size, s_view_size);
   5992 	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed.");
   5993 
   5994 	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo_id);
   5995 	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed.");
   5996 
   5997 	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
   5998 	{
   5999 		throw 0;
   6000 	}
   6001 
   6002 	gl.viewport(0, 0, s_view_size, s_view_size);
   6003 	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
   6004 }
   6005 
   6006 void gl3cts::TransformFeedback::DrawXFBInstanced::drawForXFB()
   6007 {
   6008 	/* Functions handler */
   6009 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   6010 
   6011 	gl.useProgram(m_program_id_generate);
   6012 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
   6013 
   6014 	gl.enable(GL_RASTERIZER_DISCARD);
   6015 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable call failed.");
   6016 
   6017 	gl.beginTransformFeedback(GL_POINTS);
   6018 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
   6019 
   6020 	gl.drawArrays(GL_POINTS, 0, 4 /* quad vertex count */);
   6021 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
   6022 
   6023 	gl.endTransformFeedback();
   6024 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
   6025 
   6026 	gl.disable(GL_RASTERIZER_DISCARD);
   6027 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable call failed.");
   6028 }
   6029 
   6030 void gl3cts::TransformFeedback::DrawXFBInstanced::drawInstanced()
   6031 {
   6032 	/* Functions handler */
   6033 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   6034 
   6035 	gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id_xfb);
   6036 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   6037 
   6038 	glw::GLuint position_location = gl.getAttribLocation(m_program_id_draw, "position");
   6039 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation call failed.");
   6040 
   6041 	gl.vertexAttribPointer(position_location, 4, GL_FLOAT, GL_FALSE, 0, NULL);
   6042 	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed.");
   6043 
   6044 	gl.enableVertexAttribArray(position_location);
   6045 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
   6046 
   6047 	gl.clear(GL_COLOR_BUFFER_BIT);
   6048 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed.");
   6049 
   6050 	gl.useProgram(m_program_id_draw);
   6051 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
   6052 
   6053 	gl.drawTransformFeedbackInstanced(GL_TRIANGLE_STRIP, m_xfb_id, 4);
   6054 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
   6055 }
   6056 
   6057 bool gl3cts::TransformFeedback::DrawXFBInstanced::check()
   6058 {
   6059 	/* Functions handler */
   6060 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   6061 
   6062 	/* Number of pixels. */
   6063 	const glw::GLuint number_of_pixels = s_view_size * s_view_size;
   6064 
   6065 	/* Fetch framebuffer. */
   6066 	std::vector<glw::GLfloat> pixels(number_of_pixels);
   6067 
   6068 	gl.readPixels(0, 0, s_view_size, s_view_size, GL_RED, GL_FLOAT, &pixels[0]);
   6069 	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");
   6070 
   6071 	/* Check results. */
   6072 	for (glw::GLuint i = 0; i < number_of_pixels; ++i)
   6073 	{
   6074 		if (fabs(pixels[i] - 1.f) > 0.0625 /* precision, expected result == 1.0 */)
   6075 		{
   6076 			return false;
   6077 		}
   6078 	}
   6079 
   6080 	return true;
   6081 }
   6082 
   6083 void gl3cts::TransformFeedback::DrawXFBInstanced::clean()
   6084 {
   6085 	/* Functions handler */
   6086 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   6087 
   6088 	gl.useProgram(0);
   6089 
   6090 	if (m_program_id_generate)
   6091 	{
   6092 		gl.deleteProgram(m_program_id_generate);
   6093 
   6094 		m_program_id_generate = 0;
   6095 	}
   6096 
   6097 	if (m_program_id_draw)
   6098 	{
   6099 		glw::GLuint position_location = gl.getAttribLocation(m_program_id_draw, "position");
   6100 
   6101 		gl.disableVertexAttribArray(position_location);
   6102 
   6103 		gl.deleteProgram(m_program_id_draw);
   6104 
   6105 		m_program_id_draw = 0;
   6106 	}
   6107 
   6108 	if (m_xfb_id)
   6109 	{
   6110 		gl.deleteTransformFeedbacks(1, &m_xfb_id);
   6111 
   6112 		m_xfb_id = 0;
   6113 	}
   6114 
   6115 	if (m_bo_id_xfb)
   6116 	{
   6117 		gl.deleteBuffers(1, &m_bo_id_xfb);
   6118 
   6119 		m_bo_id_xfb = 0;
   6120 	}
   6121 
   6122 	if (m_bo_id_uniform)
   6123 	{
   6124 		gl.deleteBuffers(1, &m_bo_id_uniform);
   6125 
   6126 		m_bo_id_uniform = 0;
   6127 	}
   6128 
   6129 	if (m_vao_id)
   6130 	{
   6131 		gl.deleteVertexArrays(1, &m_vao_id);
   6132 
   6133 		m_vao_id = 0;
   6134 	}
   6135 
   6136 	if (m_fbo_id)
   6137 	{
   6138 		gl.deleteFramebuffers(1, &m_fbo_id);
   6139 
   6140 		m_fbo_id = 0;
   6141 	}
   6142 
   6143 	if (m_rbo_id)
   6144 	{
   6145 		gl.deleteRenderbuffers(1, &m_rbo_id);
   6146 
   6147 		m_rbo_id = 0;
   6148 	}
   6149 }
   6150 
   6151 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBInstanced::s_vertex_shader_generate =
   6152 	"#version 140\n"
   6153 	"\n"
   6154 	"void main()\n"
   6155 	"{\n"
   6156 	"    switch(gl_VertexID % 4)\n"
   6157 	"    {\n"
   6158 	"    case 0:\n"
   6159 	"       gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
   6160 	"       break;\n"
   6161 	"    case 1:\n"
   6162 	"       gl_Position = vec4( 1.0, -1.0, 0.0, 1.0);\n"
   6163 	"       break;\n"
   6164 	"    case 2:\n"
   6165 	"       gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
   6166 	"       break;\n"
   6167 	"    case 3:\n"
   6168 	"       gl_Position = vec4( 1.0,  1.0, 0.0, 1.0);\n"
   6169 	"       break;\n"
   6170 	"    }\n"
   6171 	"}\n";
   6172 
   6173 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBInstanced::s_vertex_shader_draw =
   6174 	"#version 140\n"
   6175 	"\n"
   6176 	"uniform MatrixBlock\n"
   6177 	"{\n"
   6178 	"    mat4 transformation_0;\n"
   6179 	"    mat4 transformation_1;\n"
   6180 	"    mat4 transformation_2;\n"
   6181 	"    mat4 transformation_3;\n"
   6182 	"};\n"
   6183 	"\n"
   6184 	"in vec4 position;\n"
   6185 	"\n"
   6186 	"void main()\n"
   6187 	"{\n"
   6188 	"    switch(gl_InstanceID % 4)\n"
   6189 	"    {\n"
   6190 	"    case 0:\n"
   6191 	"       gl_Position = position * transformation_0;\n"
   6192 	"       break;\n"
   6193 	"    case 1:\n"
   6194 	"       gl_Position = position * transformation_1;\n"
   6195 	"       break;\n"
   6196 	"    case 2:\n"
   6197 	"       gl_Position = position * transformation_2;\n"
   6198 	"       break;\n"
   6199 	"    case 3:\n"
   6200 	"       gl_Position = position * transformation_3;\n"
   6201 	"       break;\n"
   6202 	"    }\n"
   6203 	"}\n";
   6204 
   6205 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBInstanced::s_fragment_shader = "#version 130\n"
   6206 																					"\n"
   6207 																					"out vec4 pixel;\n"
   6208 																					"\n"
   6209 																					"void main()\n"
   6210 																					"{\n"
   6211 																					"    pixel = vec4(1.0);\n"
   6212 																					"}\n";
   6213 
   6214 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBInstanced::s_xfb_varying = "gl_Position";
   6215 
   6216 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBInstanced::s_uniform = "MatrixBlock";
   6217 
   6218 const glw::GLuint gl3cts::TransformFeedback::DrawXFBInstanced::s_bo_xfb_size =
   6219 	4 /* vertex count */ * 4 /* vec4 components */
   6220 	* sizeof(glw::GLfloat) /* data type size */;
   6221 
   6222 const glw::GLfloat gl3cts::TransformFeedback::DrawXFBInstanced::s_bo_uniform_data[] = {
   6223 	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,
   6224 
   6225 	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,
   6226 
   6227 	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,
   6228 
   6229 	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
   6230 };
   6231 
   6232 const glw::GLuint gl3cts::TransformFeedback::DrawXFBInstanced::s_bo_uniform_size = sizeof(s_bo_uniform_data);
   6233 
   6234 const glw::GLuint gl3cts::TransformFeedback::DrawXFBInstanced::s_view_size = 4;
   6235 
   6236 /*-----------------------------------------------------------------------------------------------*/
   6237 
   6238 gl3cts::TransformFeedback::DrawXFBStreamInstanced::DrawXFBStreamInstanced(deqp::Context& context, const char* test_name,
   6239 																		  const char* test_description)
   6240 	: deqp::TestCase(context, test_name, test_description)
   6241 	, m_context(context)
   6242 	, m_program_id_generate(0)
   6243 	, m_program_id_draw(0)
   6244 	, m_vao_id(0)
   6245 	, m_xfb_id(0)
   6246 	, m_bo_id_xfb_position(0)
   6247 	, m_bo_id_xfb_color(0)
   6248 	, m_bo_id_uniform(0)
   6249 	, m_fbo_id(0)
   6250 	, m_rbo_id(0)
   6251 {
   6252 }
   6253 
   6254 gl3cts::TransformFeedback::DrawXFBStreamInstanced::~DrawXFBStreamInstanced(void)
   6255 {
   6256 }
   6257 
   6258 tcu::TestNode::IterateResult gl3cts::TransformFeedback::DrawXFBStreamInstanced::iterate(void)
   6259 {
   6260 	/* Initializations. */
   6261 	bool is_at_least_gl_31   = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(3, 1)));
   6262 	bool is_at_least_gl_40   = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 0)));
   6263 	bool is_at_least_gl_42   = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 2)));
   6264 	bool is_arb_tf_instanced = m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback_instanced");
   6265 	bool is_arb_ubo			 = m_context.getContextInfo().isExtensionSupported("GL_ARB_uniform_buffer_object");
   6266 	bool is_arb_gpu_shader5  = m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader5");
   6267 
   6268 	bool is_ok		= true;
   6269 	bool test_error = false;
   6270 
   6271 	/* Test. */
   6272 	try
   6273 	{
   6274 		if (is_at_least_gl_42 || ((is_at_least_gl_31 || is_arb_ubo) && is_arb_gpu_shader5 && is_arb_tf_instanced) ||
   6275 			(is_at_least_gl_40 && is_arb_tf_instanced))
   6276 		{
   6277 			prepareObjects();
   6278 			drawForXFB();
   6279 			drawStreamInstanced();
   6280 
   6281 			is_ok = is_ok && check();
   6282 		}
   6283 	}
   6284 	catch (...)
   6285 	{
   6286 		is_ok	  = false;
   6287 		test_error = true;
   6288 	}
   6289 
   6290 	/* Clean GL objects */
   6291 	clean();
   6292 
   6293 	/* Result's setup. */
   6294 	if (is_ok)
   6295 	{
   6296 		/* Log success. */
   6297 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB Stream Instanced have passed."
   6298 											<< tcu::TestLog::EndMessage;
   6299 
   6300 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   6301 	}
   6302 	else
   6303 	{
   6304 		if (test_error)
   6305 		{
   6306 			/* Log error. */
   6307 			m_context.getTestContext().getLog() << tcu::TestLog::Message
   6308 												<< "Draw XFB Stream Instanced have approached error."
   6309 												<< tcu::TestLog::EndMessage;
   6310 
   6311 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   6312 		}
   6313 		else
   6314 		{
   6315 			/* Log fail. */
   6316 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Draw XFB Stream Instanced have failed."
   6317 												<< tcu::TestLog::EndMessage;
   6318 
   6319 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   6320 		}
   6321 	}
   6322 
   6323 	return STOP;
   6324 }
   6325 
   6326 void gl3cts::TransformFeedback::DrawXFBStreamInstanced::prepareObjects()
   6327 {
   6328 	/* Functions handler */
   6329 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   6330 
   6331 	/* Prepare programs. */
   6332 	m_program_id_generate = gl3cts::TransformFeedback::Utilities::buildProgram(
   6333 		gl, m_context.getTestContext().getLog(), s_geometry_shader_generate, NULL, NULL, s_vertex_shader_blank,
   6334 		s_fragment_shader_blank, s_xfb_varyings, s_xfb_varyings_count, GL_INTERLEAVED_ATTRIBS);
   6335 
   6336 	if (0 == m_program_id_generate)
   6337 	{
   6338 		throw 0;
   6339 	}
   6340 
   6341 	m_program_id_draw = gl3cts::TransformFeedback::Utilities::buildProgram(
   6342 		gl, m_context.getTestContext().getLog(), NULL, NULL, NULL, s_vertex_shader_draw, s_fragment_shader_draw, NULL,
   6343 		0, GL_INTERLEAVED_ATTRIBS);
   6344 
   6345 	if (0 == m_program_id_draw)
   6346 	{
   6347 		throw 0;
   6348 	}
   6349 
   6350 	/* Prepare transform feedbacks. */
   6351 	gl.genTransformFeedbacks(1, &m_xfb_id);
   6352 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTransformFeedbacks call failed.");
   6353 
   6354 	gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_xfb_id);
   6355 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedbacks call failed.");
   6356 
   6357 	/* Create empty Vertex Array Object */
   6358 	gl.genVertexArrays(1, &m_vao_id);
   6359 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
   6360 
   6361 	gl.bindVertexArray(m_vao_id);
   6362 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   6363 
   6364 	/* Prepare xfb buffer objects. */
   6365 	gl.genBuffers(1, &m_bo_id_xfb_position);
   6366 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   6367 
   6368 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id_xfb_position);
   6369 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   6370 
   6371 	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, s_bo_xfb_size, NULL, GL_DYNAMIC_COPY); /* allocation */
   6372 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
   6373 
   6374 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_id_xfb_position);
   6375 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferRange call failed.");
   6376 
   6377 	gl.genBuffers(1, &m_bo_id_xfb_color);
   6378 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   6379 
   6380 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id_xfb_color);
   6381 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   6382 
   6383 	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, s_bo_xfb_size, NULL, GL_DYNAMIC_COPY); /* allocation */
   6384 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
   6385 
   6386 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 1, m_bo_id_xfb_color);
   6387 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferRange call failed.");
   6388 
   6389 	/* Prepare uniform buffer object. */
   6390 	gl.genBuffers(1, &m_bo_id_uniform);
   6391 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   6392 
   6393 	gl.bindBuffer(GL_UNIFORM_BUFFER, m_bo_id_uniform);
   6394 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   6395 
   6396 	gl.bufferData(GL_UNIFORM_BUFFER, s_bo_uniform_size, s_bo_uniform_data, GL_DYNAMIC_COPY); /* allocation */
   6397 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
   6398 
   6399 	gl.bindBufferBase(GL_UNIFORM_BUFFER, 0, m_bo_id_uniform);
   6400 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferRange call failed.");
   6401 
   6402 	glw::GLuint uniform_index = gl.getUniformBlockIndex(m_program_id_draw, s_uniform);
   6403 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformBlockIndex call failed.");
   6404 
   6405 	if (GL_INVALID_INDEX == uniform_index)
   6406 	{
   6407 		throw 0;
   6408 	}
   6409 
   6410 	gl.uniformBlockBinding(m_program_id_draw, uniform_index, 0);
   6411 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniformBlockBinding call failed.");
   6412 
   6413 	/* Prepare framebuffer. */
   6414 	gl.clearColor(0.f, 0.f, 0.f, 1.f);
   6415 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");
   6416 
   6417 	gl.genFramebuffers(1, &m_fbo_id);
   6418 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
   6419 
   6420 	gl.genRenderbuffers(1, &m_rbo_id);
   6421 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
   6422 
   6423 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id);
   6424 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
   6425 
   6426 	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_id);
   6427 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
   6428 
   6429 	gl.renderbufferStorage(GL_RENDERBUFFER, GL_R8, s_view_size, s_view_size);
   6430 	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed.");
   6431 
   6432 	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo_id);
   6433 	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed.");
   6434 
   6435 	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
   6436 	{
   6437 		throw 0;
   6438 	}
   6439 
   6440 	gl.viewport(0, 0, s_view_size, s_view_size);
   6441 	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
   6442 }
   6443 
   6444 void gl3cts::TransformFeedback::DrawXFBStreamInstanced::drawForXFB()
   6445 {
   6446 	/* Functions handler */
   6447 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   6448 
   6449 	gl.useProgram(m_program_id_generate);
   6450 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
   6451 
   6452 	gl.enable(GL_RASTERIZER_DISCARD);
   6453 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable call failed.");
   6454 
   6455 	gl.beginTransformFeedback(GL_POINTS);
   6456 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
   6457 
   6458 	gl.drawArrays(GL_POINTS, 0, 4 /* quad vertex count */);
   6459 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
   6460 
   6461 	gl.endTransformFeedback();
   6462 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
   6463 
   6464 	gl.disable(GL_RASTERIZER_DISCARD);
   6465 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable call failed.");
   6466 }
   6467 
   6468 void gl3cts::TransformFeedback::DrawXFBStreamInstanced::drawStreamInstanced()
   6469 {
   6470 	/* Functions handler */
   6471 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   6472 
   6473 	gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id_xfb_position);
   6474 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   6475 
   6476 	glw::GLuint position_location = gl.getAttribLocation(m_program_id_draw, "position");
   6477 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation call failed.");
   6478 
   6479 	gl.vertexAttribPointer(position_location, 4, GL_FLOAT, GL_FALSE, 0, NULL);
   6480 	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed.");
   6481 
   6482 	gl.enableVertexAttribArray(position_location);
   6483 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
   6484 
   6485 	gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id_xfb_color);
   6486 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   6487 
   6488 	glw::GLuint color_location = gl.getAttribLocation(m_program_id_draw, "color");
   6489 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation call failed.");
   6490 
   6491 	gl.vertexAttribPointer(color_location, 4, GL_FLOAT, GL_FALSE, 0, NULL);
   6492 	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed.");
   6493 
   6494 	gl.enableVertexAttribArray(color_location);
   6495 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
   6496 
   6497 	gl.useProgram(m_program_id_draw);
   6498 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
   6499 
   6500 	gl.drawTransformFeedbackStreamInstanced(GL_TRIANGLE_STRIP, m_xfb_id, 0, 4);
   6501 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
   6502 }
   6503 
   6504 bool gl3cts::TransformFeedback::DrawXFBStreamInstanced::check()
   6505 {
   6506 	/* Functions handler */
   6507 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   6508 
   6509 	/* Number of pixels. */
   6510 	const glw::GLuint number_of_pixels = s_view_size * s_view_size;
   6511 
   6512 	/* Fetch framebuffer. */
   6513 	std::vector<glw::GLfloat> pixels(number_of_pixels);
   6514 
   6515 	gl.readPixels(0, 0, s_view_size, s_view_size, GL_RED, GL_FLOAT, &pixels[0]);
   6516 	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");
   6517 
   6518 	/* Check results. */
   6519 	for (glw::GLuint i = 0; i < number_of_pixels; ++i)
   6520 	{
   6521 		if (fabs(pixels[i] - 1.f) > 0.0625 /* precision, expected result == 1.0 */)
   6522 		{
   6523 			return false;
   6524 		}
   6525 	}
   6526 
   6527 	return true;
   6528 }
   6529 
   6530 void gl3cts::TransformFeedback::DrawXFBStreamInstanced::clean()
   6531 {
   6532 	/* Functions handler */
   6533 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   6534 
   6535 	gl.useProgram(0);
   6536 
   6537 	if (m_program_id_generate)
   6538 	{
   6539 		gl.deleteProgram(m_program_id_generate);
   6540 
   6541 		m_program_id_generate = 0;
   6542 	}
   6543 
   6544 	if (m_program_id_draw)
   6545 	{
   6546 		glw::GLuint position_location = gl.getAttribLocation(m_program_id_draw, "position");
   6547 
   6548 		gl.disableVertexAttribArray(position_location);
   6549 
   6550 		glw::GLuint color_location = gl.getAttribLocation(m_program_id_draw, "color");
   6551 
   6552 		gl.disableVertexAttribArray(color_location);
   6553 
   6554 		gl.deleteProgram(m_program_id_draw);
   6555 
   6556 		m_program_id_draw = 0;
   6557 	}
   6558 
   6559 	if (m_xfb_id)
   6560 	{
   6561 		gl.deleteTransformFeedbacks(1, &m_xfb_id);
   6562 
   6563 		m_xfb_id = 0;
   6564 	}
   6565 
   6566 	if (m_bo_id_xfb_position)
   6567 	{
   6568 		gl.deleteBuffers(1, &m_bo_id_xfb_position);
   6569 
   6570 		m_bo_id_xfb_position = 0;
   6571 	}
   6572 
   6573 	if (m_bo_id_xfb_color)
   6574 	{
   6575 		gl.deleteBuffers(1, &m_bo_id_xfb_color);
   6576 
   6577 		m_bo_id_xfb_position = 0;
   6578 	}
   6579 
   6580 	if (m_bo_id_uniform)
   6581 	{
   6582 		gl.deleteBuffers(1, &m_bo_id_uniform);
   6583 
   6584 		m_bo_id_uniform = 0;
   6585 	}
   6586 
   6587 	if (m_vao_id)
   6588 	{
   6589 		gl.deleteVertexArrays(1, &m_vao_id);
   6590 
   6591 		m_vao_id = 0;
   6592 	}
   6593 
   6594 	if (m_fbo_id)
   6595 	{
   6596 		gl.deleteFramebuffers(1, &m_fbo_id);
   6597 
   6598 		m_fbo_id = 0;
   6599 	}
   6600 
   6601 	if (m_rbo_id)
   6602 	{
   6603 		gl.deleteRenderbuffers(1, &m_rbo_id);
   6604 
   6605 		m_rbo_id = 0;
   6606 	}
   6607 }
   6608 
   6609 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_vertex_shader_blank = "#version 140\n"
   6610 																							  "\n"
   6611 																							  "void main()\n"
   6612 																							  "{\n"
   6613 																							  "}\n";
   6614 
   6615 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_geometry_shader_generate =
   6616 	"#version 400\n"
   6617 	"\n"
   6618 	"layout(points) in;\n"
   6619 	"layout(points, max_vertices = 8) out;\n"
   6620 	"\n"
   6621 	"layout(stream = 1) out vec4 color;\n"
   6622 	"\n"
   6623 	"void main()\n"
   6624 	"{\n"
   6625 	"    gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
   6626 	"    EmitStreamVertex(0);\n"
   6627 	"    gl_Position = vec4( 1.0, -1.0, 0.0, 1.0);\n"
   6628 	"    EmitStreamVertex(0);\n"
   6629 	"    gl_Position = vec4(-1.0,  1.0, 0.0, 1.0);\n"
   6630 	"    EmitStreamVertex(0);\n"
   6631 	"    gl_Position = vec4( 1.0,  1.0, 0.0, 1.0);\n"
   6632 	"    EmitStreamVertex(0);\n"
   6633 	"\n"
   6634 	"    color = vec4(1.0, 1.0, 1.0, 1.0);\n"
   6635 	"    EmitStreamVertex(1);\n"
   6636 	"    color = vec4(1.0, 1.0, 1.0, 1.0);\n"
   6637 	"    EmitStreamVertex(1);\n"
   6638 	"    color = vec4(1.0, 1.0, 1.0, 1.0);\n"
   6639 	"    EmitStreamVertex(1);\n"
   6640 	"    color = vec4(1.0, 1.0, 1.0, 1.0);\n"
   6641 	"    EmitStreamVertex(1);\n"
   6642 	"}\n";
   6643 
   6644 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_vertex_shader_draw =
   6645 	"#version 140\n"
   6646 	"\n"
   6647 	"uniform MatrixBlock\n"
   6648 	"{\n"
   6649 	"    mat4 transformation_0;\n"
   6650 	"    mat4 transformation_1;\n"
   6651 	"    mat4 transformation_2;\n"
   6652 	"    mat4 transformation_3;\n"
   6653 	"};\n"
   6654 	"\n"
   6655 	"in  vec4 position;\n"
   6656 	"in  vec4 color;\n"
   6657 	"out vec4 colour;\n"
   6658 	"\n"
   6659 	"void main()\n"
   6660 	"{\n"
   6661 	"    switch(gl_InstanceID % 4)\n"
   6662 	"    {\n"
   6663 	"    case 0:\n"
   6664 	"       gl_Position = position * transformation_0;\n"
   6665 	"       break;\n"
   6666 	"    case 1:\n"
   6667 	"       gl_Position = position * transformation_1;\n"
   6668 	"       break;\n"
   6669 	"    case 2:\n"
   6670 	"       gl_Position = position * transformation_2;\n"
   6671 	"       break;\n"
   6672 	"    case 3:\n"
   6673 	"       gl_Position = position * transformation_3;\n"
   6674 	"       break;\n"
   6675 	"    }\n"
   6676 	"    colour = color;\n"
   6677 	"}\n";
   6678 
   6679 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_fragment_shader_blank =
   6680 	"#version 130\n"
   6681 	"\n"
   6682 	"out vec4 pixel;\n"
   6683 	"\n"
   6684 	"void main()\n"
   6685 	"{\n"
   6686 	"    pixel = vec4(1.0);\n"
   6687 	"}\n";
   6688 
   6689 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_fragment_shader_draw = "#version 130\n"
   6690 																							   "\n"
   6691 																							   "in vec4 colour;\n"
   6692 																							   "out vec4 pixel;\n"
   6693 																							   "\n"
   6694 																							   "void main()\n"
   6695 																							   "{\n"
   6696 																							   "    pixel = colour;\n"
   6697 																							   "}\n";
   6698 
   6699 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_xfb_varyings[] = { "gl_Position",
   6700 																						   "gl_NextBuffer", "color" };
   6701 
   6702 const glw::GLuint gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_xfb_varyings_count =
   6703 	sizeof(s_xfb_varyings) / sizeof(s_xfb_varyings[0]);
   6704 
   6705 const glw::GLchar* gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_uniform = "MatrixBlock";
   6706 
   6707 const glw::GLuint gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_bo_xfb_size =
   6708 	4 /* vertex count */ * 4 /* vec4 components */
   6709 	* sizeof(glw::GLfloat) /* data type size */;
   6710 
   6711 const glw::GLfloat gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_bo_uniform_data[] = {
   6712 	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,
   6713 
   6714 	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,
   6715 
   6716 	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,
   6717 
   6718 	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
   6719 };
   6720 
   6721 const glw::GLuint gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_bo_uniform_size = sizeof(s_bo_uniform_data);
   6722 
   6723 const glw::GLuint gl3cts::TransformFeedback::DrawXFBStreamInstanced::s_view_size = 4;
   6724 
   6725 /*-----------------------------------------------------------------------------------------------*/
   6726 
   6727 glw::GLuint gl3cts::TransformFeedback::Utilities::buildProgram(
   6728 	glw::Functions const& gl, tcu::TestLog& log, glw::GLchar const* const geometry_shader_source,
   6729 	glw::GLchar const* const tessellation_control_shader_source,
   6730 	glw::GLchar const* const tessellation_evaluation_shader_source, glw::GLchar const* const vertex_shader_source,
   6731 	glw::GLchar const* const fragment_shader_source, glw::GLchar const* const* const transform_feedback_varyings,
   6732 	glw::GLsizei const transform_feedback_varyings_count, glw::GLenum const transform_feedback_varyings_mode,
   6733 	bool const do_not_detach, glw::GLint* linking_status)
   6734 {
   6735 	glw::GLuint program = 0;
   6736 
   6737 	struct Shader
   6738 	{
   6739 		glw::GLchar const* const source;
   6740 		glw::GLenum const		 type;
   6741 		glw::GLuint				 id;
   6742 	} shader[] = { { geometry_shader_source, GL_GEOMETRY_SHADER, 0 },
   6743 				   { tessellation_control_shader_source, GL_TESS_CONTROL_SHADER, 0 },
   6744 				   { tessellation_evaluation_shader_source, GL_TESS_EVALUATION_SHADER, 0 },
   6745 				   { vertex_shader_source, GL_VERTEX_SHADER, 0 },
   6746 				   { fragment_shader_source, GL_FRAGMENT_SHADER, 0 } };
   6747 
   6748 	glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);
   6749 
   6750 	try
   6751 	{
   6752 		/* Create program. */
   6753 		program = gl.createProgram();
   6754 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");
   6755 
   6756 		/* Shader compilation. */
   6757 
   6758 		for (glw::GLuint i = 0; i < shader_count; ++i)
   6759 		{
   6760 			if (DE_NULL != shader[i].source)
   6761 			{
   6762 				shader[i].id = gl.createShader(shader[i].type);
   6763 
   6764 				GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");
   6765 
   6766 				gl.attachShader(program, shader[i].id);
   6767 
   6768 				GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");
   6769 
   6770 				gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL);
   6771 
   6772 				GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");
   6773 
   6774 				gl.compileShader(shader[i].id);
   6775 
   6776 				GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");
   6777 
   6778 				glw::GLint status = GL_FALSE;
   6779 
   6780 				gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
   6781 				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
   6782 
   6783 				if (GL_FALSE == status)
   6784 				{
   6785 					glw::GLint log_size = 0;
   6786 					gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
   6787 					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
   6788 
   6789 					glw::GLchar* log_text = new glw::GLchar[log_size];
   6790 
   6791 					gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);
   6792 
   6793 					log << tcu::TestLog::Message << "Shader compilation has failed.\n"
   6794 						<< "Shader type: " << glu::getShaderTypeStr(shader[i].type) << "\n"
   6795 						<< "Shader compilation error log:\n"
   6796 						<< log_text << "\n"
   6797 						<< "Shader source code:\n"
   6798 						<< shader[i].source << "\n"
   6799 						<< tcu::TestLog::EndMessage;
   6800 
   6801 					delete[] log_text;
   6802 
   6803 					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");
   6804 
   6805 					throw 0;
   6806 				}
   6807 			}
   6808 		}
   6809 
   6810 		/* Link. */
   6811 		if (transform_feedback_varyings_count)
   6812 		{
   6813 			gl.transformFeedbackVaryings(program, transform_feedback_varyings_count, transform_feedback_varyings,
   6814 										 transform_feedback_varyings_mode);
   6815 			GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
   6816 		}
   6817 
   6818 		gl.linkProgram(program);
   6819 
   6820 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
   6821 
   6822 		glw::GLint status = GL_FALSE;
   6823 
   6824 		gl.getProgramiv(program, GL_LINK_STATUS, &status);
   6825 
   6826 		if (DE_NULL != linking_status)
   6827 		{
   6828 			*linking_status = status;
   6829 		}
   6830 
   6831 		if (GL_TRUE == status)
   6832 		{
   6833 			if (!do_not_detach)
   6834 			{
   6835 				for (glw::GLuint i = 0; i < shader_count; ++i)
   6836 				{
   6837 					if (shader[i].id)
   6838 					{
   6839 						gl.detachShader(program, shader[i].id);
   6840 
   6841 						GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
   6842 					}
   6843 				}
   6844 			}
   6845 		}
   6846 		else
   6847 		{
   6848 			glw::GLint log_size = 0;
   6849 
   6850 			gl.getProgramiv(program, GL_INFO_LOG_LENGTH, &log_size);
   6851 
   6852 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");
   6853 
   6854 			glw::GLchar* log_text = new glw::GLchar[log_size];
   6855 
   6856 			gl.getProgramInfoLog(program, log_size, NULL, &log_text[0]);
   6857 
   6858 			log << tcu::TestLog::Message << "Program linkage has failed due to:\n"
   6859 				<< log_text << "\n"
   6860 				<< tcu::TestLog::EndMessage;
   6861 
   6862 			delete[] log_text;
   6863 
   6864 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");
   6865 
   6866 			throw 0;
   6867 		}
   6868 	}
   6869 	catch (...)
   6870 	{
   6871 		if (program)
   6872 		{
   6873 			gl.deleteProgram(program);
   6874 
   6875 			program = 0;
   6876 		}
   6877 	}
   6878 
   6879 	for (glw::GLuint i = 0; i < shader_count; ++i)
   6880 	{
   6881 		if (0 != shader[i].id)
   6882 		{
   6883 			gl.deleteShader(shader[i].id);
   6884 
   6885 			shader[i].id = 0;
   6886 		}
   6887 	}
   6888 
   6889 	return program;
   6890 }
   6891 
   6892 /** @brief Substitute key with value within source code.
   6893  *
   6894  *  @param [in] source      Source code to be prerocessed.
   6895  *  @param [in] key         Key to be substituted.
   6896  *  @param [in] value       Value to be inserted.
   6897  *
   6898  *  @return Resulting string.
   6899  */
   6900 std::string gl3cts::TransformFeedback::Utilities::preprocessCode(std::string source, std::string key, std::string value)
   6901 {
   6902 	std::string destination = source;
   6903 
   6904 	while (true)
   6905 	{
   6906 		/* Find token in source code. */
   6907 		size_t position = destination.find(key, 0);
   6908 
   6909 		/* No more occurences of this key. */
   6910 		if (position == std::string::npos)
   6911 		{
   6912 			break;
   6913 		}
   6914 
   6915 		/* Replace token with sub_code. */
   6916 		destination.replace(position, key.size(), value);
   6917 	}
   6918 
   6919 	return destination;
   6920 }
   6921 
   6922 /** @brief Convert an integer to a string.
   6923  *
   6924  *  @param [in] i       Integer to be converted.
   6925  *
   6926  *  @return String representing integer.
   6927  */
   6928 std::string gl3cts::TransformFeedback::Utilities::itoa(glw::GLint i)
   6929 {
   6930 	std::stringstream stream;
   6931 
   6932 	stream << i;
   6933 
   6934 	return stream.str();
   6935 }
   6936 
   6937 /** @brief Convert an float to a string.
   6938  *
   6939  *  @param [in] f       Float to be converted.
   6940  *
   6941  *  @return String representing integer.
   6942  */
   6943 std::string gl3cts::TransformFeedback::Utilities::ftoa(glw::GLfloat f)
   6944 {
   6945 	std::stringstream stream;
   6946 
   6947 	stream << f;
   6948 
   6949 	return stream.str();
   6950 }
   6951