#ifndef _GL3CTRANSFORMFEEDBACKTESTS_HPP
#define _GL3CTRANSFORMFEEDBACKTESTS_HPP
/*-------------------------------------------------------------------------
 * OpenGL Conformance Test Suite
 * -----------------------------
 *
 * Copyright (c) 2015-2016 The Khronos Group Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */ /*!
 * \file
 * \brief
 */ /*-------------------------------------------------------------------*/

/**
 */ /*!
 * \file  gl3cTransformFeedback.hpp
 * \brief Transform Feedback Test Suite Interface
 */ /*-------------------------------------------------------------------*/

#include "glcTestCase.hpp"
#include "glwDefs.hpp"
#include "tcuDefs.hpp"

/* Includes. */
#include <map>
#include <string>
#include <typeinfo>
#include <vector>

#include "glwEnums.hpp"
#include "glwFunctions.hpp"

namespace gl3cts
{
namespace TransformFeedback
{
class Tests : public deqp::TestCaseGroup
{
public:
	Tests(deqp::Context& context);
	~Tests(void);
	virtual void init(void);

private:
	Tests(const Tests& other);
	Tests& operator=(const Tests& other);
};

/** APIErrors
 *
 *  Verifies if errors are generated as specified.
 *  Four test shall be run:
 *   - Test api errors defined in GL_EXT_transform_feedback.
 *   - Test api errors defined in GL_ARB_transform_feedback2.
 *   - Test api errors defined in GL_ARB_transform_feedback3.
 *   - Test api errors defined in GL_ARB_transform_feedback_instanced.
 */
class APIErrors : public deqp::TestCase
{
public:
	APIErrors(deqp::Context& context);
	~APIErrors(void);
	IterateResult iterate(void);

private:
	deqp::Context& m_context;

	static const glw::GLchar* m_tessellation_control_shader;
	static const glw::GLchar* m_tessellation_evaluation_shader;
	static const glw::GLchar* m_geometry_shader;
	static const glw::GLchar* s_vertex_shader_with_input_output;
	static const glw::GLchar* s_vertex_shader_with_output;
	static const glw::GLchar* s_vertex_shader_without_output;
	static const glw::GLchar* s_fragment_shader;
	static const glw::GLchar* m_varying_name;

	static const glw::GLfloat m_buffer_1_data[];
	static const glw::GLsizei m_buffer_1_size;

	glw::GLuint m_buffer_0;
	glw::GLuint m_buffer_1;

	glw::GLuint m_vertex_array_object;

	glw::GLuint m_transform_feedback_object_0;
	glw::GLuint m_transform_feedback_object_1;

	glw::GLuint m_query_object;

	glw::GLuint m_program_id_with_input_output;
	glw::GLuint m_program_id_with_output;
	glw::GLuint m_program_id_without_output;
	glw::GLuint m_program_id_with_geometry_shader;
	glw::GLuint m_program_id_with_tessellation_shaders;

	/** Check the following if EXT_transform_feedback is supported or context is
	 *  at least 3.0:
	 *
	 *  - INVALID_VALUE is generated by BindBufferRange, BindBufferOffset and
	 *    BindBufferBase when <index> is greater or equal to
	 *    MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS;
	 *  - INVALID_VALUE is generated by BindBufferRange and BindBufferOffset
	 *    when <size> is less or equal to zero;
	 *  - INVALID_VALUE is generated by BindBufferRange and BindBufferOffset
	 *    when <offset> is not word-aligned;
	 *  - INVALID_VALUE is generated by BindBufferRange and BindBufferOffset
	 *    when <size> is not word-aligned;
	 *  - INVALID_OPERATION is generated by BindBufferRange, BindBufferOffset and
	 *    BindBufferBase when <target> is TRANSFORM_FEEDBACK_BUFFER and transform
	 *    feedback is active;
	 *  - INVALID_OPERATION is generated by UseProgram when transform feedback is
	 *    active;
	 *  - INVALID_OPERATION is generated by LinkProgram when <program> is currently
	 *    active and transform feedback is active;
	 *  - INVALID_OPERATION is generated by BeginTransformFeedback when transform
	 *    feedback is active;
	 *  - INVALID_OPERATION is generated by EndTransformFeedback when transform
	 *    feedback is inactive;
	 *  - INVALID_OPERATION is generated by draw command when generated primitives
	 *    type does not match <primitiveMode>;
	 *  - INVALID_OPERATION is generated by BeginTransformFeedback when any binding
	 *    point used by XFB does not have buffer bound;
	 *  - INVALID_OPERATION is generated by BeginTransformFeedback when no program
	 *    is active;
	 *  - INVALID_OPERATION is generated by BeginTransformFeedback when no variable
	 *    are specified to be captured in the active program;
	 *  - INVALID_VALUE is generated by TransformFeedbackVaryings when <program> is
	 *    not id of the program object;
	 *  - INVALID_VALUE is generated by TransformFeedbackVaryings when <bufferMode>
	 *    is SEPARATE_ATTRIBS and <count> is exceeds limits;
	 *  - IVALID_VALUE is generated by GetTransformFeedbackVarying when <index> is
	 *    greater than or equal to TRANSFORM_FEEDBACK_VARYINGS;
	 *  - INVALID_VALUE is generated by GetIntegerIndexdv when <index> exceeds the
	 *    limits of MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS and <param> is one of the
	 *    following:
	 *    * TRANSFORM_FEEDBACK_BUFFER_BINDING,
	 *    * TRANSFORM_FEEDBACK_BUFFER_START,
	 *    * TRANSFORM_FEEDBACK_BUFFER_SIZE;
	 *  - INVALID_VALUE is generated by GetBooleanIndexedv when <index> exceeds the
	 *    limits of MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS and <param> is
	 *    TRANSFORM_FEEDBACK_BUFFER_BINDING.
	 */
	bool testExtension1(void);

	/** Check the following if ARB_transform_feedback2 is supported or context is
	 *  at least 4.0:
	 *
	 *  - INVALID_OPERATION is generated by BindTransformFeedback if current
	 *    transform feedback is active and not paused;
	 *  - INVALID_OPERATION is generated by DeleteTransformFeedbacks if any of <ids>
	 *    is active;
	 *  - INVALID_OPERATION is generated by PauseTransformFeedback if current
	 *    transform feedback is not active or paused;
	 *  - INVALID_OPERATION is generated by ResumeTransformFeedback if current
	 *    transform feedback is not active or not paused;
	 *  - No error is generated by draw command when transform feedback is paused
	 *    and primitive modes do not match;
	 *  - No error is generated by UseProgram when transform feedback is paused;
	 *  - INVALID_OPERATION is generated by LinkProgram when <program> is used by
	 *    some transform feedback object that is currently not active;
	 *  - INVALID_VALUE is generated by DrawTransformFeedback if <id> is not name of
	 *    transform feedback object;
	 *  - INVALID_OPERATION is generated by DrawTransformFeedback when
	 *    EndTransformFeedback was never called for the object named <id>.
	 */
	bool testExtension2(void);

