1 #ifndef _GL3CTEXTURESIZEPROMOTION_HPP
2 #define _GL3CTEXTURESIZEPROMOTION_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  gl3cTextureSizePromotionTests.hpp
28  * \brief Declares test classes for testing of texture internal format
29  promotion mechanism.
30  */ /*-------------------------------------------------------------------*/
31 
32 #include "glcTestCase.hpp"
33 #include "glwDefs.hpp"
34 #include "glwEnums.hpp"
35 #include "tcuDefs.hpp"
36 #include "tcuVector.hpp"
37 
38 namespace gl3cts
39 {
40 namespace TextureSizePromotion
41 {
42 /** Test group class for texture size promotion tests */
43 class Tests : public deqp::TestCaseGroup
44 {
45 public:
46 	/* Public member functions. */
47 	Tests(deqp::Context& context); //!< Constructor.
~Tests()48 	virtual ~Tests()
49 	{
50 	} //!< Destructor
51 
52 	virtual void init(void); //!< Initialization member function.
53 
54 private:
55 	/* Private member functions. */
56 	Tests(const Tests&);			//!< Default copy constructor.
57 	Tests& operator=(const Tests&); //!< Default assign constructor.
58 };
59 
60 /** Functional Test Class
61  *
62  *  This test verifies that implementation correctly selects sizes and types
63  *  when sized internal format is requested for a texture.
64  *
65  *  This test should be executed only if context is at least 3.1.
66  *
67  *  Steps:
68  *   - prepare a source texture so that each channel is filled with specific value;
69  *   - execute GetTexLevelPrameter to query all TEXTURE_*_SIZE and TEXTURE_*_TYPE
70  *     <pname>s corresponding with internal format of source texture; It is
71  *     expected that:
72  *      * reported sizes will be at least as specified;
73  *      * reported types will be exactly as specified;
74  *   - for each channel [R, G, B, A]:
75  *      * prepare a 2D single channeled texture with format matching sampled
76  *        channel and set it up as output color in framebuffer;
77  *      * prepare a program that will implement the following snippet in the
78  *        fragment stage and output the value of result:
79  *
80  *            result = texelFetch(source).C;
81  *
82  *      * clear output texture;
83  *      * draw a full-screen quad;
84  *      * verify that the output texture is filled with correct value;
85  *
86  *  Value is correct when:
87  *   - it matches value assigned to the specified channel;
88  *   - it is one for missing alpha channel;
89  *   - it is zero for missing channel;
90  *   - it is one for ONE;
91  *   - it is zero for ZERO.
92  *
93  *  Repeat the steps for all supported sized internal formats and targets.
94  *
95  *  Depth-stencil textures can be sampled only via RED channel. Test should set
96  *  DEPTH_STENCIL_TEXTURE_MODE to select which channel will be accessed.
97  *
98  *  For multisampled targets maximum supported number of samples should be used
99  *  and fetch should be done to last sample.
100  *
101  *  Support of multisampled targets by TexParameter* routines was introduced in
102  *  extension GL_ARB_texture_storage_multisample, which is part of core
103  *  specification since 4.3.
104  *
105  *  List of required texture formats was changed in 4.4. Therefore the list of
106  *  "supported sized internal formats" depends on context version.
107  */
108 class FunctionalTest : public deqp::TestCase
109 {
110 public:
111 	/* Public member functions. */
112 	FunctionalTest(deqp::Context& context);			//!< Functional test constructor.
113 	virtual tcu::TestNode::IterateResult iterate(); //!< Member function to iterate over test cases.
114 
115 private:
116 	/* Private member variables. */
117 	glw::GLuint m_vao;				   //!< Vertex Array Object name.
118 	glw::GLuint m_source_texture;	  //!< Source Texture  Object name.
119 	glw::GLuint m_destination_texture; //!< Destination Texture Object name.
120 	glw::GLuint m_framebuffer;		   //!< Framebuffer Object name.
121 	glw::GLuint m_program;			   //!< Program Object name.
122 	glw::GLint  m_max_samples;		   //!< Maximum samples available for usage in multisampled targets.
123 
124 	/* Private type definitions. */
125 
126 	/** Texture Internal Format Description structure
127 	 */
128 	struct TextureInternalFormatDescriptor
129 	{
130 		glu::ContextType   required_by_context;  //!< Minimum context version by which format is required.
131 		glw::GLenum		   internal_format;		 //!< Texture internal format.
132 		const glw::GLchar* internal_format_name; //!< String representing texture internal format.
133 		bool			   is_sRGB;				 //!< Is this format described in sRGB space.
134 		bool			   is_color_renderable;  //!< Is this format color renderable.
135 
136 		glw::GLint min_red_size;	 //!< Minimum required red     component resolution (in bits).
137 		glw::GLint min_green_size;   //!< Minimum required green   component resolution (in bits).
138 		glw::GLint min_blue_size;	//!< Minimum required blue    component resolution (in bits).
139 		glw::GLint min_alpha_size;   //!< Minimum required alpha   component resolution (in bits).
140 		glw::GLint min_depth_size;   //!< Minimum required depth   component resolution (in bits).
141 		glw::GLint min_stencil_size; //!< Minimum required stencil component resolution (in bits).
142 
143 		glw::GLenum expected_red_type;   //!< Expected type of red   component.
144 		glw::GLenum expected_green_type; //!< Expected type of green component.
145 		glw::GLenum expected_blue_type;  //!< Expected type of blue  component.
146 		glw::GLenum expected_alpha_type; //!< Expected type of alpha component.
147 		glw::GLenum expected_depth_type; //!< Expected type of depth component.
148 	};
149 
150 	/** Color channels enumeration
151 	 */
152 	enum ColorChannelSelector
153 	{
154 		RED_COMPONENT,   //!< Red   component.
155 		GREEN_COMPONENT, //!< Green component.
156 		BLUE_COMPONENT,  //!< Blue  component.
157 		ALPHA_COMPONENT, //!< Alpha component (must be last color channel).
158 		COMPONENTS_COUNT //!< Number of components.
159 	};
160 
161 	/* Private class' static constants. */
162 	static const glw::GLfloat s_source_texture_data_f[]; //!< Source texture for floating point type internal formats.
163 	static const glw::GLfloat
164 		s_source_texture_data_n[]; //!< Source texture for unsigned normalized integer type internal formats.
165 	static const glw::GLfloat
166 							 s_source_texture_data_sn[]; //!< Source texture for signed normalized integer type internal formats.
167 	static const glw::GLint  s_source_texture_data_i[];  //!< Source texture for signed integer type internal formats.
168 	static const glw::GLuint s_source_texture_data_ui[]; //!< Source texture for unsigned integer type internal formats.
169 	static const glw::GLuint s_source_texture_size;		 //!< Linear size of the source texture.
170 	static const glw::GLfloat s_destination_texture_data_f
171 		[]; //!< Destination texture data (to be sure that it was overwritten) for floating point and normalized types internal formats.
172 	static const glw::GLint s_destination_texture_data_i
173 		[]; //!< Destination texture data (to be sure that it was overwritten) signed integer type internal formats.
174 	static const glw::GLuint s_destination_texture_data_ui
175 		[]; //!< Destination texture data (to be sure that it was overwritten) unsigned integer type internal formats.
176 
177 	static const glw::GLenum  s_source_texture_targets[];		//!< Targets to be tested.
178 	static const glw::GLchar* s_source_texture_targets_names[]; //!< Targets' names (strings) for logging purpose.
179 	static const glw::GLuint  s_source_texture_targets_count;   //!< Number of targets to be tested.
180 
181 	static const glw::GLchar* s_color_channel_names[]; //!< Color channel names (like in enum) for logging purpose.
182 
183 	static const glw::GLchar*
184 							  s_vertex_shader_code; //!< Vertex shader source code for drawing quad depending on vertex ID of triangle strip.
185 	static const glw::GLchar* s_fragment_shader_template; //!< Fragment shader source code template.
186 
187 	static const TextureInternalFormatDescriptor
188 							 s_formats[]; //!< List of internal formats (and their descriptions) to be tested by Functional Test.
189 	static const glw::GLuint s_formats_size; //!< number of internal format to be tested.
190 
191 	/* Private member functions. */
192 
193 	/** Generate and bind an empty Vertex Array Object.
194 	 */
195 	void prepareVertexArrayObject();
196 
197 	/** Generate, bind and upload source texture.
198 	 *
199 	 *  @param [in] descriptor      Internal format description.
200 	 *  @param [in] target          Texture target to be used.
201 	 */
202 	void prepareSourceTexture(TextureInternalFormatDescriptor descriptor, glw::GLenum target);
203 
204 	/** Generate, bind and clean destination texture.
205 	 *
206 	 *  @param [in] descriptor      Internal format description.
207 	 *  @param [in] target          Texture target to be used.
208 	 */
209 	void prepareDestinationTextureAndFramebuffer(TextureInternalFormatDescriptor descriptor, glw::GLenum target);
210 
211 	/** Preprocess, compile and linke GLSL program.
212 	 *
213 	 *  @param [in] target          Texture target to be used.
214 	 *  @param [in] descriptor      Internal format description.
215 	 *  @param [in] channel         Color channel to be tested.
216 	 *
217 	 *  @return Program name on success, 0 on failure.
218 	 */
219 	glw::GLuint prepareProgram(glw::GLenum target, TextureInternalFormatDescriptor descriptor,
220 							   ColorChannelSelector channel);
221 
222 	/** Use GLSL program with source and destination textures.
223 	 *
224 	 *  @param [in] target          Texture target to be used.
225 	 */
226 	void makeProgramAndSourceTextureActive(glw::GLenum target);
227 
228 	/** Check source texture queries.
229 	 *
230 	 *  @param [in] descriptor      Internal format description.
231 	 *  @param [in] target          Texture target to be used.
232 	 */
233 	bool checkSourceTextureSizeAndType(TextureInternalFormatDescriptor descriptor, glw::GLenum target);
234 
235 	/** Draw quad using GL_TRIANGLE_STRIP.
236 	 */
237 	void drawQuad();
238 
239 	/** Check rendered destination texture to match expected values.
240 	 *
241 	 *  @param [in] descriptor      Internal format description.
242 	 *  @param [in] channel         Used color channel.
243 	 *  @param [in] target          Texture target to be used.
244 	 *  @param [in] target_name     Texture target name for logging purposes.
245 	 *
246 	 *  @return True if fetched value matches expected value within the range of precission, false otherwise.
247 	 */
248 	bool checkDestinationTexture(TextureInternalFormatDescriptor descriptor, ColorChannelSelector channel,
249 								 glw::GLenum target, const glw::GLchar* target_name);
250 
251 	/** Clean source texture object.
252 	 */
253 	void cleanSourceTexture();
254 
255 	/** Clean framebuffer object.
256 	 */
257 	void cleanFramebuffer();
258 
259 	/** Clean destination texture object.
260 	 */
261 	void cleanDestinationTexture();
262 
263 	/** Clean program object.
264 	 */
265 	void cleanProgram();
266 
267 	/** Clean vertex array object object.
268 	 */
269 	void cleanVertexArrayObject();
270 
271 	/** Choose internal format of destination texture for rendered source texture.
272 	 *
273 	 *  @param [in] descriptor      Internal format description.
274 	 */
275 	glw::GLenum getDestinationFormatForChannel(TextureInternalFormatDescriptor descriptor);
276 
277 	/** Is internal format a floating type.
278 	 *
279 	 *  @param [in] descriptor      Internal format description.
280 	 *
281 	 *  @return True if internal format is floating point type, false otherwise.
282 	 */
283 	bool isFloatType(TextureInternalFormatDescriptor descriptor);
284 
285 	/** Is internal format a fixed signed type.
286 	 *
287 	 *  @param [in] descriptor      Internal format description.
288 	 *
289 	 *  @return True if internal format is fixed signed type, false otherwise.
290 	 */
291 	bool isFixedSignedType(TextureInternalFormatDescriptor descriptor);
292 
293 	/** Is internal format a fixed unsigned type.
294 	 *
295 	 *  @param [in] descriptor      Internal format description.
296 	 *
297 	 *  @return True if internal format is fixed unsigned type, false otherwise.
298 	 */
299 	bool isFixedUnsignedType(TextureInternalFormatDescriptor descriptor);
300 
301 	/** Is internal format a signed integral type.
302 	 *
303 	 *  @param [in] descriptor      Internal format description.
304 	 *
305 	 *  @return True if internal format is integral signed type, false otherwise.
306 	 */
307 	bool isIntegerSignedType(TextureInternalFormatDescriptor descriptor);
308 
309 	/** Is internal format an unsigned integral type.
310 	 *
311 	 *  @param [in] descriptor      Internal format description.
312 	 *
313 	 *  @return True if internal format is integral unsigned type, false otherwise.
314 	 */
315 	bool isIntegerUnsignedType(TextureInternalFormatDescriptor descriptor);
316 
317 	/** Is internal format a depth type.
318 	 *
319 	 *  @param [in] descriptor      Internal format description.
320 	 *
321 	 *  @return True if internal format is depth type, false otherwise.
322 	 */
323 	bool isDepthType(TextureInternalFormatDescriptor descriptor);
324 
325 	/** Is internal format a stencil type.
326 	 *
327 	 *  @param [in] descriptor      Internal format description.
328 	 *
329 	 *  @return True if internal format is stencil type, false otherwise.
330 	 */
331 	bool isStencilType(TextureInternalFormatDescriptor descriptor);
332 
333 	/** Is channel of internal format a none type (does not appear in the texture internal format).
334 	 *
335 	 *  @param [in] descriptor      Internal format description.
336 	 *  @param [in] channel         Color channel to be queried.
337 	 *
338 	 *  @return True if internal format is none type, false otherwise.
339 	 */
340 	bool isChannelTypeNone(TextureInternalFormatDescriptor descriptor, ColorChannelSelector channel);
341 
342 	/** Calculate minimal required precission for internal format's channel.
343 	 *
344 	 *  @note It is needed only for floating point and normalized fixed point types.
345 	 *
346 	 *  @param [in] descriptor      Internal format description.
347 	 *  @param [in] channel         Color channel to be queried.
348 	 *
349 	 *  @return Minimum precission.
350 	 */
351 	glw::GLfloat getMinPrecision(TextureInternalFormatDescriptor descriptor, ColorChannelSelector channel);
352 
353 	/** Is target multisample.
354 	 *
355 	 *  @param [in] target      Target.
356 	 *
357 	 *  @return True if target is multisampled, false otherwise.
358 	 */
359 	bool isTargetMultisampled(glw::GLenum target);
360 
361 	/** Render data to the source texture for multisampled texture.
362 	 *
363 	 *  @param [in] descriptor      Internal format description.
364 	 *  @param [in] target          Texture target to be used.
365 	 */
366 	void renderDataIntoMultisampledTexture(TextureInternalFormatDescriptor descriptor, glw::GLenum target);
367 
368 	/** Convert value from sRGB space to linear space.
369 	 *
370 	 *  @param [in] value           Value to be converted (sRGB space).
371 	 *
372 	 *  @return Converted value (linear space).
373 	 */
374 	float convert_from_sRGB(float value);
375 };
376 /* class TextureSizePromotion */
377 
378 namespace Utilities
379 {
380 /** Build a GLSL program
381  *
382  *  @param [in]  gl                                     OpenGL Functions Access.
383  *  @param [in]  log                                    Log outut.
384  *  @param [in]  vertex_shader_source                   Pointer to C string of the vertex shader or NULL if not used.
385  *  @param [in]  fragment_shader_source                 Pointer to C string of the fragment shader or NULL if not used.
386  *
387  *  @return OpenGL program shader ID or zero if error had occured.
388  */
389 glw::GLuint buildProgram(glw::Functions const& gl, tcu::TestLog& log, glw::GLchar const* const vertex_shader_source,
390 						 glw::GLchar const* const fragment_shader_source);
391 
392 /** Preprocess source string by replacing key tokens with new values.
393  *
394  *  @param [in] source      Source string.
395  *  @param [in] key         Key, substring to be replaced.
396  *  @param [in] value       Value, substring to be substituted in place of key.
397  *
398  *  @return Preprocessed string.
399  */
400 std::string preprocessString(std::string source, std::string key, std::string value);
401 
402 /** @brief Convert an integer to a string.
403  *
404  *  @param [in] i       Integer to be converted.
405  *
406  *  @return String representing integer.
407  */
408 std::string itoa(glw::GLint i);
409 }
410 
411 } /* TextureSizePromotion namespace */
412 } /* gl3cts namespace */
413 
414 #endif // _GL3CTEXTURESIZEPROMOTION_HPP
415