1#ifndef _GL3CGPUSHADER5TESTS_HPP
2#define _GL3CGPUSHADER5TESTS_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 * \file  gl3cGPUShader5Tests.hpp
28 * \brief Declares test classes for "GPU Shader 5" functionality.
29 */ /*-------------------------------------------------------------------*/
30
31#include "glcTestCase.hpp"
32#include "glwDefs.hpp"
33#include "glwEnums.hpp"
34#include "tcuDefs.hpp"
35#include "tcuVector.hpp"
36#include <queue>
37
38namespace gl3cts
39{
40class Utils
41{
42public:
43	/* Public type definitions */
44	/* Defines GLSL variable type */
45	enum _variable_type
46	{
47		VARIABLE_TYPE_FLOAT,
48		VARIABLE_TYPE_INT,
49		VARIABLE_TYPE_IVEC2,
50		VARIABLE_TYPE_IVEC3,
51		VARIABLE_TYPE_IVEC4,
52		VARIABLE_TYPE_UINT,
53		VARIABLE_TYPE_UVEC2,
54		VARIABLE_TYPE_UVEC3,
55		VARIABLE_TYPE_UVEC4,
56		VARIABLE_TYPE_VEC2,
57		VARIABLE_TYPE_VEC3,
58		VARIABLE_TYPE_VEC4,
59
60		/* Always last */
61		VARIABLE_TYPE_UNKNOWN
62	};
63
64	/** Store information about program object
65	 *
66	 **/
67	struct programInfo
68	{
69		programInfo(deqp::Context& context);
70		~programInfo();
71
72		void build(const glw::GLchar* fragment_shader_code, const glw::GLchar* vertex_shader_code);
73		void compile(glw::GLuint shader_id, const glw::GLchar* shader_code) const;
74		void link() const;
75
76		void setUniform(Utils::_variable_type type, const glw::GLchar* name, const glw::GLvoid* data);
77
78		deqp::Context& m_context;
79
80		glw::GLuint m_fragment_shader_id;
81		glw::GLuint m_program_object_id;
82		glw::GLuint m_vertex_shader_id;
83	};
84
85	/* Public static methods */
86	static void replaceToken(const glw::GLchar* token, size_t& search_position, const glw::GLchar* text,
87							 std::string& string);
88};
89
90/** Implements ImplicitConversions test, description follows:
91 *
92 * Verifies that compiler accepts implicit conversions and the results of
93 * implicit conversions are the same as explicit conversions.
94 *
95 * Steps:
96 * - prepare a program consisting of vertex and fragment shader; Vertex shader
97 * should implement the following snippet:
98 *
99 *   uniform SOURCE_TYPE u1;
100 *   uniform SOURCE_TYPE u2;
101 *
102 *   out vec4 result;
103 *
104 *   void main()
105 *   {
106 *     DESTINATION_TYPE v = 0;
107 *
108 *     v = DESTINATION_TYPE(u2) - u1;
109 *
110 *     result = vec4(0.0, 0.0, 0.0, 0.0);
111 *
112 *     if (0 == v)
113 *     {
114 *       result = vec4(1.0, 1.0, 1.0, 1.0);
115 *     }
116 *   }
117 *
118 * Fragment shader should pass result from vertex shader to output color.
119 * - it is expected that program will link without any errors;
120 * - set u1 and u2 with different values;
121 * - draw fullscreen quad;
122 * - it is expected that drawn image is filled with black color;
123 * - set u1 and u2 with the same value;
124 * - draw fullscreen quad;
125 * - it is expected that drawn image is filled with white color;
126 *
127 * Repeat steps for the following pairs:
128 *
129 *   int   - uint
130 *   int   - float
131 *   ivec2 - uvec2
132 *   ivec3 - uvec3
133 *   ivec4 - uvec4
134 *   ivec2 - vec2
135 *   ivec3 - vec3
136 *   ivec4 - vec4
137 *   uint  - float
138 *   uvec2 - vec2
139 *   uvec3 - vec3
140 *   uvec4 - vec4
141 **/
142class GPUShader5ImplicitConversionsTest : public deqp::TestCase
143{
144public:
145	/* Public methods */
146	GPUShader5ImplicitConversionsTest(deqp::Context& context);
147	GPUShader5ImplicitConversionsTest(deqp::Context& context, const char* name, const char* description);
148
149	void								 deinit();
150	virtual tcu::TestNode::IterateResult iterate();
151
152protected:
153	/* Protected methods*/
154	void testInit();
155	void verifyImage(glw::GLuint color, bool is_expected) const;
156
157private:
158	/* Private type definitions */
159	struct testCase
160	{
161		const glw::GLchar*	m_destination_type;
162		bool				  m_is_white_expected;
163		const glw::GLchar*	m_source_type;
164		Utils::_variable_type m_source_variable_type;
165		const void*			  m_u1_data;
166		const void*			  m_u2_data;
167	};
168
169	/* Private methods */
170	void executeTestCase(const testCase& test_case);
171	std::string getFragmentShader();
172	std::string getVertexShader(const glw::GLchar* destination_type, const glw::GLchar* source_type);
173
174	/* Private fields */
175	glw::GLuint m_fbo_id;
176	glw::GLuint m_tex_id;
177	glw::GLuint m_vao_id;
178
179	/* Private constants */
180	static const glw::GLsizei m_width;
181	static const glw::GLsizei m_height;
182};
183
184/** Implements FunctionOverloading test, description follows:
185 *
186 * Verifies that compiler accepts overloaded functions and selects proper one.
187 *
188 * Steps:
189 * - prepare a program consisting of vertex and fragment shader; Vertex shader
190 * should implement the following snippet:
191 *
192 *   uniform ivec4 u1;
193 *   uniform uvec4 u2;
194 *
195 *   out vec4 result;
196 *
197 *   vec4 f(in vec4 a, in vec4 b) // first
198 *   {
199 *     return a * b;
200 *   }
201 *
202 *   vec4 f(in uvec4 a, in uvec4 b) // second
203 *   {
204 *     return a - b;
205 *   }
206 *
207 *   void main()
208 *   {
209 *     result = f(u1, u2);
210 *   }
211 *
212 * Fragment shader should pass result from vertex shader to output color.
213 * - it is expected that program will link without any errors;
214 * - set u1 and u2 with different positive values;
215 * - draw fullscreen quad;
216 * - it is expected that drawn image is filled with non-black color;
217 * - set u1 and u2 with the same positive value;
218 * - draw fullscreen quad;
219 * - it is expected that drawn image is filled with black color;
220 *
221 * The second function should be considered a better match as u2 is exact
222 * match.
223 **/
224class GPUShader5FunctionOverloadingTest : public GPUShader5ImplicitConversionsTest
225{
226public:
227	/* Public methods */
228	GPUShader5FunctionOverloadingTest(deqp::Context& context);
229
230	virtual tcu::TestNode::IterateResult iterate();
231
232private:
233	/* Private methods */
234	void execute(const glw::GLint* u1_data, const glw::GLuint* u2_data, bool is_black_expected);
235};
236
237/** Implements FunctionOverloading test, description follows:
238 *
239 * Verifies functions: floatBitsTo* and *BitsToFloat work as expected.
240 *
241 * Steps:
242 * - prepare a program consisting of vertex and fragment shader; Vertex shader
243 * should implement the following snippet:
244 *
245 *   uniform T1 value;
246 *   uniform T2 expected_result;
247 *
248 *   out vec4 result;
249 *
250 *   void main()
251 *   {
252 *     result = 1;
253 *
254 *     T2 ret_val = TESTED_FUNCTION(value);
255 *
256 *     if (expected_result != ret_val)
257 *     {
258 *       result = 0;
259 *     }
260 *   }
261 *
262 * Fragment shader should pass result from vertex shader to output color.
263 * - it is expected that program will link without any errors;
264 * - set uniforms with "matching" values;
265 * - draw fullscreen quad;
266 * - inspect drawn image.
267 *
268 * Repeat steps to test the following functions:
269 * - floatBitsToInt
270 * - floatBitsToUint
271 * - intBitsToFloat
272 * - uintBitsToFloat
273 *
274 * Select "value" and "expected_result" to provoke both "white" and "black"
275 * results.
276 **/
277class GPUShader5FloatEncodingTest : public GPUShader5ImplicitConversionsTest
278{
279public:
280	/* Public methods */
281	GPUShader5FloatEncodingTest(deqp::Context& context);
282
283	virtual tcu::TestNode::IterateResult iterate();
284
285private:
286	/* Private types */
287	struct valueInfo
288	{
289		const Utils::_variable_type m_type;
290		const glw::GLchar*			m_type_name;
291		const void*					m_data;
292	};
293
294	struct testCase
295	{
296		const valueInfo	m_expected_value;
297		const valueInfo	m_value;
298		const glw::GLchar* m_function_name;
299		bool			   m_is_white_expected;
300	};
301
302	/* Private methods */
303	void execute(const testCase& test_case);
304	std::string getVertexShader(const testCase& test_case) const;
305};
306
307/** Group class for GPU Shader 5 conformance tests */
308class GPUShader5Tests : public deqp::TestCaseGroup
309{
310public:
311	/* Public methods */
312	GPUShader5Tests(deqp::Context& context);
313	virtual ~GPUShader5Tests()
314	{
315	}
316
317	virtual void init(void);
318
319private:
320	/* Private methods */
321	GPUShader5Tests(const GPUShader5Tests&);
322	GPUShader5Tests& operator=(const GPUShader5Tests&);
323};
324} /* gl3cts namespace */
325
326#endif // _GL3CGPUSHADER5TESTS_HPP
327