	/** Check the following if ARB_transform_feedback3 is supported or context is
	 *  at least 4.0:
	 *
	 *  - INVALID_VALUE is generated by BeginQueryIndexed, EndQueryIndexed and
	 *    GetQueryIndexediv when <target> is TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN and
	 *    <index> exceeds limits of MAX_VERTEX_STREAMS;
	 *  - INVALID_VALUE is generated by BeginQueryIndexed, EndQueryIndexed and
	 *    GetQueryIndexediv when <target> is PRIMITIVES_GENERATED and <index> exceeds
	 *    limits of MAX_VERTEX_STREAMS;
	 *  - INVALID_OPERATION is generated by EndQueryIndexed when name of active
	 *    query at <index> of <target> is zero;
	 *  - INVALID_VALUE is generated by DrawTransformFeedbackStream when <stream>
	 *    exceeds limits of MAX_VERTEX_STREAMS;
	 *  - INVALID_OPERATION is generated by TransformFeedbackVaryings when
	 *    <varyings> contains any of the special names while <bufferMode> is not
	 *    INTERLEAVED_ATTRIBS;
	 *  - INVALID_OPERATION is generated by TransformFeedbackVaryings when
	 *    <varyings> contains more "gl_NextBuffer" entries than allowed limit of
	 *    MAX_TRANSFORM_FEEDBACK_BUFFERS;
	 */
	bool testExtension3(void);

	/** Check the following if ARB_transform_feedback_instanced is supported or
	 *  context is at least 4.2:
	 *
	 *  - INVALID_ENUM is generated by DrawTransformFeedbackInstanced and
	 *    DrawTransformFeedbackStreamInstanced if <mode> is invalid;
	 *  - INVALID_OPERATION is generated by DrawTransformFeedbackInstanced and
	 *    DrawTransformFeedbackStreamInstanced if <mode> does not match geometry
	 *    shader;
	 *  - INVALID_OPERATION is generated by DrawTransformFeedbackInstanced and
	 *    DrawTransformFeedbackStreamInstanced if <mode> does not match tessellation;
	 *  - INVALID_VALUE is generated by DrawTransformFeedbackStreamInstanced if
	 *    <stream> is greater than or equal to MAX_VERTEX_STREAMS;
	 *  - INVALID_VALUE is generated by DrawTransformFeedbackInstanced and
	 *    DrawTransformFeedbackStreamInstanced if <id> is not name of transform
	 *    feedback object;
	 *  - INVALID_OPERATION is generated by DrawTransformFeedbackInstanced and
	 *    DrawTransformFeedbackStreamInstanced if a non-zero buffer object name is
	 *    bound to an enabled array and the buffer object's data store is currently
	 *    mapped;
	 *  - INVALID_OPERATION is generated if by DrawTransformFeedbackStreamInstanced
	 *    if EndTransformFeedback was never called for the object named <id>.
	 */
	bool testInstanced(void);

	typedef GLW_APICALL void (GLW_APIENTRY *BindBufferOffsetEXT_ProcAddress)(glw::GLenum target, glw::GLuint index, glw::GLuint buffer,
																			 glw::GLintptr offset);
	typedef GLW_APICALL void (GLW_APIENTRY *GetIntegerIndexedvEXT_ProcAddress)(glw::GLenum param, glw::GLuint index, glw::GLint* values);
	typedef GLW_APICALL void (GLW_APIENTRY *GetBooleanIndexedvEXT_ProcAddress)(glw::GLenum param, glw::GLuint index, glw::GLboolean* values);

	BindBufferOffsetEXT_ProcAddress   m_glBindBufferOffsetEXT;
	GetIntegerIndexedvEXT_ProcAddress m_glGetIntegerIndexedvEXT;
	GetBooleanIndexedvEXT_ProcAddress m_glGetBooleanIndexedvEXT;
};

/** LinkingErrors
 *
 *  Verifies that linker reports errors as specified.
 *
 *  Test should be run if EXT_transform_feedback is supported or context is
 *  at least 3.0.
 *
 *  Check if link process fails under the following conditions:
 *  - <count> specified by TransformFeedbackVaryings is non-zero and program has
 *    neither vertex nor geometry shader;
 *  - <varyings> specified by TransformFeedbackVaryings contains name of
 *    variable that is not available for capture;
 *  - <varyings> specified by TransformFeedbackVaryings contains name of
 *    variable more than once;
 *  - number of components specified to capture exceeds limits
 *    MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS or
 *    MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS.
 */
class LinkingErrors : public deqp::TestCase
{
public:
	LinkingErrors(deqp::Context& context);
	~LinkingErrors(void);
	IterateResult iterate(void);

private:
	deqp::Context& m_context;

	static const glw::GLchar* s_fragment_shader;
	static const glw::GLchar* s_vertex_shader_template;
	static const glw::GLchar* s_valid_transform_feedback_varying;
	static const glw::GLchar* s_invalid_transform_feedback_varying;
	static const glw::GLchar* s_repeated_transform_feedback_varying[];
	static const glw::GLsizei s_repeated_transform_feedback_varying_count;

	bool testNoVertexNoGeometry(void);
	bool testInvalidVarying(void);
	bool testRepeatedVarying(void);
	bool testTooManyVaryings(void);
};

/** Limits
 *
 *  Verifies that limits reported by API are as expected.
 *
 *  Check the following if EXT_transform_feedback is supported or context is at
 *  least 3.0:
 *  - MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS is at least 64,
 *  - MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS is at least 4,
 *  - MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS is at least 4.
 *
 *  Check the following if ARB_transform_feedback3 is supported or context is at
 *  least 4.0:
 *  - MAX_TRANSFORM_FEEDBACK_BUFFERS is at least 4,
 *  - MAX_VERTEX_STREAMS is at least 1.
 */
class Limits : public deqp::TestCase
{
public:
	Limits(deqp::Context& context);
	~Limits(void);
	IterateResult iterate(void);

private:
	deqp::Context& m_context;

	static const glw::GLchar* s_fragment_shader;
	static const glw::GLchar* s_vertex_shader;

	static const glw::GLint s_min_value_of_max_transform_feedback_interleaved_components;
	static const glw::GLint s_min_value_of_max_transform_feedback_separate_attribs;
	static const glw::GLint s_min_value_of_max_transform_feedback_separate_components;
	static const glw::GLint s_min_value_of_max_transform_feedback_buffers;
	static const glw::GLint s_min_value_of_max_vertex_streams;

