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 
38 namespace gl3cts
39 {
40 namespace TextureSwizzle
41 {
42 class Utils
43 {
44 public:
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  **/
82 class APIErrorsTest : public deqp::TestCase
83 {
84 public:
85 	/* Public methods */
86 	APIErrorsTest(deqp::Context& context);
87 
88 	virtual void						 deinit();
89 	virtual tcu::TestNode::IterateResult iterate();
90 
91 private:
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  **/
116 class IntialStateTest : public deqp::TestCase
117 {
118 public:
119 	/* Public methods */
120 	IntialStateTest(deqp::Context& context);
121 
122 	virtual void						 deinit();
123 	virtual tcu::TestNode::IterateResult iterate();
124 
125 private:
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  **/
194 class SmokeTest : public deqp::TestCase
195 {
196 public:
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 
204 protected:
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  **/
310 class FunctionalTest : public SmokeTest
311 {
312 public:
313 	/* Public methods */
314 	FunctionalTest(deqp::Context& context);
315 
316 	virtual tcu::TestNode::IterateResult iterate();
317 
318 protected:
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 
332 private:
333 	/* Private types */
334 	class wrongResults : public std::exception
335 	{
336 	public:
wrongResults(const FunctionalTest::testCase & test_case)337 		wrongResults(const FunctionalTest::testCase& test_case) : m_test_case(test_case)
338 		{
339 		}
340 
~wrongResults()341 		virtual ~wrongResults() throw()
342 		{
343 		}
344 
what() const345 		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 */
356 class TextureSwizzleTests : public deqp::TestCaseGroup
357 {
358 public:
359 	/* Public methods */
360 	TextureSwizzleTests(deqp::Context& context);
~TextureSwizzleTests()361 	virtual ~TextureSwizzleTests()
362 	{
363 	}
364 
365 	virtual void init(void);
366 
367 private:
368 	/* Private methods */
369 	TextureSwizzleTests(const TextureSwizzleTests&);
370 	TextureSwizzleTests& operator=(const TextureSwizzleTests&);
371 };
372 } /* gl3cts namespace */
373 
374 #endif // _GL3CTEXTURESWIZZLETESTS_HPP
375