Home | History | Annotate | Download | only in gl
      1 #ifndef _GL3CTRANSFORMFEEDBACKTESTS_HPP
      2 #define _GL3CTRANSFORMFEEDBACKTESTS_HPP
      3 /*-------------------------------------------------------------------------
      4  * OpenGL Conformance Test Suite
      5  * -----------------------------
      6  *
      7  * Copyright (c) 2015-2016 The Khronos Group Inc.
      8  *
      9  * Licensed under the Apache License, Version 2.0 (the "License");
     10  * you may not use this file except in compliance with the License.
     11  * You may obtain a copy of the License at
     12  *
     13  *      http://www.apache.org/licenses/LICENSE-2.0
     14  *
     15  * Unless required by applicable law or agreed to in writing, software
     16  * distributed under the License is distributed on an "AS IS" BASIS,
     17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     18  * See the License for the specific language governing permissions and
     19  * limitations under the License.
     20  *
     21  */ /*!
     22  * \file
     23  * \brief
     24  */ /*-------------------------------------------------------------------*/
     25 
     26 /**
     27  */ /*!
     28  * \file  gl3cTransformFeedback.hpp
     29  * \brief Transform Feedback Test Suite Interface
     30  */ /*-------------------------------------------------------------------*/
     31 
     32 #include "glcTestCase.hpp"
     33 #include "glwDefs.hpp"
     34 #include "tcuDefs.hpp"
     35 
     36 /* Includes. */
     37 #include <map>
     38 #include <string>
     39 #include <typeinfo>
     40 #include <vector>
     41 
     42 #include "glwEnums.hpp"
     43 #include "glwFunctions.hpp"
     44 
     45 namespace gl3cts
     46 {
     47 namespace TransformFeedback
     48 {
     49 class Tests : public deqp::TestCaseGroup
     50 {
     51 public:
     52 	Tests(deqp::Context& context);
     53 	~Tests(void);
     54 	virtual void init(void);
     55 
     56 private:
     57 	Tests(const Tests& other);
     58 	Tests& operator=(const Tests& other);
     59 };
     60 
     61 /** APIErrors
     62  *
     63  *  Verifies if errors are generated as specified.
     64  *  Four test shall be run:
     65  *   - Test api errors defined in GL_EXT_transform_feedback.
     66  *   - Test api errors defined in GL_ARB_transform_feedback2.
     67  *   - Test api errors defined in GL_ARB_transform_feedback3.
     68  *   - Test api errors defined in GL_ARB_transform_feedback_instanced.
     69  */
     70 class APIErrors : public deqp::TestCase
     71 {
     72 public:
     73 	APIErrors(deqp::Context& context);
     74 	~APIErrors(void);
     75 	IterateResult iterate(void);
     76 
     77 private:
     78 	deqp::Context& m_context;
     79 
     80 	static const glw::GLchar* m_tessellation_control_shader;
     81 	static const glw::GLchar* m_tessellation_evaluation_shader;
     82 	static const glw::GLchar* m_geometry_shader;
     83 	static const glw::GLchar* s_vertex_shader_with_input_output;
     84 	static const glw::GLchar* s_vertex_shader_with_output;
     85 	static const glw::GLchar* s_vertex_shader_without_output;
     86 	static const glw::GLchar* s_fragment_shader;
     87 	static const glw::GLchar* m_varying_name;
     88 
     89 	static const glw::GLfloat m_buffer_1_data[];
     90 	static const glw::GLsizei m_buffer_1_size;
     91 
     92 	glw::GLuint m_buffer_0;
     93 	glw::GLuint m_buffer_1;
     94 
     95 	glw::GLuint m_vertex_array_object;
     96 
     97 	glw::GLuint m_transform_feedback_object_0;
     98 	glw::GLuint m_transform_feedback_object_1;
     99 
    100 	glw::GLuint m_query_object;
    101 
    102 	glw::GLuint m_program_id_with_input_output;
    103 	glw::GLuint m_program_id_with_output;
    104 	glw::GLuint m_program_id_without_output;
    105 	glw::GLuint m_program_id_with_geometry_shader;
    106 	glw::GLuint m_program_id_with_tessellation_shaders;
    107 
    108 	/** Check the following if EXT_transform_feedback is supported or context is
    109 	 *  at least 3.0:
    110 	 *
    111 	 *  - INVALID_VALUE is generated by BindBufferRange, BindBufferOffset and
    112 	 *    BindBufferBase when <index> is greater or equal to
    113 	 *    MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS;
    114 	 *  - INVALID_VALUE is generated by BindBufferRange and BindBufferOffset
    115 	 *    when <size> is less or equal to zero;
    116 	 *  - INVALID_VALUE is generated by BindBufferRange and BindBufferOffset
    117 	 *    when <offset> is not word-aligned;
    118 	 *  - INVALID_VALUE is generated by BindBufferRange and BindBufferOffset
    119 	 *    when <size> is not word-aligned;
    120 	 *  - INVALID_OPERATION is generated by BindBufferRange, BindBufferOffset and
    121 	 *    BindBufferBase when <target> is TRANSFORM_FEEDBACK_BUFFER and transform
    122 	 *    feedback is active;
    123 	 *  - INVALID_OPERATION is generated by UseProgram when transform feedback is
    124 	 *    active;
    125 	 *  - INVALID_OPERATION is generated by LinkProgram when <program> is currently
    126 	 *    active and transform feedback is active;
    127 	 *  - INVALID_OPERATION is generated by BeginTransformFeedback when transform
    128 	 *    feedback is active;
    129 	 *  - INVALID_OPERATION is generated by EndTransformFeedback when transform
    130 	 *    feedback is inactive;
    131 	 *  - INVALID_OPERATION is generated by draw command when generated primitives
    132 	 *    type does not match <primitiveMode>;
    133 	 *  - INVALID_OPERATION is generated by BeginTransformFeedback when any binding
    134 	 *    point used by XFB does not have buffer bound;
    135 	 *  - INVALID_OPERATION is generated by BeginTransformFeedback when no program
    136 	 *    is active;
    137 	 *  - INVALID_OPERATION is generated by BeginTransformFeedback when no variable
    138 	 *    are specified to be captured in the active program;
    139 	 *  - INVALID_VALUE is generated by TransformFeedbackVaryings when <program> is
    140 	 *    not id of the program object;
    141 	 *  - INVALID_VALUE is generated by TransformFeedbackVaryings when <bufferMode>
    142 	 *    is SEPARATE_ATTRIBS and <count> is exceeds limits;
    143 	 *  - IVALID_VALUE is generated by GetTransformFeedbackVarying when <index> is
    144 	 *    greater than or equal to TRANSFORM_FEEDBACK_VARYINGS;
    145 	 *  - INVALID_VALUE is generated by GetIntegerIndexdv when <index> exceeds the
    146 	 *    limits of MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS and <param> is one of the
    147 	 *    following:
    148 	 *    * TRANSFORM_FEEDBACK_BUFFER_BINDING,
    149 	 *    * TRANSFORM_FEEDBACK_BUFFER_START,
    150 	 *    * TRANSFORM_FEEDBACK_BUFFER_SIZE;
    151 	 *  - INVALID_VALUE is generated by GetBooleanIndexedv when <index> exceeds the
    152 	 *    limits of MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS and <param> is
    153 	 *    TRANSFORM_FEEDBACK_BUFFER_BINDING.
    154 	 */
    155 	bool testExtension1(void);
    156 
    157 	/** Check the following if ARB_transform_feedback2 is supported or context is
    158 	 *  at least 4.0:
    159 	 *
    160 	 *  - INVALID_OPERATION is generated by BindTransformFeedback if current
    161 	 *    transform feedback is active and not paused;
    162 	 *  - INVALID_OPERATION is generated by DeleteTransformFeedbacks if any of <ids>
    163 	 *    is active;
    164 	 *  - INVALID_OPERATION is generated by PauseTransformFeedback if current
    165 	 *    transform feedback is not active or paused;
    166 	 *  - INVALID_OPERATION is generated by ResumeTransformFeedback if current
    167 	 *    transform feedback is not active or not paused;
    168 	 *  - No error is generated by draw command when transform feedback is paused
    169 	 *    and primitive modes do not match;
    170 	 *  - No error is generated by UseProgram when transform feedback is paused;
    171 	 *  - INVALID_OPERATION is generated by LinkProgram when <program> is used by
    172 	 *    some transform feedback object that is currently not active;
    173 	 *  - INVALID_VALUE is generated by DrawTransformFeedback if <id> is not name of
    174 	 *    transform feedback object;
    175 	 *  - INVALID_OPERATION is generated by DrawTransformFeedback when
    176 	 *    EndTransformFeedback was never called for the object named <id>.
    177 	 */
    178 	bool testExtension2(void);
    179 
    180 	/** Check the following if ARB_transform_feedback3 is supported or context is
    181 	 *  at least 4.0:
    182 	 *
    183 	 *  - INVALID_VALUE is generated by BeginQueryIndexed, EndQueryIndexed and
    184 	 *    GetQueryIndexediv when <target> is TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN and
    185 	 *    <index> exceeds limits of MAX_VERTEX_STREAMS;
    186 	 *  - INVALID_VALUE is generated by BeginQueryIndexed, EndQueryIndexed and
    187 	 *    GetQueryIndexediv when <target> is PRIMITIVES_GENERATED and <index> exceeds
    188 	 *    limits of MAX_VERTEX_STREAMS;
    189 	 *  - INVALID_OPERATION is generated by EndQueryIndexed when name of active
    190 	 *    query at <index> of <target> is zero;
    191 	 *  - INVALID_VALUE is generated by DrawTransformFeedbackStream when <stream>
    192 	 *    exceeds limits of MAX_VERTEX_STREAMS;
    193 	 *  - INVALID_OPERATION is generated by TransformFeedbackVaryings when
    194 	 *    <varyings> contains any of the special names while <bufferMode> is not
    195 	 *    INTERLEAVED_ATTRIBS;
    196 	 *  - INVALID_OPERATION is generated by TransformFeedbackVaryings when
    197 	 *    <varyings> contains more "gl_NextBuffer" entries than allowed limit of
    198 	 *    MAX_TRANSFORM_FEEDBACK_BUFFERS;
    199 	 */
    200 	bool testExtension3(void);
    201 
    202 	/** Check the following if ARB_transform_feedback_instanced is supported or
    203 	 *  context is at least 4.2:
    204 	 *
    205 	 *  - INVALID_ENUM is generated by DrawTransformFeedbackInstanced and
    206 	 *    DrawTransformFeedbackStreamInstanced if <mode> is invalid;
    207 	 *  - INVALID_OPERATION is generated by DrawTransformFeedbackInstanced and
    208 	 *    DrawTransformFeedbackStreamInstanced if <mode> does not match geometry
    209 	 *    shader;
    210 	 *  - INVALID_OPERATION is generated by DrawTransformFeedbackInstanced and
    211 	 *    DrawTransformFeedbackStreamInstanced if <mode> does not match tessellation;
    212 	 *  - INVALID_VALUE is generated by DrawTransformFeedbackStreamInstanced if
    213 	 *    <stream> is greater than or equal to MAX_VERTEX_STREAMS;
    214 	 *  - INVALID_VALUE is generated by DrawTransformFeedbackInstanced and
    215 	 *    DrawTransformFeedbackStreamInstanced if <id> is not name of transform
    216 	 *    feedback object;
    217 	 *  - INVALID_OPERATION is generated by DrawTransformFeedbackInstanced and
    218 	 *    DrawTransformFeedbackStreamInstanced if a non-zero buffer object name is
    219 	 *    bound to an enabled array and the buffer object's data store is currently
    220 	 *    mapped;
    221 	 *  - INVALID_OPERATION is generated if by DrawTransformFeedbackStreamInstanced
    222 	 *    if EndTransformFeedback was never called for the object named <id>.
    223 	 */
    224 	bool testInstanced(void);
    225 
    226 	typedef void (*BindBufferOffsetEXT_ProcAddress)(glw::GLenum target, glw::GLuint index, glw::GLuint buffer,
    227 													glw::GLintptr offset);
    228 	typedef void (*GetIntegerIndexedvEXT_ProcAddress)(glw::GLenum param, glw::GLuint index, glw::GLint* values);
    229 	typedef void (*GetBooleanIndexedvEXT_ProcAddress)(glw::GLenum param, glw::GLuint index, glw::GLboolean* values);
    230 
    231 	BindBufferOffsetEXT_ProcAddress   m_glBindBufferOffsetEXT;
    232 	GetIntegerIndexedvEXT_ProcAddress m_glGetIntegerIndexedvEXT;
    233 	GetBooleanIndexedvEXT_ProcAddress m_glGetBooleanIndexedvEXT;
    234 };
    235 
    236 /** LinkingErrors
    237  *
    238  *  Verifies that linker reports errors as specified.
    239  *
    240  *  Test should be run if EXT_transform_feedback is supported or context is
    241  *  at least 3.0.
    242  *
    243  *  Check if link process fails under the following conditions:
    244  *  - <count> specified by TransformFeedbackVaryings is non-zero and program has
    245  *    neither vertex nor geometry shader;
    246  *  - <varyings> specified by TransformFeedbackVaryings contains name of
    247  *    variable that is not available for capture;
    248  *  - <varyings> specified by TransformFeedbackVaryings contains name of
    249  *    variable more than once;
    250  *  - number of components specified to capture exceeds limits
    251  *    MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS or
    252  *    MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS.
    253  */
    254 class LinkingErrors : public deqp::TestCase
    255 {
    256 public:
    257 	LinkingErrors(deqp::Context& context);
    258 	~LinkingErrors(void);
    259 	IterateResult iterate(void);
    260 
    261 private:
    262 	deqp::Context& m_context;
    263 
    264 	static const glw::GLchar* s_fragment_shader;
    265 	static const glw::GLchar* s_vertex_shader_template;
    266 	static const glw::GLchar* s_valid_transform_feedback_varying;
    267 	static const glw::GLchar* s_invalid_transform_feedback_varying;
    268 	static const glw::GLchar* s_repeated_transform_feedback_varying[];
    269 	static const glw::GLsizei s_repeated_transform_feedback_varying_count;
    270 
    271 	bool testNoVertexNoGeometry(void);
    272 	bool testInvalidVarying(void);
    273 	bool testRepeatedVarying(void);
    274 	bool testTooManyVaryings(void);
    275 };
    276 
    277 /** Limits
    278  *
    279  *  Verifies that limits reported by API are as expected.
    280  *
    281  *  Check the following if EXT_transform_feedback is supported or context is at
    282  *  least 3.0:
    283  *  - MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS is at least 64,
    284  *  - MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS is at least 4,
    285  *  - MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS is at least 4.
    286  *
    287  *  Check the following if ARB_transform_feedback3 is supported or context is at
    288  *  least 4.0:
    289  *  - MAX_TRANSFORM_FEEDBACK_BUFFERS is at least 4,
    290  *  - MAX_VERTEX_STREAMS is at least 1.
    291  */
    292 class Limits : public deqp::TestCase
    293 {
    294 public:
    295 	Limits(deqp::Context& context);
    296 	~Limits(void);
    297 	IterateResult iterate(void);
    298 
    299 private:
    300 	deqp::Context& m_context;
    301 
    302 	static const glw::GLchar* s_fragment_shader;
    303 	static const glw::GLchar* s_vertex_shader;
    304 
    305 	static const glw::GLint s_min_value_of_max_transform_feedback_interleaved_components;
    306 	static const glw::GLint s_min_value_of_max_transform_feedback_separate_attribs;
    307 	static const glw::GLint s_min_value_of_max_transform_feedback_separate_components;
    308 	static const glw::GLint s_min_value_of_max_transform_feedback_buffers;
    309 	static const glw::GLint s_min_value_of_max_vertex_streams;
    310 
    311 	bool test_max_transform_feedback_interleaved_components(void);
    312 	bool test_max_transform_feedback_separate_attribs(void);
    313 	bool test_max_transform_feedback_separate_components(void);
    314 	bool test_max_transform_feedback_buffers(void);
    315 	bool test_max_vertex_streams(void);
    316 };
    317 
    318 /** CaptureVertexInterleaved
    319  *
    320  *  Verifies if geometry processed with vertex shader is captured as expected in
    321  *  interleaved mode.
    322  *
    323  *  Test should be run if EXT_transform_feedback is supported or context is
    324  *  at least 3.0.
    325  *
    326  *  Steps:
    327  *  - prepare program consisting of vertex and fragment shader; Vertex shader
    328  *    should assign all MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS components;
    329  *    One of the variables must be a position; Position should be set to one of
    330  *    corners, based on gl_VertexID: 0 - top left, 1 - top right, 2 - bottom left
    331  *    and 3 - bottom right; Rest of components should be covered with output
    332  *    variables of type vec4; Fragment shader should accept all outputs from
    333  *    vertex shader as inputs and use them to calculate non-black output color;
    334  *  - instruct implementation to capture all outputs defined by vertex shader;
    335  *    Use interleaved mode;
    336  *  - prepare and set buffer to store captured geometry;
    337  *  - prepare, set and clean frame-buffer with black color;
    338  *  - execute BeginTransformFeedback;
    339  *  - execute DrawElements;
    340  *  - execute EndTransformFeedback;
    341  *  - inspect contents of frame-buffer to check if rasterization was done
    342  *    correctly;
    343  *  - inspect TRANSFORM_FEEDBACK_BUFFER_START and
    344  *    TRANSFORM_FEEDBACK_BUFFER_SIZE;
    345  *  - inspect contents of the buffer to check if geometry was captured
    346  *    correctly.
    347  *
    348  *  Test the following BindBuffer routines:
    349  *  - BindBufferRange - use non-zero offset,
    350  *  - BindBufferOffset - use non-zero offset,
    351  *  - BindBufferBase.
    352  *
    353  *  Test the following primitive types:
    354  *  - GL_POINTS - use these indices: [0, 1, 2, 3]; All corner pixels should be
    355  *    set to specific colors; XFB should contain four vertices;
    356  *  - GL_LINES - use these indices: [0, 1, 2, 3]; Top and bottom edges should be
    357  *    drawn; XFB should contain four vertices;
    358  *  - GL_LINE_LOOP - use these indices: [0, 1, 3, 2]; All four edges should be
    359  *    drawn; XFB should contain eight vertices;
    360  *  - GL_LINE_STRIP - use these indices: [0, 1, 3, 2]; Top, right and bottom
    361  *    edge should be drawn; XFB should contain six vertices;
    362  *  - GL_TRIANGLES - use these indices: [2, 0, 1, 2, 1, 3]; Whole image should
    363  *    be drawn; XFB should contain six vertices;
    364  *  - GL_TRIANGLE_STRIP - use these indices: [0, 1, 2, 3]; Whole image should
    365  *    be drawn; XFB should contain six vertices;
    366  *  - GL_TRIANGLE_FAN - use these indices: [2, 0, 1, 3]; Whole image should
    367  *    be drawn; XFB should contain six vertices.
    368  *
    369  *  Number of components that can be passed to rasterization must not exceed
    370  *  MAX_VARYING_COMPONENTS.
    371  */
    372 class CaptureVertexInterleaved : public deqp::TestCase
    373 {
    374 public:
    375 	CaptureVertexInterleaved(deqp::Context& context, const char* test_name, const char* test_description);
    376 	~CaptureVertexInterleaved(void);
    377 	virtual IterateResult iterate(void);
    378 
    379 protected:
    380 	deqp::Context& m_context;
    381 	glw::GLuint	m_program;
    382 	glw::GLuint	m_framebuffer;
    383 	glw::GLuint	m_renderbuffer;
    384 	glw::GLuint	m_buffer;
    385 	glw::GLuint	m_buffer_size;
    386 	glw::GLuint	m_vertex_array_object;
    387 	glw::GLint	 m_max_transform_feedback_components;
    388 	glw::GLenum	m_attrib_type;
    389 	glw::GLuint	m_max_vertices_drawn;
    390 
    391 	typedef void (*BindBufferOffsetEXT_ProcAddress)(glw::GLenum target, glw::GLuint index, glw::GLuint buffer,
    392 													glw::GLintptr offset);
    393 
    394 	BindBufferOffsetEXT_ProcAddress m_glBindBufferOffsetEXT;
    395 
    396 	static const glw::GLchar* s_vertex_shader_source_code_template;
    397 	static const glw::GLchar* s_fragment_shader_source_code;
    398 
    399 	static const glw::GLuint  s_max_element_indices_count = 6;
    400 	static const glw::GLuint  s_element_indices[][s_max_element_indices_count];
    401 	static const glw::GLuint  s_primitive_cases_count;
    402 	static const glw::GLuint  s_element_indices_counts[];
    403 	static const glw::GLenum  s_primitive_cases[];
    404 	static const glw::GLenum  s_primitive_cases_xfb[];
    405 	static const glw::GLuint  s_framebuffer_size;
    406 	static const glw::GLfloat s_rasterization_epsilon;
    407 	static const glw::GLuint  s_max_vertex_id = 4;
    408 
    409 	enum BindBufferCase
    410 	{
    411 		BIND_BUFFER_BASE_CASE,
    412 		BIND_BUFFER_RANGE_CASE,
    413 		BIND_BUFFER_OFFSET_CASE,
    414 		BIND_BUFFER_CASES_COUNT
    415 	};
    416 
    417 	virtual void fetchLimits(void);
    418 	virtual void buildProgram(void);
    419 	void		 createFramebuffer(void);
    420 	virtual void createTransformFeedbackBuffer(void);
    421 	void		 createVertexArrayObject(void);
    422 	virtual void draw(glw::GLuint primitive_case);
    423 	virtual bool checkFramebuffer(glw::GLuint primitive_case);
    424 	virtual bool checkTransformFeedbackBuffer(BindBufferCase bind_case, glw::GLenum primitive_type);
    425 	virtual void bindBuffer(BindBufferCase bind_case);
    426 	virtual void clean(void);
    427 	virtual void cleanBuffer(void);
    428 };
    429 
    430 /** CaptureGeometryInterleaved
    431  *
    432  *  Verifies if geometry processed with geometry shader is captured as expected
    433  *  in interleaved mode.
    434  *
    435  *  Test should be run if either EXT_transform_feedback is supported or context
    436  *  is at least 3.0 and either ARB_geometry_shader4 is supported or context is
    437  *  at least 3.2.
    438  *
    439  *  Modify CaptureVertexInterleaved test in the following aspects:
    440  *  - outputs definition and assignment is done in geometry instead of
    441  *    vertex shader;
    442  *  - vertex shader can be blank;
    443  *  - use DrawArrays instead of DrawElements, draw single vertex with GL_POINTS.
    444  *
    445  *  Test the following output primitive types for geometry shader:
    446  *  - points - emit vertices as in GL_POINTS case;
    447  *  - line_strip - emit vertices as in GL_LINE_STRIP case;
    448  *  - triangle_strip - emit vertices as in GL_TRIANGLE_STRIP case.
    449  *
    450  *  Number of components written by geometry shader must not exceed
    451  *  MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS.
    452  */
    453 class CaptureGeometryInterleaved : virtual public CaptureVertexInterleaved
    454 {
    455 public:
    456 	CaptureGeometryInterleaved(deqp::Context& context, const char* test_name, const char* test_description);
    457 	~CaptureGeometryInterleaved(void);
    458 	virtual IterateResult iterate(void);
    459 
    460 protected:
    461 	virtual void fetchLimits(void);
    462 	using CaptureVertexInterleaved::buildProgram;
    463 	virtual void buildProgram(glw::GLuint primitive_case);
    464 	virtual void draw(glw::GLuint primitive_case);
    465 
    466 	static const glw::GLchar* s_geometry_shader_source_code_template;
    467 	static const glw::GLchar* s_blank_vertex_shader_source_code;
    468 
    469 	static const glw::GLchar* s_geometry_interleaved_primitive_cases[];
    470 	static const glw::GLenum  s_geometry_interleaved_primitive_cases_xfb[];
    471 	static const glw::GLuint  s_geometry_interleaved_primitive_cases_count;
    472 };
    473 
    474 /** CaptureVertexSeparate
    475  *
    476  *  Verifies if geometry processed with vertex shader is captured as expected in
    477  *  separate mode.
    478  *
    479  *  Test should be run if EXT_transform_feedback is supported or context is
    480  *  at least 3.0.
    481  *
    482  *  Modify CaptureVertexInterleaved test in the following aspects:
    483  *  - use transform feedback in separate mode.
    484  *
    485  *  Separate mode require one buffer per captured variable.
    486  *
    487  *  Number of attributes and components that can be captured is limited by:
    488  *  - MAX TRANSFORM FEEDBACK SEPARATE ATTRIBS,
    489  *  - MAX TRANSFORM FEEDBACK SEPARATE COMPONENTS.
    490  */
    491 class CaptureVertexSeparate : virtual public CaptureVertexInterleaved
    492 {
    493 public:
    494 	CaptureVertexSeparate(deqp::Context& context, const char* test_name, const char* test_description);
    495 
    496 protected:
    497 	glw::GLuint* m_buffers;
    498 	glw::GLint   m_max_transform_feedback_separate_attribs;
    499 
    500 	virtual void fetchLimits(void);
    501 	virtual void createTransformFeedbackBuffer(void);
    502 	virtual void bindBuffer(BindBufferCase bind_case);
    503 	virtual void cleanBuffer(void);
    504 	virtual bool checkTransformFeedbackBuffer(BindBufferCase bind_case, glw::GLenum primitive_type);
    505 };
    506 
    507 /** CaptureGeometrySeparate
    508  *
    509  *  Verifies if geometry processed with geometry shader is captured as expected
    510  *  in separate mode.
    511  *
    512  *  Test should be run if either EXT_transform_feedback is supported or context
    513  *  is at least 3.0 and either ARB_geometry_shader4 is supported or context is
    514  *  at least 3.2.
    515  *
    516  *  Modify CaptureGeometryInterleaved test in the following aspects:
    517  *  - use transform feedback in separate mode.
    518  *
    519  *  Separate mode require one buffer per captured variable.
    520  *
    521  *  Number of attributes and components that can be captured is limited by:
    522  *  - MAX TRANSFORM FEEDBACK SEPARATE ATTRIBS,
    523  *  - MAX TRANSFORM FEEDBACK SEPARATE COMPONENTS.
    524  */
    525 class CaptureGeometrySeparate : public CaptureGeometryInterleaved, virtual public CaptureVertexSeparate
    526 {
    527 public:
    528 	CaptureGeometrySeparate(deqp::Context& context, const char* test_name, const char* test_description);
    529 	virtual IterateResult iterate(void)
    530 	{
    531 		return CaptureGeometryInterleaved::iterate();
    532 	};
    533 
    534 protected:
    535 	glw::GLuint* m_buffers;
    536 	glw::GLint   m_max_transform_feedback_separate_attribs;
    537 
    538 	virtual void draw(glw::GLenum primitive_type)
    539 	{
    540 		CaptureGeometryInterleaved::draw(primitive_type);
    541 	};
    542 	virtual void fetchLimits(void)
    543 	{
    544 		CaptureVertexSeparate::fetchLimits();
    545 	};
    546 	virtual void createTransformFeedbackBuffer(void)
    547 	{
    548 		CaptureVertexSeparate::createTransformFeedbackBuffer();
    549 	};
    550 	virtual void bindBuffer(BindBufferCase bind_case)
    551 	{
    552 		CaptureVertexSeparate::bindBuffer(bind_case);
    553 	};
    554 	virtual void cleanBuffer(void)
    555 	{
    556 		CaptureVertexSeparate::cleanBuffer();
    557 	};
    558 	virtual bool checkTransformFeedbackBuffer(BindBufferCase bind_case, glw::GLenum primitive_type)
    559 	{
    560 		return CaptureVertexSeparate::checkTransformFeedbackBuffer(bind_case, primitive_type);
    561 	};
    562 };
    563 
    564 /** GetXFBVaryingVertexInterleaved
    565  *
    566  *  Verifies if varyings captured from vertex stage are correctly reported in
    567  *  interleaved mode.
    568  *
    569  *  Test should be run if EXT_transform_feedback is supported or context is
    570  *  at least 3.0.
    571  *
    572  *  Steps:
    573  *  - prepare program consisting of vertex and fragment shader; Vertex shader
    574  *    should define and assign maximum allowed number of varyings of tested type;
    575  *    Fragment shader can be blank;
    576  *  - instruct implementation to capture all outputs defined by vertex shader;
    577  *    Use interleaved mode;
    578  *  - inspect all captured varying with GetTransformFeedbackVarying;
    579  *  - inspect TRANSFORM_FEEDBACK_VARYINGS;
    580  *  - inspect TRANSFORM_FEEDBACK_BUFFER_MODE;
    581  *  - inspect TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH.
    582  *
    583  *  Test all valid types.
    584  *
    585  *
    586  *  GetXFBVaryingGeometryInterleaved
    587  *
    588  *  Verifies if varyings captured from geometry stage are correctly reported in
    589  *  interleaved mode.
    590  *
    591  *  Test should be run if either EXT_transform_feedback is supported or context
    592  *  is at least 3.0 and either ARB_geometry_shader4 is supported or context is
    593  *  at least 3.2.
    594  *
    595  *  Modify GetXFBVaryingVertexInterleaved test in the following aspects:
    596  *  - outputs definition and assignment is done in geometry instead of
    597  *    vertex shader;
    598  *  - vertex shader can be blank;
    599  *
    600  *
    601  *  GetXFBVaryingVertexSeparate
    602  *
    603  *  Verifies if varyings captured from vertex stage are correctly reported in
    604  *  separate mode.
    605  *
    606  *  Test should be run if EXT_transform_feedback is supported or context is
    607  *  at least 3.0.
    608  *
    609  *  Modify CaptureGeometryInterleaved test in the following aspects:
    610  *  - use transform feedback in separate mode.
    611  *
    612  *  Separate mode require one buffer per captured variable.
    613  *
    614  *
    615  *  GetXFBVaryingGeometrySeparate
    616  *
    617  *  Verifies if varyings captured from geometry stage are correctly reported in
    618  *  separate mode.
    619  *
    620  *  Test should be run if either EXT_transform_feedback is supported or context
    621  *  is at least 3.0 and either ARB_geometry_shader4 is supported or context is
    622  *  at least 3.2.
    623  *
    624  *  Modify GetXFBVaryingGeometryInterleaved test in the following aspects:
    625  *  - use transform feedback in separate mode.
    626  *
    627  *  Separate mode require one buffer per captured variable.
    628  */
    629 class CheckGetXFBVarying : public deqp::TestCase
    630 {
    631 public:
    632 	CheckGetXFBVarying(deqp::Context& context, const char* test_name, const char* test_description);
    633 	~CheckGetXFBVarying(void);
    634 	virtual IterateResult iterate(void);
    635 
    636 private:
    637 	deqp::Context& m_context;
    638 	glw::GLint	 m_max_xfb_interleaved_components;
    639 	glw::GLint	 m_max_xfb_separate_attributes;
    640 	glw::GLint	 m_max_xfb_separate_components;
    641 	glw::GLint	 m_max_varying_components;
    642 	glw::GLint	 m_max_varying_vectors;
    643 	glw::GLint	 m_max_geometry_total_output_components;
    644 
    645 	void		fetchLimits(void);
    646 	glw::GLuint numberOfAttributes(glw::GLuint capture_way, glw::GLuint shader_case, glw::GLuint varying_type);
    647 
    648 	glw::GLuint buildProgram(glw::GLuint capture_way, glw::GLuint shader_case, glw::GLuint varying_type,
    649 							 glw::GLuint number_of_attributes);
    650 
    651 	bool check(glw::GLuint program, glw::GLuint capture_way, glw::GLuint shader_case, glw::GLuint varying_type,
    652 			   glw::GLuint number_of_attributes);
    653 
    654 	static const glw::GLchar* s_generic_fragment_shader;
    655 
    656 	static const struct ShaderCase
    657 	{
    658 		const glw::GLchar* vertex_shader;
    659 		const glw::GLchar* geometry_shader;
    660 	} s_shader_cases[];
    661 
    662 	static const glw::GLuint s_shader_cases_count;
    663 
    664 	static const struct VaryingType
    665 	{
    666 		const glw::GLenum  type;
    667 		const glw::GLchar* name;
    668 		const glw::GLuint  components_count;
    669 		const bool		   float_component;
    670 	} s_varying_types[];
    671 
    672 	static const glw::GLuint s_varying_types_count;
    673 
    674 	static const glw::GLenum s_capture_ways[];
    675 	static const glw::GLuint s_capture_ways_count;
    676 };
    677 
    678 /** QueryVertexInterleaved
    679  *
    680  *  Verifies if queries are performed as expected when geometry is captured from
    681  *  vertex stage in interleaved mode.
    682  *
    683  *  Test should be run if EXT_transform_feedback is supported or context is
    684  *  at least 3.0.
    685  *
    686  *  Modify CaptureVertexInterleaved test in the following aspects:
    687  *  - buffer used as storage for captured geometry should be too small to fit
    688  *    all emitted vertices;
    689  *  - execute BeginQuery for PRIMITIVES_GENERATED and
    690  *    TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN before draw is executed; End queries
    691  *    after draw call.
    692  *
    693  *  Test pass if results of queries are correct.
    694  */
    695 class QueryVertexInterleaved : public CaptureVertexInterleaved
    696 {
    697 public:
    698 	QueryVertexInterleaved(deqp::Context& context, const char* test_name, const char* test_description);
    699 
    700 protected:
    701 	glw::GLuint m_query_object;
    702 
    703 	virtual void createTransformFeedbackBuffer(void);
    704 	virtual void draw(glw::GLuint primitive_case);
    705 	virtual bool checkTransformFeedbackBuffer(BindBufferCase bind_case, glw::GLenum primitive_type);
    706 	virtual void clean(void);
    707 };
    708 
    709 /** QueryGeometryInterleaved
    710  *
    711  *  Verifies if queries are performed as expected when geometry is captured from
    712  *  geometry stage in interleaved mode.
    713  *
    714  *  Test should be run if either EXT_transform_feedback is supported or context
    715  *  is at least 3.0 and either ARB_geometry_shader4 is supported or context is
    716  *  at least 3.2.
    717  *
    718  *  Modify CaptureGeometryInterleaved test in the following aspects:
    719  *  - buffer used as storage for captured geometry should be too small to fit
    720  *    all emitted vertices;
    721  *  - execute BeginQuery for PRIMITIVES_GENERATED and
    722  *    TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN before draw is executed; End queries
    723  *    after draw call.
    724  *
    725  *  Test pass if results of queries are correct.
    726  */
    727 class QueryGeometryInterleaved : public CaptureGeometryInterleaved
    728 {
    729 public:
    730 	QueryGeometryInterleaved(deqp::Context& context, const char* test_name, const char* test_description);
    731 
    732 protected:
    733 	glw::GLuint m_query_object;
    734 
    735 	virtual void createTransformFeedbackBuffer(void);
    736 	virtual void draw(glw::GLuint primitive_case);
    737 	virtual bool checkTransformFeedbackBuffer(BindBufferCase bind_case, glw::GLenum primitive_type);
    738 	virtual void clean(void);
    739 };
    740 
    741 /** QueryVertexSeparate
    742  *
    743  *  Verifies if queries are performed as expected when geometry is captured from
    744  *  vertex stage in separate mode.
    745  *
    746  *  Test should be run if EXT_transform_feedback is supported or context is
    747  *  at least 3.0.
    748  *
    749  *  Modify CaptureVertexSeparate test in the following aspects:
    750  *  - buffers used as storage for captured geometry should be too small to fit
    751  *    all emitted vertices;
    752  *  - execute BeginQuery for PRIMITIVES_GENERATED and
    753  *    TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN before draw is executed; End queries
    754  *    after draw call;
    755  *  - use transform feedback in separate mode.
    756  *
    757  *  Separate mode require one buffer per captured variable.
    758  *
    759  *  Test pass if results of queries are correct.
    760  */
    761 class QueryVertexSeparate : public CaptureVertexSeparate
    762 {
    763 public:
    764 	QueryVertexSeparate(deqp::Context& context, const char* test_name, const char* test_description);
    765 
    766 protected:
    767 	glw::GLuint m_query_object;
    768 
    769 	virtual void createTransformFeedbackBuffer(void);
    770 	virtual void draw(glw::GLuint primitive_case);
    771 	virtual bool checkTransformFeedbackBuffer(BindBufferCase bind_case, glw::GLenum primitive_type);
    772 	virtual void clean(void);
    773 };
    774 
    775 /** QueryGeometrySeparate
    776  *
    777  *  Verifies if queries are performed as expected when geometry is captured from
    778  *  geometry stage in separate mode.
    779  *
    780  *  Test should be run if either EXT_transform_feedback is supported or context
    781  *  is at least 3.0 and either ARB_geometry_shader4 is supported or context is
    782  *  at least 3.2.
    783  *
    784  *  Modify CaptureGeometrySeparate test in the following aspects:
    785  *  - buffers used as storage for captured geometry should be too small to fit
    786  *    all emitted vertices;
    787  *  - execute BeginQuery for PRIMITIVES_GENERATED and
    788  *    TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN before draw is executed; End queries
    789  *    after draw call;
    790  *  - use transform feedback in separate mode.
    791  *
    792  *  Separate mode require one buffer per captured variable.
    793  *
    794  *  Test pass if results of queries are correct.
    795  */
    796 class QueryGeometrySeparate : public CaptureGeometrySeparate
    797 {
    798 public:
    799 	QueryGeometrySeparate(deqp::Context& context, const char* test_name, const char* test_description);
    800 
    801 protected:
    802 	glw::GLuint m_query_object;
    803 
    804 	virtual void createTransformFeedbackBuffer(void);
    805 	virtual void draw(glw::GLuint primitive_case);
    806 	virtual bool checkTransformFeedbackBuffer(BindBufferCase bind_case, glw::GLenum primitive_type);
    807 	virtual void clean(void);
    808 };
    809 
    810 /** DiscardVertex
    811  *
    812  *  Verifies if rasterization is discarded when geometry is captured from vertex
    813  *  stage.
    814  *
    815  *  Test should be run if EXT_transform_feedback is supported or context is
    816  *  at least 3.0.
    817  *
    818  *  Modify CaptureVertexInterleaved test in the following aspects:
    819  *  - disable rasterization before draw call;
    820  *  - it is expected that framebuffer contents will not change, while XFB buffer
    821  *  is modified.
    822  */
    823 class DiscardVertex : public CaptureVertexInterleaved
    824 {
    825 public:
    826 	DiscardVertex(deqp::Context& context, const char* test_name, const char* test_description);
    827 
    828 protected:
    829 	virtual void draw(glw::GLuint primitive_case);
    830 	virtual bool checkFramebuffer(glw::GLuint primitive_case);
    831 };
    832 
    833 /** DiscardGeometry
    834  *
    835  *  Verifies if rasterization is discarded when geometry is captured from
    836  *  geometry stage.
    837  *
    838  *  Test should be run if EXT_transform_feedback is supported or context is at least 3.0.
    839  *  Test should be run if ARB_geometry_shader4 is supported or context is at least 3.2.
    840  *
    841  *  Modify CaptureGeometryInterleaved test in the following aspects:
    842  *  - disable rasterization before draw call;
    843  *  - it is expected that framebuffer contents will not change, while XFB buffer
    844  *    is modified.
    845  */
    846 class DiscardGeometry : public CaptureGeometryInterleaved
    847 {
    848 public:
    849 	DiscardGeometry(deqp::Context& context, const char* test_name, const char* test_description);
    850 
    851 protected:
    852 	virtual void draw(glw::GLuint primitive_case);
    853 	virtual bool checkFramebuffer(glw::GLuint primitive_case);
    854 };
    855 
    856 /** DrawXFB
    857  *
    858  *  Verifies that transform feedback objects can be used to draw.
    859  *
    860  *  Test should be executed if ARB_transform_feedback2 is supported or context
    861  *  is at least 4.0.
    862  *
    863  *  Steps:
    864  *  - prepare two programs consisting of vertex shader which will:
    865  *     * output position based on gl_VertexID:
    866  *     * output color by passing value of uniform;
    867  *    First program should use the following positions:
    868  *     ID |  X |  Y
    869  *      0 | -1 | -1
    870  *      1 | -1 |  1
    871  *      2 |  1 |  1
    872  *    Second program should use the following positions:
    873  *      0 | -1 | -1
    874  *      1 |  1 |  1
    875  *      2 |  1 | -1
    876  *  - prepare three XFB objects and corresponding buffers for captured geometry;
    877  *    Each XFB should capture position and color from both programs;
    878  *  - activate first program;
    879  *  - for each XFB object:
    880  *     * set uniform to color corresponding with XFB;
    881  *     * activate XFB;
    882  *     * execute DrawArrays to draw three points starting at 0;
    883  *     * pause XFB;
    884  *  - inspect TRANSFORM_FEEDBACK_BUFFER_PAUSED and
    885  *    TRANSFORM_FEEDBACK_BUFFER_ACTIVE;
    886  *  - activate second program;
    887  *  - for each XFB object:
    888  *     * set uniform to color corresponding with XFB;
    889  *     * resume XFB;
    890  *     * execute DrawArrays to draw three points starting at 0;
    891  *     * end XFB;
    892  *  - inspect TRANSFORM_FEEDBACK_BUFFER_PAUSED and
    893  *    TRANSFORM_FEEDBACK_BUFFER_ACTIVE;
    894  *  - prepare program consisting of vertex and fragment stage; Vertex shader
    895  *    should pass position and color; Fragment stage should pass color;
    896  *  - set program;
    897  *  - set vertex array to match layout of XFB;
    898  *  - for each XFB:
    899  *     * prepare and clean framebuffer;
    900  *     * execute DrawTransformFeedback to draw triangles;
    901  *     * inspect contents of framebuffer;
    902  *
    903  *  It is expected that drawn images will be filled with color set via uniform
    904  *  variables.
    905  *
    906  *  Repeat steps for both interleaved and separate modes.
    907  */
    908 class DrawXFB : public deqp::TestCase
    909 {
    910 public:
    911 	DrawXFB(deqp::Context& context, const char* test_name, const char* test_description);
    912 	~DrawXFB(void);
    913 	virtual IterateResult iterate(void);
    914 
    915 protected:
    916 	static const glw::GLchar* s_vertex_shader_xfb;
    917 	static const glw::GLchar* s_vertex_shader_draw;
    918 	static const glw::GLchar* s_fragment_shader;
    919 
    920 	static const glw::GLuint  s_xfb_varyings_count = 2;
    921 	static const glw::GLchar* s_xfb_varyings[s_xfb_varyings_count];
    922 	static const glw::GLuint  s_vertex_count = 3;
    923 	static const glw::GLenum  s_capture_modes[];
    924 	static const glw::GLuint  s_capture_modes_count;
    925 	static const glw::GLuint  s_capture_size = s_vertex_count * sizeof(glw::GLfloat) * 4 /* number of components */ *
    926 											  s_xfb_varyings_count * 2 /* number of programs */;
    927 	static const glw::GLuint  s_view_size = 2;
    928 	static const glw::GLuint  s_xfb_count = 3;
    929 	static const glw::GLfloat s_colours[s_xfb_count][4];
    930 
    931 	deqp::Context& m_context;
    932 	glw::GLuint	m_program_id_xfb;
    933 	glw::GLuint	m_program_id_draw;
    934 	glw::GLuint	m_xfb_id[s_xfb_count];
    935 	glw::GLuint	m_bo_id[s_xfb_count];
    936 	glw::GLuint	m_fbo_id;
    937 	glw::GLuint	m_rbo_id;
    938 	glw::GLuint	m_vao_id;
    939 
    940 	void prepare(glw::GLenum capture_mode);
    941 	void bindXFB(glw::GLuint xfb_id);
    942 	void bindVAO(glw::GLuint vao_id);
    943 	void bindBOForXFB(glw::GLenum capture_mode, glw::GLuint bo_id);
    944 	void bindBOForDraw(glw::GLuint program_id, glw::GLenum capture_mode, glw::GLuint bo_id);
    945 	void useProgram(glw::GLuint program_id);
    946 	void useColour(glw::GLuint program_id, glw::GLfloat r, glw::GLfloat g, glw::GLfloat b, glw::GLfloat a);
    947 	void useGeometrySet(glw::GLuint program_id, bool invert_sign);
    948 	void drawForCapture(bool begin_xfb, bool pause_xfb, bool resume_xfb, bool end_xfb);
    949 	void drawToFramebuffer(glw::GLuint xfb_id);
    950 	bool checkFramebuffer(glw::GLfloat r, glw::GLfloat g, glw::GLfloat b, glw::GLfloat a);
    951 	bool inspectXFBState(bool shall_be_paused, bool shall_be_active);
    952 	void clean();
    953 };
    954 
    955 /** DrawXFBFeedback
    956  *
    957  *  Verifies that data captured with XFB can be used as source for next capture.
    958  *
    959  *  Test should be executed if ARB_transform_feedback2 is supported or context
    960  *  is at least 4.0.
    961  *
    962  *  Steps:
    963  *  - prepare program consisting of vertex shader which pass position from input
    964  *    attribute to gl_Position multiplying it by 2.0;
    965  *  - instruct implementation to capture geometry in interleaved mode;
    966  *  - prepare source buffer;
    967  *  - prepare buffer to capture geometry;
    968  *  - begin transform feedback;
    969  *  - draw one vertex using DrawArrays;
    970  *  - end transform feedback;
    971  *  - swap buffer
    972  *  - begin transform feedback;
    973  *  - draw using DrawTransformFeedback;
    974  *  - end transform feedback;
    975  *  - swap buffer
    976  *  - begin transform feedback;
    977  *  - draw using DrawTransformFeedback;
    978  *  - end transform feedback;
    979  *  - map last captured buffer, expect position vector multiplied by value 8;
    980  */
    981 class DrawXFBFeedback : public deqp::TestCase
    982 {
    983 public:
    984 	DrawXFBFeedback(deqp::Context& context, const char* test_name, const char* test_description);
    985 	~DrawXFBFeedback(void);
    986 	virtual IterateResult iterate(void);
    987 
    988 protected:
    989 	static const glw::GLchar* s_vertex_shader;
    990 	static const glw::GLchar* s_fragment_shader;
    991 	static const glw::GLchar* s_xfb_varying;
    992 	static const glw::GLchar* s_attrib;
    993 	static const glw::GLuint  s_draw_vertex_count;
    994 	static const glw::GLfloat s_initial_data[];
    995 	static const glw::GLuint  s_bo_count = 2;
    996 	static const glw::GLuint  s_bo_size;
    997 
    998 	deqp::Context& m_context;
    999 	glw::GLuint	m_program_id;
   1000 	glw::GLuint	m_vao_id[s_bo_count];
   1001 	glw::GLuint	m_xfb_id;
   1002 	glw::GLuint	m_bo_id[s_bo_count];
   1003 	glw::GLuint	m_source_bo_index;
   1004 
   1005 	void prepareAndBind();
   1006 	void draw(bool is_first_draw);
   1007 	void swapBuffers();
   1008 	bool check();
   1009 	void clean();
   1010 };
   1011 
   1012 /** DrawXFBStream
   1013  *
   1014  *  Verifies that vertex stream captured with transform feedback can be used to
   1015  *  draw.
   1016  *
   1017  *  Test should be executed if both ARB_transform_feedback3 and ARB_gpu_shader5
   1018  *  are supported or context is at least 4.0.
   1019  *  This test is not supported if MAX_VERTEX_STREAMS is less than 2.
   1020  *
   1021  *  Steps:
   1022  *  - prepare program consisting of vertex and geometry shaders; Geometry shader
   1023  *    should output full-screen quad made of two triangles; First triangle should
   1024  *    be emitted to first vertex stream; Second triangle should be emitted to the
   1025  *    second vertex stream; Vertex shader can be blank;
   1026  *  - prepare buffers to capture geometry;
   1027  *  - instruct implementation to capture geometry in interleaved mode;
   1028  *  - begin XFB;
   1029  *  - begin indexed query for PRIMITIVES_GENERATED and
   1030  *    TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN for both vertex streams;
   1031  *  - draw single vertex;
   1032  *  - end queries;
   1033  *  - end XFB;
   1034  *  - inspect results of queries;
   1035  *  - prepare program consisting of vertex and fragment shaders; Vertex stage
   1036  *    should pass position from input to output; Fragment shader should output
   1037  *    white color;
   1038  *  - prepare and clean framebuffer;
   1039  *  - set vertex array layout to match data captured by XFB;
   1040  *  - execute DrawTransformFeedbackStream to draw triangle from first stream;
   1041  *  - execute DrawTransformFeedbackStream to draw triangle from second stream;
   1042  *  - inspect contents of framebuffer, it is expected to be filled with white
   1043  *    color.
   1044  */
   1045 class DrawXFBStream : public deqp::TestCase
   1046 {
   1047 public:
   1048 	DrawXFBStream(deqp::Context& context, const char* test_name, const char* test_description);
   1049 	~DrawXFBStream(void);
   1050 	virtual IterateResult iterate(void);
   1051 
   1052 private:
   1053 	static const glw::GLchar* s_vertex_shader_pass;
   1054 	static const glw::GLchar* s_vertex_shader_blank;
   1055 	static const glw::GLchar* s_geometry_shader;
   1056 	static const glw::GLchar* s_fragment_shader;
   1057 	static const glw::GLchar* s_xfb_varyings[];
   1058 	static const glw::GLuint  s_xfb_varyings_count;
   1059 	static const glw::GLuint  s_bo_ids_count = 2;
   1060 	static const glw::GLuint  s_qo_ids_count = 4;
   1061 	static const glw::GLuint  s_bo_size;
   1062 	static const glw::GLuint  s_view_size;
   1063 
   1064 	deqp::Context& m_context;
   1065 	glw::GLuint	m_program_id_generate;
   1066 	glw::GLuint	m_program_id_draw;
   1067 	glw::GLuint	m_vao_id;
   1068 	glw::GLuint	m_xfb_id;
   1069 	glw::GLuint	m_bo_id[s_bo_ids_count];
   1070 	glw::GLuint	m_fbo_id;
   1071 	glw::GLuint	m_rbo_id;
   1072 	glw::GLuint	m_qo_id[s_qo_ids_count];
   1073 
   1074 	void prepareObjects();
   1075 	void setupVertexArray(glw::GLuint bo_id);
   1076 	void useProgram(glw::GLuint program_id);
   1077 	void drawForXFB();
   1078 	bool inspectQueries();
   1079 	void drawForFramebuffer(glw::GLuint stream);
   1080 	bool check();
   1081 	void clean();
   1082 };
   1083 
   1084 /** CaptureSpecialInterleaved
   1085  *
   1086  *  Verifies that special variable names are respected.
   1087  *
   1088  *  Test should be executed if ARB_transform_feedback3 is supported or context
   1089  *  is at least 4.0.
   1090  *
   1091  *  Steps:
   1092  *  - prepare program consisting of vertex shader which outputs four variables;
   1093  *  - set up XFB to capture the following <varyings>:
   1094  *    * variable_1,
   1095  *    * gl_SkipComponents4,
   1096  *    * variable_2,
   1097  *    * gl_NextBuffer,
   1098  *    * variable_3,
   1099  *    * gl_SkipComponents4,
   1100  *    * variable_4;
   1101  *  - begin XFB;
   1102  *  - draw two vertices;
   1103  *  - end XFB;
   1104  *  - verify that captured geometry is correct.
   1105  */
   1106 class CaptureSpecialInterleaved : public deqp::TestCase
   1107 {
   1108 public:
   1109 	CaptureSpecialInterleaved(deqp::Context& context, const char* test_name, const char* test_description);
   1110 	~CaptureSpecialInterleaved(void);
   1111 	virtual IterateResult iterate(void);
   1112 
   1113 private:
   1114 	static const glw::GLchar* s_vertex_shader;
   1115 	static const glw::GLchar* s_fragment_shader;
   1116 	static const glw::GLchar* s_xfb_varyings[];
   1117 	static const glw::GLuint  s_xfb_varyings_count;
   1118 	static const glw::GLuint  s_bo_ids_count = 2;
   1119 	static const glw::GLuint  s_bo_size;
   1120 
   1121 	deqp::Context& m_context;
   1122 	glw::GLuint	m_program_id;
   1123 	glw::GLuint	m_vao_id;
   1124 	glw::GLuint	m_xfb_id;
   1125 	glw::GLuint	m_bo_id[s_bo_ids_count];
   1126 
   1127 	void prepareAndBind();
   1128 	void draw();
   1129 	bool check();
   1130 	void clean();
   1131 };
   1132 
   1133 /** DrawXFBInstanced
   1134  *
   1135  *  Verifies that transform feedback objects can used with instanced draws.
   1136  *
   1137  *  Test should be executed if context is at least 3.1 and either
   1138  *  ARB_transform_feedback_instanced is supported or context is at least 4.2.
   1139  *
   1140  *  Steps:
   1141  *  - prepare program consisting of vertex shader which outputs positions of
   1142  *    full-screen quad made of triangle strip based on gl_VertexID;
   1143  *  - instruct implementation to capture geometry in interleaved mode;
   1144  *  - prepare buffer to capture geometry;
   1145  *  - begin transform feedback;
   1146  *  - draw four vertices;
   1147  *  - end transform feedback;
   1148  *  - prepare program consisting of vertex and fragment shaders; Vertex stage
   1149  *    should calculate position as follows:
   1150  *
   1151  *    gl_Position = in_position * uni_matrices[gl_InstanceID];
   1152  *
   1153  *  Fragment shader should output white color;
   1154  *  - prepare UNIFORM_BUFFER filled with four mat4; Select data so matrices
   1155  *    transforms quad [-1, -1] : [1, 1] as follows:
   1156  *    * 0 - [-1,  0] : [0, 1] - left top,
   1157  *    * 1 - [ 0,  0] : [1, 1] - right top,
   1158  *    * 2 - [-1, -1] : [0, 0] - left bottom,
   1159  *    * 3 - [ 0, -1] : [1, 0] - right bottom;
   1160  *  - prepare and clean framebuffer;
   1161  *  - set up layout of vertex data in XFB;
   1162  *  - execute DrawTransformFeedbackInstanced to draw four instances of quad from XFB;
   1163  *  - it is expected that framebuffer is filled with white color;
   1164  */
   1165 class DrawXFBInstanced : public deqp::TestCase
   1166 {
   1167 public:
   1168 	DrawXFBInstanced(deqp::Context& context, const char* test_name, const char* test_description);
   1169 	~DrawXFBInstanced(void);
   1170 	virtual IterateResult iterate(void);
   1171 
   1172 private:
   1173 	static const glw::GLchar* s_vertex_shader_generate;
   1174 	static const glw::GLchar* s_vertex_shader_draw;
   1175 	static const glw::GLchar* s_fragment_shader;
   1176 	static const glw::GLchar* s_xfb_varying;
   1177 	static const glw::GLchar* s_uniform;
   1178 	static const glw::GLuint  s_bo_xfb_size;
   1179 	static const glw::GLfloat s_bo_uniform_data[];
   1180 	static const glw::GLuint  s_bo_uniform_size;
   1181 	static const glw::GLuint  s_view_size;
   1182 
   1183 	deqp::Context& m_context;
   1184 	glw::GLuint	m_program_id_generate;
   1185 	glw::GLuint	m_program_id_draw;
   1186 	glw::GLuint	m_vao_id;
   1187 	glw::GLuint	m_xfb_id;
   1188 	glw::GLuint	m_bo_id_xfb;
   1189 	glw::GLuint	m_bo_id_uniform;
   1190 	glw::GLuint	m_fbo_id;
   1191 	glw::GLuint	m_rbo_id;
   1192 
   1193 	void prepareObjects();
   1194 	void drawForXFB();
   1195 	void drawInstanced();
   1196 	bool check();
   1197 	void clean();
   1198 };
   1199 
   1200 /** DrawXFBStreamInstanced
   1201  *
   1202  *  Verifies that transform feedback objects can used with instanced draws.
   1203  *
   1204  *  Test should be executed if context is at least 3.1 and either
   1205  *  ARB_gpu_shader5 is supported or context is at least 4.0 and either
   1206  *  ARB_transform_feedback_instanced is supported or context is at least 4.2.
   1207  *
   1208  *  Steps:
   1209  *  - prepare program consisting of vertex shader which based on gl_VertexID
   1210  *    outputs:
   1211  *     * to stream 0 - color,
   1212  *     * to stream 1 - positions
   1213  *    for a full-screen quad made of triangle strip;
   1214  *  - instruct implementation to capture geometry in interleaved mode;
   1215  *  - prepare buffers to capture geometry;
   1216  *  - begin transform feedback;
   1217  *  - draw four vertices;
   1218  *  - end transform feedback;
   1219  *  - prepare program consisting of vertex and fragment shaders; Vertex stage
   1220  *    should calculate position as follows:
   1221  *
   1222  *      gl_Position = in_position * uni_matrices[gl_InstanceID];
   1223  *
   1224  *  Fragment shader should output white color;
   1225  *  - prepare UNIFORM_BUFFER filled with four mat4; Select data so matrices
   1226  *    transforms quad [-1, -1] : [1, 1] as follows:
   1227  *     * 0 - [-1,  0] : [0, 1] - left top,
   1228  *     * 1 - [ 0,  0] : [1, 1] - right top,
   1229  *     * 2 - [-1, -1] : [0, 0] - left bottom,
   1230  *     * 3 - [ 0, -1] : [1, 0] - right bottom;
   1231  *  - prepare and clean framebuffer;
   1232  *  - set up layout of vertex data in XFB;
   1233  *  - execute DrawTransformFeedbackStreamInstanced to draw four instances of
   1234  *    quad from XFB, stream 1;
   1235  *  - it is expected that framebuffer is filled with white color;
   1236  */
   1237 class DrawXFBStreamInstanced : public deqp::TestCase
   1238 {
   1239 public:
   1240 	DrawXFBStreamInstanced(deqp::Context& context, const char* test_name, const char* test_description);
   1241 	~DrawXFBStreamInstanced(void);
   1242 	virtual IterateResult iterate(void);
   1243 
   1244 private:
   1245 	static const glw::GLchar* s_vertex_shader_blank;
   1246 	static const glw::GLchar* s_geometry_shader_generate;
   1247 	static const glw::GLchar* s_vertex_shader_draw;
   1248 	static const glw::GLchar* s_fragment_shader_blank;
   1249 	static const glw::GLchar* s_fragment_shader_draw;
   1250 	static const glw::GLchar* s_xfb_varyings[];
   1251 	static const glw::GLuint  s_xfb_varyings_count;
   1252 	static const glw::GLchar* s_uniform;
   1253 	static const glw::GLuint  s_bo_xfb_size;
   1254 	static const glw::GLfloat s_bo_uniform_data[];
   1255 	static const glw::GLuint  s_bo_uniform_size;
   1256 	static const glw::GLuint  s_view_size;
   1257 
   1258 	deqp::Context& m_context;
   1259 	glw::GLuint	m_program_id_generate;
   1260 	glw::GLuint	m_program_id_draw;
   1261 	glw::GLuint	m_vao_id;
   1262 	glw::GLuint	m_xfb_id;
   1263 	glw::GLuint	m_bo_id_xfb_position;
   1264 	glw::GLuint	m_bo_id_xfb_color;
   1265 	glw::GLuint	m_bo_id_uniform;
   1266 	glw::GLuint	m_fbo_id;
   1267 	glw::GLuint	m_rbo_id;
   1268 
   1269 	void prepareObjects();
   1270 	void drawForXFB();
   1271 	void drawStreamInstanced();
   1272 	bool check();
   1273 	void clean();
   1274 };
   1275 
   1276 namespace Utilities
   1277 {
   1278 /** Build a GLSL program
   1279  *
   1280  *  @param [in]  gl                                     OpenGL Functions Access.
   1281  *  @param [in]  log                                    Log outut.
   1282  *  @param [in]  geometry_shader_source                 Pointer to C string of the geometry shader or NULL if not used.
   1283  *  @param [in]  tessellation_control_shader_source     Pointer to C string of the tessellation control shader or NULL if not used.
   1284  *  @param [in]  tessellation_evaluation_shader_source  Pointer to C string of the tessellation evaluation shader or NULL if not used.
   1285  *  @param [in]  vertex_shader_source                   Pointer to C string of the vertex shader or NULL if not used.
   1286  *  @param [in]  geometry_shader_source                 Pointer to C string of the fragment shader or NULL if not used.
   1287  *  @param [in]  transform_feedback_varyings            C array of transform feedback varyings names.
   1288  *  @param [in]  transform_feedback_varyings_count      Count of transform feedback varyings names.
   1289  *  @param [in]  transform_feedback_varyings_mode       Transform feedback capture mode - GL_SEPARATE_ATTRIBS or GL_INTERLEAVED_ATTRIBS.
   1290  *  @param [in]  do_not_detach                          Do not detach shaders - default is faulse.
   1291  *  @param [out] linking_status                         Return pointer to store linking status or NULL if not needed.
   1292  *
   1293  *  @return OpenGL program shader ID or zero if error had occured.
   1294  */
   1295 glw::GLuint buildProgram(glw::Functions const& gl, tcu::TestLog& log, glw::GLchar const* const geometry_shader_source,
   1296 						 glw::GLchar const* const tessellation_control_shader_source,
   1297 						 glw::GLchar const* const tessellation_evaluation_shader_source,
   1298 						 glw::GLchar const* const vertex_shader_source, glw::GLchar const* const fragment_shader_source,
   1299 						 glw::GLchar const* const* const transform_feedback_varyings,
   1300 						 glw::GLsizei const				 transform_feedback_varyings_count,
   1301 						 glw::GLenum const transform_feedback_varyings_mode, bool const do_not_detach = false,
   1302 						 glw::GLint* linking_status = DE_NULL);
   1303 
   1304 /** Preprocess source string by replacing key tokens with new values.
   1305  *
   1306  *  @param [in] source      Source string.
   1307  *  @param [in] key         Key, substring to be replaced.
   1308  *  @param [in] value       Value, substring to be substituted in place of key.
   1309  *
   1310  *  @return Preprocessed string.
   1311  */
   1312 std::string preprocessCode(std::string source, std::string key, std::string value);
   1313 
   1314 /** Change integer number to string
   1315  *
   1316  *  @param [in] i       Integer number.
   1317  *
   1318  *  @return String represnting integer number.
   1319  */
   1320 std::string itoa(glw::GLint i);
   1321 
   1322 /** Change floating point number to string
   1323  *
   1324  *  @param [in] f       Floating point number.
   1325  *
   1326  *  @return String represnting floating point number.
   1327  */
   1328 std::string ftoa(glw::GLfloat f);
   1329 } /* Utilities namespace */
   1330 } /* TransformFeedback namespace */
   1331 
   1332 } /* gl3cts namespace */
   1333 
   1334 #endif // _GL3CTRANSFORMFEEDBACKTESTS_HPP
   1335