	bool test_max_transform_feedback_interleaved_components(void);
	bool test_max_transform_feedback_separate_attribs(void);
	bool test_max_transform_feedback_separate_components(void);
	bool test_max_transform_feedback_buffers(void);
	bool test_max_vertex_streams(void);
};

/** CaptureVertexInterleaved
 *
 *  Verifies if geometry processed with vertex shader is captured as expected in
 *  interleaved mode.
 *
 *  Test should be run if EXT_transform_feedback is supported or context is
 *  at least 3.0.
 *
 *  Steps:
 *  - prepare program consisting of vertex and fragment shader; Vertex shader
 *    should assign all MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS components;
 *    One of the variables must be a position; Position should be set to one of
 *    corners, based on gl_VertexID: 0 - top left, 1 - top right, 2 - bottom left
 *    and 3 - bottom right; Rest of components should be covered with output
 *    variables of type vec4; Fragment shader should accept all outputs from
 *    vertex shader as inputs and use them to calculate non-black output color;
 *  - instruct implementation to capture all outputs defined by vertex shader;
 *    Use interleaved mode;
 *  - prepare and set buffer to store captured geometry;
 *  - prepare, set and clean frame-buffer with black color;
 *  - execute BeginTransformFeedback;
 *  - execute DrawElements;
 *  - execute EndTransformFeedback;
 *  - inspect contents of frame-buffer to check if rasterization was done
 *    correctly;
 *  - inspect TRANSFORM_FEEDBACK_BUFFER_START and
 *    TRANSFORM_FEEDBACK_BUFFER_SIZE;
 *  - inspect contents of the buffer to check if geometry was captured
 *    correctly.
 *
 *  Test the following BindBuffer routines:
 *  - BindBufferRange - use non-zero offset,
 *  - BindBufferOffset - use non-zero offset,
 *  - BindBufferBase.
 *
 *  Test the following primitive types:
 *  - GL_POINTS - use these indices: [0, 1, 2, 3]; All corner pixels should be
 *    set to specific colors; XFB should contain four vertices;
 *  - GL_LINES - use these indices: [0, 1, 2, 3]; Top and bottom edges should be
 *    drawn; XFB should contain four vertices;
 *  - GL_LINE_LOOP - use these indices: [0, 1, 3, 2]; All four edges should be
 *    drawn; XFB should contain eight vertices;
 *  - GL_LINE_STRIP - use these indices: [0, 1, 3, 2]; Top, right and bottom
 *    edge should be drawn; XFB should contain six vertices;
 *  - GL_TRIANGLES - use these indices: [2, 0, 1, 2, 1, 3]; Whole image should
 *    be drawn; XFB should contain six vertices;
 *  - GL_TRIANGLE_STRIP - use these indices: [0, 1, 2, 3]; Whole image should
 *    be drawn; XFB should contain six vertices;
 *  - GL_TRIANGLE_FAN - use these indices: [2, 0, 1, 3]; Whole image should
 *    be drawn; XFB should contain six vertices.
 *
 *  Number of components that can be passed to rasterization must not exceed
 *  MAX_VARYING_COMPONENTS.
 */
class CaptureVertexInterleaved : public deqp::TestCase
{
public:
	CaptureVertexInterleaved(deqp::Context& context, const char* test_name, const char* test_description);
	~CaptureVertexInterleaved(void);
	virtual IterateResult iterate(void);

protected:
	deqp::Context& m_context;
	glw::GLuint	m_program;
	glw::GLuint	m_framebuffer;
	glw::GLuint	m_renderbuffer;
	glw::GLuint	m_buffer;
	glw::GLuint	m_buffer_size;
	glw::GLuint	m_vertex_array_object;
	glw::GLint	 m_max_transform_feedback_components;
	glw::GLenum	m_attrib_type;
	glw::GLuint	m_max_vertices_drawn;

	typedef GLW_APICALL void (GLW_APIENTRY *BindBufferOffsetEXT_ProcAddress)(glw::GLenum target, glw::GLuint index, glw::GLuint buffer,
																			 glw::GLintptr offset);

	BindBufferOffsetEXT_ProcAddress m_glBindBufferOffsetEXT;

	static const glw::GLchar* s_vertex_shader_source_code_template;
	static const glw::GLchar* s_fragment_shader_source_code;

	static const glw::GLuint  s_max_element_indices_count = 6;
	static const glw::GLuint  s_element_indices[][s_max_element_indices_count];
	static const glw::GLuint  s_primitive_cases_count;
	static const glw::GLuint  s_element_indices_counts[];
	static const glw::GLenum  s_primitive_cases[];
	static const glw::GLenum  s_primitive_cases_xfb[];
	static const glw::GLuint  s_framebuffer_size;
	static const glw::GLfloat s_rasterization_epsilon;
	static const glw::GLuint  s_max_vertex_id = 4;

	enum BindBufferCase
	{
		BIND_BUFFER_BASE_CASE,
		BIND_BUFFER_RANGE_CASE,
		BIND_BUFFER_OFFSET_CASE,
		BIND_BUFFER_CASES_COUNT
	};

	virtual void fetchLimits(void);
	virtual void buildProgram(void);
	void		 createFramebuffer(void);
	virtual void createTransformFeedbackBuffer(void);
	void		 createVertexArrayObject(void);
	virtual void draw(glw::GLuint primitive_case);
	virtual bool checkFramebuffer(glw::GLuint primitive_case);
	virtual bool checkTransformFeedbackBuffer(BindBufferCase bind_case, glw::GLenum primitive_type);
	virtual void bindBuffer(BindBufferCase bind_case);
	virtual void clean(void);
	virtual void cleanBuffer(void);
};

/** CaptureGeometryInterleaved
 *
 *  Verifies if geometry processed with geometry shader is captured as expected
 *  in interleaved mode.
 *
 *  Test should be run if either EXT_transform_feedback is supported or context
 *  is at least 3.0 and either ARB_geometry_shader4 is supported or context is
 *  at least 3.2.
 *
 *  Modify CaptureVertexInterleaved test in the following aspects:
 *  - outputs definition and assignment is done in geometry instead of
 *    vertex shader;
 *  - vertex shader can be blank;
 *  - use DrawArrays instead of DrawElements, draw single vertex with GL_POINTS.
 *
 *  Test the following output primitive types for geometry shader:
 *  - points - emit vertices as in GL_POINTS case;
 *  - line_strip - emit vertices as in GL_LINE_STRIP case;
 *  - triangle_strip - emit vertices as in GL_TRIANGLE_STRIP case.
 *
 *  Number of components written by geometry shader must not exceed
 *  MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS.
 */
class CaptureGeometryInterleaved : virtual public CaptureVertexInterleaved
{
public:
	CaptureGeometryInterleaved(deqp::Context& context, const char* test_name, const char* test_description);
	~CaptureGeometryInterleaved(void);
	virtual IterateResult iterate(void);

protected:
	virtual void fetchLimits(void);
	using CaptureVertexInterleaved::buildProgram;
	virtual void buildProgram(glw::GLuint primitive_case);
	virtual void draw(glw::GLuint primitive_case);

	static const glw::GLchar* s_geometry_shader_source_code_template;
	static const glw::GLchar* s_blank_vertex_shader_source_code;

