1#ifndef _GL3CTEXTURESWIZZLETESTS_HPP
2#define _GL3CTEXTURESWIZZLETESTS_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  gl3cTextureSwizzleTests.hpp
28 * \brief Declares test classes for "Texture Swizzle" 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{
40namespace TextureSwizzle
41{
42class Utils
43{
44public:
45	/** Store information about program object
46	 *
47	 **/
48	struct programInfo
49	{
50		programInfo(deqp::Context& context);
51		~programInfo();
52
53		void build(const glw::GLchar* fragment_shader_code, const glw::GLchar* vertex_shader_code);
54		void compile(glw::GLuint shader_id, const glw::GLchar* shader_code) const;
55		void link() const;
56
57		deqp::Context& m_context;
58
59		glw::GLuint m_fragment_shader_id;
60		glw::GLuint m_program_object_id;
61		glw::GLuint m_vertex_shader_id;
62	};
63
64	/* Public static methods */
65	static void replaceToken(const glw::GLchar* token, size_t& search_position, const glw::GLchar* text,
66							 std::string& string);
67};
68
69/** Implements APIErrors test, description follows:
70 *
71 * Verifies that errors are generated as expected.
72 *
73 * Check if:
74 * - INVALID_OPERATION is generated by TexParameter* routines when <pname> is
75 * one of [TEXTURE_SWIZZLE_R, TEXTURE_SWIZZLE_G, TEXTURE_SWIZZLE_B,
76 * TEXTURE_SWIZZLE_A] and <param> is not one of [RED, GREEN, BLUE, ALPHA, ZERO,
77 * ONE];
78 * - INVALID_OPERATION is generated by TexParameter*v routines when <pname> is
79 * TEXTURE_SWIZZLE_RGBA and any of four values pointed by <param> is not one of
80 * [RED, GREEN, BLUE, ALPHA, ZERO, ONE].
81 **/
82class APIErrorsTest : public deqp::TestCase
83{
84public:
85	/* Public methods */
86	APIErrorsTest(deqp::Context& context);
87
88	virtual void						 deinit();
89	virtual tcu::TestNode::IterateResult iterate();
90
91private:
92	/* Private methods */
93	void verifyError(const glw::GLenum expected_error);
94
95	/* Private fields */
96	glw::GLuint m_id;
97};
98
99/** Implements IntialState test, description follows:
100 *
101 * Verifies that intial state is as expected.
102 *
103 * Steps:
104 * - create a texture;
105 * - verify that query for TEXTURE_SWIZZLE_R results with RED;
106 * - verify that query for TEXTURE_SWIZZLE_G results with GREEN;
107 * - verify that query for TEXTURE_SWIZZLE_B results with BLUE;
108 * - verify that query for TEXTURE_SWIZZLE_A results with ALPHA;
109 * - verify that query for TEXTURE_SWIZZLE_RGBA results with [RED, GREEN, BLUE,
110 * ALPHA].
111 *
112 * Use GetTexParameter to query states. If GL_ARB_direct_state_access is
113 * supported than repeat the steps with GetTextureParameter.
114 * Repeat the steps for all supported texture targets.
115 **/
116class IntialStateTest : public deqp::TestCase
117{
118public:
119	/* Public methods */
120	IntialStateTest(deqp::Context& context);
121
122	virtual void						 deinit();
123	virtual tcu::TestNode::IterateResult iterate();
124
125private:
126	/* Private methods */
127	void verifyValues(const glw::GLenum texture_target);
128
129	/* Private fields */
130	glw::GLuint m_id;
131};
132
133/** Implements Smoke test, description follows:
134 *
135 * Verifies that all swizzle combinations work with all texture access
136 * routines.
137 *
138 * Steps:
139 * - prepare a source texture so that each channel is filled with specific
140 * value;
141 * - for each TEXTURE_SWIZZLE state combination:
142 *   * for each channel [R, G, B, A]:
143 *     + prepare a 2D single channeled texture with format matching sampled
144 *     channel and set it up as output color in framebuffer;
145 *     + prepare a program that will implement the following snippet in vertex
146 *     stage and output the value of result:
147 *
148 *       result = texture(source).C;
149 *
150 *     + set swizzle states with channel specific enums;
151 *     + draw a full-screen quad;
152 *     + verify that the output texture is filled with correct value;
153 *     + set swizzle states with RGBA enum;
154 *     + draw a full-screen quad;
155 *     + verify that the output texture is filled with correct value;
156 *     + prepare a program that will implement the following snippet in
157 *     fragment stage and output the value of result:
158 *
159 *       result = texture(source).C;
160 *
161 *     + set swizzle states with channel specific enums;
162 *     + draw a full-screen quad;
163 *     + verify that the output texture is filled with correct value;
164 *     + set swizzle states with RGBA enum;
165 *     + draw a full-screen quad;
166 *     + verify that the output texture is filled with correct value.
167 *
168 * Value is correct when:
169 * - it matches value assigned to the specified channel;
170 * - it is one for missing alpha channel;
171 * - it is zero for missing channel;
172 * - it is one for ONE;
173 * - it is zero for ZERO.
174 *
175 * Before any draw output texture should be cleared.
176 * Source texture should be RGBA32UI 2D_ARRAY 1x1 of length 1 with
177 * single mipmap at level 0.
178 * Dimenssions of destination texture should be 8x8.
179 * Repeat the steps for the following texture access routines:
180 * - textureProj,
181 * - textureLod,
182 * - textureOffset,
183 * - texelFetch,
184 * - texelFetchOffset,
185 * - textureProjOffset,
186 * - textureLodOffset,
187 * - textureProjLod,
188 * - textureProjLodOffset,
189 * - textureGrad,
190 * - textureGradOffset,
191 * - textureProjGrad,
192 * - textureProjGradOffset.
193 **/
194class SmokeTest : public deqp::TestCase
195{
196public:
197	/* Public methods */
198	SmokeTest(deqp::Context& context);
199	SmokeTest(deqp::Context& context, const glw::GLchar* name, const glw::GLchar* description);
200
201	virtual void						 deinit();
202	virtual tcu::TestNode::IterateResult iterate();
203
204protected:
205	/* Protected types */
206	struct testCase
207	{
208		size_t	 m_channel_index;
209		size_t	 m_source_texture_format_index;
210		size_t	 m_source_texture_target_index;
211		size_t	 m_texture_access_index;
212		glw::GLint m_texture_swizzle_red;
213		glw::GLint m_texture_swizzle_green;
214		glw::GLint m_texture_swizzle_blue;
215		glw::GLint m_texture_swizzle_alpha;
216		glw::GLint m_texture_sizes[4];
217	};
218
219	/* Protected methods */
220	void captureAndVerify(const testCase& test_case, size_t output_format_index, glw::GLint output_channel_size,
221						  size_t index_of_swizzled_channel);
222
223	void deinitOutputTexture();
224	void deinitTextures();
225
226	void draw(glw::GLenum target, const glw::GLint* texture_swizzle, bool use_rgba_enum);
227
228	void executeTestCase(const testCase& test_case);
229
230	virtual bool fillSourceTexture(size_t format_idx, size_t target_idx);
231
232	std::string getFragmentShader(const testCase& test_case, size_t output_format_index, bool is_tested_stage);
233
234	std::string getVertexShader(const testCase& test_case, bool is_tested_stage);
235
236	bool isTargetSupported(size_t target_idx);
237
238	bool isTargetSuppByAccess(size_t access_idx, size_t target_idx);
239
240	bool isTargetSuppByFormat(size_t format_idx, size_t target_idx);
241
242	void logTestCaseDetials(const testCase& test_case);
243
244	void prepareAndTestProgram(const testCase& test_case, size_t output_format_index, glw::GLint output_channel_size,
245							   size_t index_of_swizzled_channel, bool test_vertex_stage);
246
247	std::string prepareArguments(const testCase& test_case);
248	std::string prepareCoordinates(const testCase& test_case);
249
250	std::string prepareDerivatives(const testCase& test_case, size_t index);
251
252	std::string prepareOffsets(const testCase& test_case);
253	void prepareOutputTexture(size_t format_idx);
254
255	std::string prepareSample();
256	void prepareSourceTexture(size_t format_idx, size_t target_idx, glw::GLint out_sizes[4]);
257
258	void testInit();
259
260	virtual void verifyOutputImage(const testCase& test_case, size_t output_format_index,
261								   glw::GLint output_channel_size, size_t index_of_swizzled_channel,
262								   const glw::GLubyte* data);
263
264	/* Protected fields */
265	bool		m_is_ms_supported;
266	glw::GLuint m_prepare_fbo_id;
267	glw::GLuint m_out_tex_id;
268	glw::GLuint m_source_tex_id;
269	glw::GLuint m_test_fbo_id;
270	glw::GLuint m_vao_id;
271
272	/* Protected constants */
273	static const glw::GLsizei m_depth;
274	static const glw::GLsizei m_height;
275	static const glw::GLsizei m_width;
276	static const glw::GLsizei m_output_height;
277	static const glw::GLsizei m_output_width;
278};
279
280/** Implements Functional test, description follows:
281 *
282 * Verifies that swizzle is respected for textures of different formats and
283 * targets.
284 *
285 * Modify Smoke in the following aspects:
286 * - repeat the steps for all supported sized internal formats and
287 * texture targets;
288 * - repeat the steps for the texture_swizzle combinations listed below;
289 * - use only texelFetch routine.
290 *
291 * List of texture_swizzle combinations to test:
292 * - ABGR,
293 * - 01RA,
294 * - 0000,
295 * - 1111,
296 * - BBBB.
297 *
298 * Depth-stencil textures can be sampled only via RED channel. Test should set
299 * DEPTH_STENCIL_TEXTURE_MODE to select which channel will be accessed.
300 *
301 * For multisampled targets maximum supported number of samples should be used
302 * and fetch should be done to last sample.
303 *
304 * Support of multisampled targets by TexParameter* routines was introduced in
305 * extension GL_ARB_texture_storage_multisample, which is part of core
306 * specification since 4.3. Therefore texture_swizzle functionality may be used
307 * with multisampled targets only if either context is at least 4.3 or
308 * extension GL_ARB_texture_storage_multisample is supported.
309 **/
310class FunctionalTest : public SmokeTest
311{
312public:
313	/* Public methods */
314	FunctionalTest(deqp::Context& context);
315
316	virtual tcu::TestNode::IterateResult iterate();
317
318protected:
319	/* Protected methods */
320	virtual bool fillSourceTexture(size_t format_idx, size_t target_idx);
321
322	bool fillMSTexture(size_t format_idx, size_t target_idx);
323
324	void prepareProgram(size_t format_idx, Utils::programInfo& program);
325
326	std::string prepareValues(size_t format_idx);
327
328	virtual void verifyOutputImage(const testCase& test_case, size_t output_format_index,
329								   glw::GLint output_channel_size, size_t index_of_swizzled_channel,
330								   const glw::GLubyte* data);
331
332private:
333	/* Private types */
334	class wrongResults : public std::exception
335	{
336	public:
337		wrongResults(const FunctionalTest::testCase& test_case) : m_test_case(test_case)
338		{
339		}
340
341		virtual ~wrongResults() throw()
342		{
343		}
344
345		virtual const char* what() const throw()
346		{
347			return "Found pixel with wrong value";
348		}
349
350		FunctionalTest::testCase m_test_case;
351	};
352};
353}
354
355/** Group class for GPU Shader 5 conformance tests */
356class TextureSwizzleTests : public deqp::TestCaseGroup
357{
358public:
359	/* Public methods */
360	TextureSwizzleTests(deqp::Context& context);
361	virtual ~TextureSwizzleTests()
362	{
363	}
364
365	virtual void init(void);
366
367private:
368	/* Private methods */
369	TextureSwizzleTests(const TextureSwizzleTests&);
370	TextureSwizzleTests& operator=(const TextureSwizzleTests&);
371};
372} /* gl3cts namespace */
373
374#endif // _GL3CTEXTURESWIZZLETESTS_HPP
375