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