	static const glw::GLchar* s_geometry_interleaved_primitive_cases[];
	static const glw::GLenum  s_geometry_interleaved_primitive_cases_xfb[];
	static const glw::GLuint  s_geometry_interleaved_primitive_cases_count;
};

/** CaptureVertexSeparate
 *
 *  Verifies if geometry processed with vertex shader is captured as expected in
 *  separate mode.
 *
 *  Test should be run if EXT_transform_feedback is supported or context is
 *  at least 3.0.
 *
 *  Modify CaptureVertexInterleaved test in the following aspects:
 *  - use transform feedback in separate mode.
 *
 *  Separate mode require one buffer per captured variable.
 *
 *  Number of attributes and components that can be captured is limited by:
 *  - MAX TRANSFORM FEEDBACK SEPARATE ATTRIBS,
 *  - MAX TRANSFORM FEEDBACK SEPARATE COMPONENTS.
 */
class CaptureVertexSeparate : virtual public CaptureVertexInterleaved
{
public:
	CaptureVertexSeparate(deqp::Context& context, const char* test_name, const char* test_description);

protected:
	glw::GLuint* m_buffers;
	glw::GLint   m_max_transform_feedback_separate_attribs;

	virtual void fetchLimits(void);
	virtual void createTransformFeedbackBuffer(void);
	virtual void bindBuffer(BindBufferCase bind_case);
	virtual void cleanBuffer(void);
	virtual bool checkTransformFeedbackBuffer(BindBufferCase bind_case, glw::GLenum primitive_type);
};

/** CaptureGeometrySeparate
 *
 *  Verifies if geometry processed with geometry shader is captured as expected
 *  in separate mode.
 *
 *  Test should be run if either EXT_transform_feedback is supported or context
 *  is at least 3.0 and either ARB_geometry_shader4 is supported or context is
 *  at least 3.2.
 *
 *  Modify CaptureGeometryInterleaved test in the following aspects:
 *  - use transform feedback in separate mode.
 *
 *  Separate mode require one buffer per captured variable.
 *
 *  Number of attributes and components that can be captured is limited by:
 *  - MAX TRANSFORM FEEDBACK SEPARATE ATTRIBS,
 *  - MAX TRANSFORM FEEDBACK SEPARATE COMPONENTS.
 */
class CaptureGeometrySeparate : public CaptureGeometryInterleaved, virtual public CaptureVertexSeparate
{
public:
	CaptureGeometrySeparate(deqp::Context& context, const char* test_name, const char* test_description);
	virtual IterateResult iterate(void)
	{
		return CaptureGeometryInterleaved::iterate();
	}

protected:
	glw::GLuint* m_buffers;
	glw::GLint   m_max_transform_feedback_separate_attribs;

	virtual void draw(glw::GLenum primitive_type)
	{
		CaptureGeometryInterleaved::draw(primitive_type);
	}
	virtual void fetchLimits(void)
	{
		CaptureVertexSeparate::fetchLimits();
	}
	virtual void createTransformFeedbackBuffer(void)
	{
		CaptureVertexSeparate::createTransformFeedbackBuffer();
	}
	virtual void bindBuffer(BindBufferCase bind_case)
	{
		CaptureVertexSeparate::bindBuffer(bind_case);
	}
	virtual void cleanBuffer(void)
	{
		CaptureVertexSeparate::cleanBuffer();
	}
	virtual bool checkTransformFeedbackBuffer(BindBufferCase bind_case, glw::GLenum primitive_type)
	{
		return CaptureVertexSeparate::checkTransformFeedbackBuffer(bind_case, primitive_type);
	}
};

/** GetXFBVaryingVertexInterleaved
 *
 *  Verifies if varyings captured from vertex stage are correctly reported in
 *  interleaved mode.
 *
 *  Test should be run if EXT_transform_feedback is supported or context is
 *  at least 3.0.
 *
 *  Steps:
 *  - prepare program consisting of vertex and fragment shader; Vertex shader
 *    should define and assign maximum allowed number of varyings of tested type;
 *    Fragment shader can be blank;
 *  - instruct implementation to capture all outputs defined by vertex shader;
 *    Use interleaved mode;
 *  - inspect all captured varying with GetTransformFeedbackVarying;
 *  - inspect TRANSFORM_FEEDBACK_VARYINGS;
 *  - inspect TRANSFORM_FEEDBACK_BUFFER_MODE;
 *  - inspect TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH.
 *
 *  Test all valid types.
 *
 *
 *  GetXFBVaryingGeometryInterleaved
 *
 *  Verifies if varyings captured from geometry stage are correctly reported in
 *  interleaved mode.
 *
 *  Test should be run if either EXT_transform_feedback is supported or context
 *  is at least 3.0 and either ARB_geometry_shader4 is supported or context is
 *  at least 3.2.
 *
 *  Modify GetXFBVaryingVertexInterleaved test in the following aspects:
 *  - outputs definition and assignment is done in geometry instead of
 *    vertex shader;
 *  - vertex shader can be blank;
 *
 *
 *  GetXFBVaryingVertexSeparate
 *
 *  Verifies if varyings captured from vertex stage are correctly reported in
 *  separate mode.
 *
 *  Test should be run if EXT_transform_feedback is supported or context is
 *  at least 3.0.
 *
 *  Modify CaptureGeometryInterleaved test in the following aspects:
 *  - use transform feedback in separate mode.
 *
 *  Separate mode require one buffer per captured variable.
 *
 *
 *  GetXFBVaryingGeometrySeparate
 *
 *  Verifies if varyings captured from geometry stage are correctly reported in
 *  separate mode.
 *
 *  Test should be run if either EXT_transform_feedback is supported or context
 *  is at least 3.0 and either ARB_geometry_shader4 is supported or context is
 *  at least 3.2.
 *
 *  Modify GetXFBVaryingGeometryInterleaved test in the following aspects:
 *  - use transform feedback in separate mode.
 *
 *  Separate mode require one buffer per captured variable.
 */
class CheckGetXFBVarying : public deqp::TestCase
{
public:
	CheckGetXFBVarying(deqp::Context& context, const char* test_name, const char* test_description);
	~CheckGetXFBVarying(void);
	virtual IterateResult iterate(void);

private:
	deqp::Context& m_context;
	glw::GLint	 m_max_xfb_interleaved_components;
	glw::GLint	 m_max_xfb_separate_attributes;
	glw::GLint	 m_max_xfb_separate_components;
	glw::GLint	 m_max_varying_components;
	glw::GLint	 m_max_varying_vectors;
	glw::GLint	 m_max_geometry_total_output_components;

	void		fetchLimits(void);
	glw::GLuint numberOfAttributes(glw::GLuint capture_way, glw::GLuint shader_case, glw::GLuint varying_type);

	glw::GLuint buildProgram(glw::GLuint capture_way, glw::GLuint shader_case, glw::GLuint varying_type,
							 glw::GLuint number_of_attributes);

	bool check(glw::GLuint program, glw::GLuint capture_way, glw::GLuint shader_case, glw::GLuint varying_type,
			   glw::GLuint number_of_attributes);

	static const glw::GLchar* s_generic_fragment_shader;

	static const struct ShaderCase
	{
		const glw::GLchar* vertex_shader;
		const glw::GLchar* geometry_shader;
	} s_shader_cases[];

	static const glw::GLuint s_shader_cases_count;

	static const struct VaryingType
	{
		const glw::GLenum  type;
		const glw::GLchar* name;
		const glw::GLuint  components_count;
		const bool		   float_component;
	} s_varying_types[];

	static const glw::GLuint s_varying_types_count;

	static const glw::GLenum s_capture_ways[];
	static const glw::GLuint s_capture_ways_count;
};

/** QueryVertexInterleaved
 *
 *  Verifies if queries are performed as expected when geometry is captured from
 *  vertex stage in interleaved mode.
 *
 *  Test should be run if EXT_transform_feedback is supported or context is
 *  at least 3.0.
 *
 *  Modify CaptureVertexInterleaved test in the following aspects:
 *  - buffer used as storage for captured geometry should be too small to fit
 *    all emitted vertices;
 *  - execute BeginQuery for PRIMITIVES_GENERATED and
 *    TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN before draw is executed; End queries
 *    after draw call.
 *
 *  Test pass if results of queries are correct.
 */
class QueryVertexInterleaved : public CaptureVertexInterleaved
{
public:
	QueryVertexInterleaved(deqp::Context& context, const char* test_name, const char* test_description);

protected:
	glw::GLuint m_query_object;

	virtual void createTransformFeedbackBuffer(void);
	virtual void draw(glw::GLuint primitive_case);
	virtual bool checkTransformFeedbackBuffer(BindBufferCase bind_case, glw::GLenum primitive_type);
	virtual void clean(void);
};

/** QueryGeometryInterleaved
 *
 *  Verifies if queries are performed as expected when geometry is captured from
 *  geometry stage in interleaved mode.
 *
 *  Test should be run if either EXT_transform_feedback is supported or context
 *  is at least 3.0 and either ARB_geometry_shader4 is supported or context is
 *  at least 3.2.
 *
 *  Modify CaptureGeometryInterleaved test in the following aspects:
 *  - buffer used as storage for captured geometry should be too small to fit
 *    all emitted vertices;
 *  - execute BeginQuery for PRIMITIVES_GENERATED and
 *    TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN before draw is executed; End queries
 *    after draw call.
 *
 *  Test pass if results of queries are correct.
 */
class QueryGeometryInterleaved : public CaptureGeometryInterleaved
{
public:
	QueryGeometryInterleaved(deqp::Context& context, const char* test_name, const char* test_description);

protected:
	glw::GLuint m_query_object;

	virtual void createTransformFeedbackBuffer(void);
	virtual void draw(glw::GLuint primitive_case);
	virtual bool checkTransformFeedbackBuffer(BindBufferCase bind_case, glw::GLenum primitive_type);
	virtual void clean(void);
};

/** QueryVertexSeparate
 *
 *  Verifies if queries are performed as expected when geometry is captured from
 *  vertex stage in separate mode.
 *
 *  Test should be run if EXT_transform_feedback is supported or context is
 *  at least 3.0.
 *
 *  Modify CaptureVertexSeparate test in the following aspects:
 *  - buffers used as storage for captured geometry should be too small to fit
 *    all emitted vertices;
 *  - execute BeginQuery for PRIMITIVES_GENERATED and
 *    TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN before draw is executed; End queries
 *    after draw call;
 *  - use transform feedback in separate mode.
 *
 *  Separate mode require one buffer per captured variable.
 *
 *  Test pass if results of queries are correct.
 */
class QueryVertexSeparate : public CaptureVertexSeparate
{
public:
	QueryVertexSeparate(deqp::Context& context, const char* test_name, const char* test_description);

protected:
	glw::GLuint m_query_object;

	virtual void createTransformFeedbackBuffer(void);
	virtual void draw(glw::GLuint primitive_case);
	virtual bool checkTransformFeedbackBuffer(BindBufferCase bind_case, glw::GLenum primitive_type);
	virtual void clean(void);
};

/** QueryGeometrySeparate
 *
 *  Verifies if queries are performed as expected when geometry is captured from
 *  geometry stage in separate mode.
 *
 *  Test should be run if either EXT_transform_feedback is supported or context
 *  is at least 3.0 and either ARB_geometry_shader4 is supported or context is
 *  at least 3.2.
 *
 *  Modify CaptureGeometrySeparate test in the following aspects:
 *  - buffers used as storage for captured geometry should be too small to fit
 *    all emitted vertices;
 *  - execute BeginQuery for PRIMITIVES_GENERATED and
 *    TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN before draw is executed; End queries
 *    after draw call;
 *  - use transform feedback in separate mode.
 *
 *  Separate mode require one buffer per captured variable.
 *
 *  Test pass if results of queries are correct.
 */
class QueryGeometrySeparate : public CaptureGeometrySeparate
{
public:
	QueryGeometrySeparate(deqp::Context& context, const char* test_name, const char* test_description);

protected:
	glw::GLuint m_query_object;

	virtual void createTransformFeedbackBuffer(void);
	virtual void draw(glw::GLuint primitive_case);
	virtual bool checkTransformFeedbackBuffer(BindBufferCase bind_case, glw::GLenum primitive_type);
	virtual void clean(void);
};

/** DiscardVertex
 *
 *  Verifies if rasterization is discarded when geometry is captured from vertex
 *  stage.
 *
 *  Test should be run if EXT_transform_feedback is supported or context is
 *  at least 3.0.
 *
 *  Modify CaptureVertexInterleaved test in the following aspects:
 *  - disable rasterization before draw call;
 *  - it is expected that framebuffer contents will not change, while XFB buffer
 *  is modified.
 */
class DiscardVertex : public CaptureVertexInterleaved
{
public:
	DiscardVertex(deqp::Context& context, const char* test_name, const char* test_description);

protected:
	virtual void draw(glw::GLuint primitive_case);
	virtual bool checkFramebuffer(glw::GLuint primitive_case);
};

/** DiscardGeometry
 *
 *  Verifies if rasterization is discarded when geometry is captured from
 *  geometry stage.
 *
 *  Test should be run if EXT_transform_feedback is supported or context is at least 3.0.
 *  Test should be run if ARB_geometry_shader4 is supported or context is at least 3.2.
 *
 *  Modify CaptureGeometryInterleaved test in the following aspects:
 *  - disable rasterization before draw call;
 *  - it is expected that framebuffer contents will not change, while XFB buffer
 *    is modified.
 */
class DiscardGeometry : public CaptureGeometryInterleaved
{
public:
	DiscardGeometry(deqp::Context& context, const char* test_name, const char* test_description);

protected:
	virtual void draw(glw::GLuint primitive_case);
	virtual bool checkFramebuffer(glw::GLuint primitive_case);
};

/** DrawXFB
 *
 *  Verifies that transform feedback objects can be used to draw.
 *
 *  Test should be executed if ARB_transform_feedback2 is supported or context
 *  is at least 4.0.
 *
 *  Steps:
 *  - prepare two programs consisting of vertex shader which will:
 *     * output position based on gl_VertexID:
 *     * output color by passing value of uniform;
 *    First program should use the following positions:
 *     ID |  X |  Y
 *      0 | -1 | -1
 *      1 | -1 |  1
 *      2 |  1 |  1
 *    Second program should use the following positions:
 *      0 | -1 | -1
 *      1 |  1 |  1
 *      2 |  1 | -1
 *  - prepare three XFB objects and corresponding buffers for captured geometry;
 *    Each XFB should capture position and color from both programs;
 *  - activate first program;
 *  - for each XFB object:
 *     * set uniform to color corresponding with XFB;
 *     * activate XFB;
 *     * execute DrawArrays to draw three points starting at 0;
 *     * pause XFB;
 *  - inspect TRANSFORM_FEEDBACK_BUFFER_PAUSED and
 *    TRANSFORM_FEEDBACK_BUFFER_ACTIVE;
 *  - activate second program;
 *  - for each XFB object:
 *     * set uniform to color corresponding with XFB;
 *     * resume XFB;
 *     * execute DrawArrays to draw three points starting at 0;
 *     * end XFB;
 *  - inspect TRANSFORM_FEEDBACK_BUFFER_PAUSED and
 *    TRANSFORM_FEEDBACK_BUFFER_ACTIVE;
 *  - prepare program consisting of vertex and fragment stage; Vertex shader
 *    should pass position and color; Fragment stage should pass color;
 *  - set program;
 *  - set vertex array to match layout of XFB;
 *  - for each XFB:
 *     * prepare and clean framebuffer;
 *     * execute DrawTransformFeedback to draw triangles;
 *     * inspect contents of framebuffer;
 *
 *  It is expected that drawn images will be filled with color set via uniform
 *  variables.
 *
 *  Repeat steps for both interleaved and separate modes.
 */
class DrawXFB : public deqp::TestCase
{
public:
	DrawXFB(deqp::Context& context, const char* test_name, const char* test_description);
	~DrawXFB(void);
	virtual IterateResult iterate(void);

protected:
	static const glw::GLchar* s_vertex_shader_xfb;
	static const glw::GLchar* s_vertex_shader_draw;
	static const glw::GLchar* s_fragment_shader;

	static const glw::GLuint  s_xfb_varyings_count = 2;
	static const glw::GLchar* s_xfb_varyings[s_xfb_varyings_count];
	static const glw::GLuint  s_vertex_count = 3;
	static const glw::GLenum  s_capture_modes[];
	static const glw::GLuint  s_capture_modes_count;
	static const glw::GLuint  s_capture_size = s_vertex_count * sizeof(glw::GLfloat) * 4 /* number of components */ *
											  s_xfb_varyings_count * 2 /* number of programs */;
	static const glw::GLuint  s_view_size = 2;
	static const glw::GLuint  s_xfb_count = 3;
	static const glw::GLfloat s_colours[s_xfb_count][4];

	deqp::Context& m_context;
	glw::GLuint	m_program_id_xfb;
	glw::GLuint	m_program_id_draw;
	glw::GLuint	m_xfb_id[s_xfb_count];
	glw::GLuint	m_bo_id[s_xfb_count];
	glw::GLuint	m_fbo_id;
	glw::GLuint	m_rbo_id;
	glw::GLuint	m_vao_id;

	void prepare(glw::GLenum capture_mode);
	void bindXFB(glw::GLuint xfb_id);
	void bindVAO(glw::GLuint vao_id);
	void bindBOForXFB(glw::GLenum capture_mode, glw::GLuint bo_id);
	void bindBOForDraw(glw::GLuint program_id, glw::GLenum capture_mode, glw::GLuint bo_id);
	void useProgram(glw::GLuint program_id);
	void useColour(glw::GLuint program_id, glw::GLfloat r, glw::GLfloat g, glw::GLfloat b, glw::GLfloat a);
	void useGeometrySet(glw::GLuint program_id, bool invert_sign);
	void drawForCapture(bool begin_xfb, bool pause_xfb, bool resume_xfb, bool end_xfb);
	void drawToFramebuffer(glw::GLuint xfb_id);
	bool checkFramebuffer(glw::GLfloat r, glw::GLfloat g, glw::GLfloat b, glw::GLfloat a);
	bool inspectXFBState(bool shall_be_paused, bool shall_be_active);
	void clean();
};

/** DrawXFBFeedback
 *
 *  Verifies that data captured with XFB can be used as source for next capture.
 *
 *  Test should be executed if ARB_transform_feedback2 is supported or context
 *  is at least 4.0.
 *
 *  Steps:
 *  - prepare program consisting of vertex shader which pass position from input
 *    attribute to gl_Position multiplying it by 2.0;
 *  - instruct implementation to capture geometry in interleaved mode;
 *  - prepare source buffer;
 *  - prepare buffer to capture geometry;
 *  - begin transform feedback;
 *  - draw one vertex using DrawArrays;
 *  - end transform feedback;
 *  - swap buffer
 *  - begin transform feedback;
 *  - draw using DrawTransformFeedback;
 *  - end transform feedback;
 *  - swap buffer
 *  - begin transform feedback;
 *  - draw using DrawTransformFeedback;
 *  - end transform feedback;
 *  - map last captured buffer, expect position vector multiplied by value 8;
 */
class DrawXFBFeedback : public deqp::TestCase
{
public:
	DrawXFBFeedback(deqp::Context& context, const char* test_name, const char* test_description);
	~DrawXFBFeedback(void);
	virtual IterateResult iterate(void);

protected:
	static const glw::GLchar* s_vertex_shader;
	static const glw::GLchar* s_fragment_shader;
	static const glw::GLchar* s_xfb_varying;
	static const glw::GLchar* s_attrib;
	static const glw::GLuint  s_draw_vertex_count;
	static const glw::GLfloat s_initial_data[];
	static const glw::GLuint  s_bo_count = 2;
	static const glw::GLuint  s_bo_size;

	deqp::Context& m_context;
	glw::GLuint	m_program_id;
	glw::GLuint	m_vao_id[s_bo_count];
	glw::GLuint	m_xfb_id;
	glw::GLuint	m_bo_id[s_bo_count];
	glw::GLuint	m_source_bo_index;

	void prepareAndBind();
	void draw(bool is_first_draw);
	void swapBuffers();
	bool check();
	void clean();
};

/** DrawXFBStream
 *
 *  Verifies that vertex stream captured with transform feedback can be used to
 *  draw.
 *
 *  Test should be executed if both ARB_transform_feedback3 and ARB_gpu_shader5
 *  are supported or context is at least 4.0.
 *  This test is not supported if MAX_VERTEX_STREAMS is less than 2.
 *
 *  Steps:
 *  - prepare program consisting of vertex and geometry shaders; Geometry shader
 *    should output full-screen quad made of two triangles; First triangle should
 *    be emitted to first vertex stream; Second triangle should be emitted to the
 *    second vertex stream; Vertex shader can be blank;
 *  - prepare buffers to capture geometry;
 *  - instruct implementation to capture geometry in interleaved mode;
 *  - begin XFB;
 *  - begin indexed query for PRIMITIVES_GENERATED and
 *    TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN for both vertex streams;
 *  - draw single vertex;
 *  - end queries;
 *  - end XFB;
 *  - inspect results of queries;
 *  - prepare program consisting of vertex and fragment shaders; Vertex stage
 *    should pass position from input to output; Fragment shader should output
 *    white color;
 *  - prepare and clean framebuffer;
 *  - set vertex array layout to match data captured by XFB;
 *  - execute DrawTransformFeedbackStream to draw triangle from first stream;
 *  - execute DrawTransformFeedbackStream to draw triangle from second stream;
 *  - inspect contents of framebuffer, it is expected to be filled with white
 *    color.
 */
class DrawXFBStream : public deqp::TestCase
{
public:
	DrawXFBStream(deqp::Context& context, const char* test_name, const char* test_description);
	~DrawXFBStream(void);
	virtual IterateResult iterate(void);

private:
	static const glw::GLchar* s_vertex_shader_pass;
	static const glw::GLchar* s_vertex_shader_blank;
	static const glw::GLchar* s_geometry_shader;
	static const glw::GLchar* s_fragment_shader;
	static const glw::GLchar* s_xfb_varyings[];
	static const glw::GLuint  s_xfb_varyings_count;
	static const glw::GLuint  s_bo_ids_count = 2;
	static const glw::GLuint  s_qo_ids_count = 4;
	static const glw::GLuint  s_bo_size;
	static const glw::GLuint  s_view_size;

	deqp::Context& m_context;
	glw::GLuint	m_program_id_generate;
	glw::GLuint	m_program_id_draw;
	glw::GLuint	m_vao_id;
	glw::GLuint	m_xfb_id;
	glw::GLuint	m_bo_id[s_bo_ids_count];
	glw::GLuint	m_fbo_id;
	glw::GLuint	m_rbo_id;
	glw::GLuint	m_qo_id[s_qo_ids_count];

	void prepareObjects();
	void setupVertexArray(glw::GLuint bo_id);
	void useProgram(glw::GLuint program_id);
	void drawForXFB();
	bool inspectQueries();
	void drawForFramebuffer(glw::GLuint stream);
	bool check();
	void clean();
};

/** CaptureSpecialInterleaved
 *
 *  Verifies that special variable names are respected.
 *
 *  Test should be executed if ARB_transform_feedback3 is supported or context
 *  is at least 4.0.
 *
 *  Steps:
 *  - prepare program consisting of vertex shader which outputs four variables;
 *  - set up XFB to capture the following <varyings>:
 *    * variable_1,
 *    * gl_SkipComponents4,
 *    * variable_2,
 *    * gl_NextBuffer,
 *    * variable_3,
 *    * gl_SkipComponents4,
 *    * variable_4;
 *  - begin XFB;
 *  - draw two vertices;
 *  - end XFB;
 *  - verify that captured geometry is correct.
 */
class CaptureSpecialInterleaved : public deqp::TestCase
{
public:
	CaptureSpecialInterleaved(deqp::Context& context, const char* test_name, const char* test_description);
	~CaptureSpecialInterleaved(void);
	virtual IterateResult iterate(void);

private:
	static const glw::GLchar* s_vertex_shader;
	static const glw::GLchar* s_fragment_shader;
	static const glw::GLchar* s_xfb_varyings[];
	static const glw::GLuint  s_xfb_varyings_count;
	static const glw::GLuint  s_bo_ids_count = 2;
	static const glw::GLuint  s_bo_size;

	deqp::Context& m_context;
	glw::GLuint	m_program_id;
	glw::GLuint	m_vao_id;
	glw::GLuint	m_xfb_id;
	glw::GLuint	m_bo_id[s_bo_ids_count];

	void prepareAndBind();
	void draw();
	bool check();
	void clean();
};

/** DrawXFBInstanced
 *
 *  Verifies that transform feedback objects can used with instanced draws.
 *
 *  Test should be executed if context is at least 3.1 and either
 *  ARB_transform_feedback_instanced is supported or context is at least 4.2.
 *
 *  Steps:
 *  - prepare program consisting of vertex shader which outputs positions of
 *    full-screen quad made of triangle strip based on gl_VertexID;
 *  - instruct implementation to capture geometry in interleaved mode;
 *  - prepare buffer to capture geometry;
 *  - begin transform feedback;
 *  - draw four vertices;
 *  - end transform feedback;
 *  - prepare program consisting of vertex and fragment shaders; Vertex stage
 *    should calculate position as follows:
 *
 *    gl_Position = in_position * uni_matrices[gl_InstanceID];
 *
 *  Fragment shader should output white color;
 *  - prepare UNIFORM_BUFFER filled with four mat4; Select data so matrices
 *    transforms quad [-1, -1] : [1, 1] as follows:
 *    * 0 - [-1,  0] : [0, 1] - left top,
 *    * 1 - [ 0,  0] : [1, 1] - right top,
 *    * 2 - [-1, -1] : [0, 0] - left bottom,
 *    * 3 - [ 0, -1] : [1, 0] - right bottom;
 *  - prepare and clean framebuffer;
 *  - set up layout of vertex data in XFB;
 *  - execute DrawTransformFeedbackInstanced to draw four instances of quad from XFB;
 *  - it is expected that framebuffer is filled with white color;
 */
class DrawXFBInstanced : public deqp::TestCase
{
public:
	DrawXFBInstanced(deqp::Context& context, const char* test_name, const char* test_description);
	~DrawXFBInstanced(void);
	virtual IterateResult iterate(void);

private:
	static const glw::GLchar* s_vertex_shader_generate;
	static const glw::GLchar* s_vertex_shader_draw;
	static const glw::GLchar* s_fragment_shader;
	static const glw::GLchar* s_xfb_varying;
	static const glw::GLchar* s_uniform;
	static const glw::GLuint  s_bo_xfb_size;
	static const glw::GLfloat s_bo_uniform_data[];
	static const glw::GLuint  s_bo_uniform_size;
	static const glw::GLuint  s_view_size;

	deqp::Context& m_context;
	glw::GLuint	m_program_id_generate;
	glw::GLuint	m_program_id_draw;
	glw::GLuint	m_vao_id;
	glw::GLuint	m_xfb_id;
	glw::GLuint	m_bo_id_xfb;
	glw::GLuint	m_bo_id_uniform;
	glw::GLuint	m_fbo_id;
	glw::GLuint	m_rbo_id;

	void prepareObjects();
	void drawForXFB();
	void drawInstanced();
	bool check();
	void clean();

	typedef GLW_APICALL glw::GLuint (GLW_APIENTRY *GetUniformBlockIndex_ProcAddress)(glw::GLuint program, const glw::GLchar* uniformBlockName);
	typedef GLW_APICALL void        (GLW_APIENTRY *UniformBlockBinding_ProcAddress)(glw::GLuint program,
																					glw::GLuint uniformIndex,
																					glw::GLuint uniformBlockBinding);

	GetUniformBlockIndex_ProcAddress m_glGetUniformBlockIndex;
	UniformBlockBinding_ProcAddress  m_glUniformBlockBinding;
};

/** DrawXFBStreamInstanced
 *
 *  Verifies that transform feedback objects can used with instanced draws.
 *
 *  Test should be executed if context is at least 3.1 and either
 *  ARB_gpu_shader5 is supported or context is at least 4.0 and either
 *  ARB_transform_feedback_instanced is supported or context is at least 4.2.
 *
 *  Steps:
 *  - prepare program consisting of vertex shader which based on gl_VertexID
 *    outputs:
 *     * to stream 0 - color,
 *     * to stream 1 - positions
 *    for a full-screen quad made of triangle strip;
 *  - instruct implementation to capture geometry in interleaved mode;
 *  - prepare buffers to capture geometry;
 *  - begin transform feedback;
 *  - draw four vertices;
 *  - end transform feedback;
 *  - prepare program consisting of vertex and fragment shaders; Vertex stage
 *    should calculate position as follows:
 *
 *      gl_Position = in_position * uni_matrices[gl_InstanceID];
 *
 *  Fragment shader should output white color;
 *  - prepare UNIFORM_BUFFER filled with four mat4; Select data so matrices
 *    transforms quad [-1, -1] : [1, 1] as follows:
 *     * 0 - [-1,  0] : [0, 1] - left top,
 *     * 1 - [ 0,  0] : [1, 1] - right top,
 *     * 2 - [-1, -1] : [0, 0] - left bottom,
 *     * 3 - [ 0, -1] : [1, 0] - right bottom;
 *  - prepare and clean framebuffer;
 *  - set up layout of vertex data in XFB;
 *  - execute DrawTransformFeedbackStreamInstanced to draw four instances of
 *    quad from XFB, stream 1;
 *  - it is expected that framebuffer is filled with white color;
 */
class DrawXFBStreamInstanced : public deqp::TestCase
{
public:
	DrawXFBStreamInstanced(deqp::Context& context, const char* test_name, const char* test_description);
	~DrawXFBStreamInstanced(void);
	virtual IterateResult iterate(void);

private:
	static const glw::GLchar* s_vertex_shader_blank;
	static const glw::GLchar* s_geometry_shader_generate;
	static const glw::GLchar* s_vertex_shader_draw;
	static const glw::GLchar* s_fragment_shader_blank;
	static const glw::GLchar* s_fragment_shader_draw;
	static const glw::GLchar* s_xfb_varyings[];
	static const glw::GLuint  s_xfb_varyings_count;
	static const glw::GLchar* s_uniform;
	static const glw::GLuint  s_bo_xfb_size;
	static const glw::GLfloat s_bo_uniform_data[];
	static const glw::GLuint  s_bo_uniform_size;
	static const glw::GLuint  s_view_size;

	deqp::Context& m_context;
	glw::GLuint	m_program_id_generate;
	glw::GLuint	m_program_id_draw;
	glw::GLuint	m_vao_id;
	glw::GLuint	m_xfb_id;
	glw::GLuint	m_bo_id_xfb_position;
	glw::GLuint	m_bo_id_xfb_color;
	glw::GLuint	m_bo_id_uniform;
	glw::GLuint	m_fbo_id;
	glw::GLuint	m_rbo_id;

	void prepareObjects();
	void drawForXFB();
	void drawStreamInstanced();
	bool check();
	void clean();

	typedef GLW_APICALL glw::GLuint (GLW_APIENTRY *GetUniformBlockIndex_ProcAddress)(glw::GLuint program, const glw::GLchar* uniformBlockName);
	typedef GLW_APICALL void        (GLW_APIENTRY *UniformBlockBinding_ProcAddress)(glw::GLuint program,
																					glw::GLuint uniformIndex,
																					glw::GLuint uniformBlockBinding);

	GetUniformBlockIndex_ProcAddress m_glGetUniformBlockIndex;
	UniformBlockBinding_ProcAddress  m_glUniformBlockBinding;
};

namespace Utilities
{
/** Build a GLSL program
 *
 *  @param [in]  gl                                     OpenGL Functions Access.
 *  @param [in]  log                                    Log outut.
 *  @param [in]  geometry_shader_source                 Pointer to C string of the geometry shader or NULL if not used.
 *  @param [in]  tessellation_control_shader_source     Pointer to C string of the tessellation control shader or NULL if not used.
 *  @param [in]  tessellation_evaluation_shader_source  Pointer to C string of the tessellation evaluation shader or NULL if not used.
 *  @param [in]  vertex_shader_source                   Pointer to C string of the vertex shader or NULL if not used.
 *  @param [in]  geometry_shader_source                 Pointer to C string of the fragment shader or NULL if not used.
 *  @param [in]  transform_feedback_varyings            C array of transform feedback varyings names.
 *  @param [in]  transform_feedback_varyings_count      Count of transform feedback varyings names.
 *  @param [in]  transform_feedback_varyings_mode       Transform feedback capture mode - GL_SEPARATE_ATTRIBS or GL_INTERLEAVED_ATTRIBS.
 *  @param [in]  do_not_detach                          Do not detach shaders - default is faulse.
 *  @param [out] linking_status                         Return pointer to store linking status or NULL if not needed.
 *
 *  @return OpenGL program shader ID or zero if error had occured.
 */
glw::GLuint buildProgram(glw::Functions const& gl, tcu::TestLog& log, glw::GLchar const* const geometry_shader_source,
						 glw::GLchar const* const tessellation_control_shader_source,
						 glw::GLchar const* const tessellation_evaluation_shader_source,
						 glw::GLchar const* const vertex_shader_source, glw::GLchar const* const fragment_shader_source,
						 glw::GLchar const* const* const transform_feedback_varyings,
						 glw::GLsizei const				 transform_feedback_varyings_count,
						 glw::GLenum const transform_feedback_varyings_mode, bool const do_not_detach = false,
						 glw::GLint* linking_status = DE_NULL);

/** Preprocess source string by replacing key tokens with new values.
 *
 *  @param [in] source      Source string.
 *  @param [in] key         Key, substring to be replaced.
 *  @param [in] value       Value, substring to be substituted in place of key.
 *
 *  @return Preprocessed string.
 */
std::string preprocessCode(std::string source, std::string key, std::string value);

/** Change integer number to string
 *
 *  @param [in] i       Integer number.
 *
 *  @return String represnting integer number.
 */
std::string itoa(glw::GLint i);

/** Change floating point number to string
 *
 *  @param [in] f       Floating point number.
 *
 *  @return String represnting floating point number.
 */
std::string ftoa(glw::GLfloat f);
} /* Utilities namespace */
} /* TransformFeedback namespace */

} /* gl3cts namespace */

#endif // _GL3CTRANSFORMFEEDBACKTESTS_HPP
