1 #ifndef _ESEXTCTEXTUREBORDERCLAMPSAMPLINGTEXTURE_HPP
2 #define _ESEXTCTEXTUREBORDERCLAMPSAMPLINGTEXTURE_HPP
3 /*-------------------------------------------------------------------------
4  * OpenGL Conformance Test Suite
5  * -----------------------------
6  *
7  * Copyright (c) 2014-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 esextcTextureBorderClampSamplingTexture.hpp
28  * \brief Verify that sampling a texture with GL_CLAMP_TO_BORDER_EXT
29  * wrap mode enabled gives correct results (Test 7)
30  */ /*-------------------------------------------------------------------*/
31 
32 #include "../esextcTestCaseBase.hpp"
33 #include "glwEnums.hpp"
34 #include <vector>
35 
36 namespace glcts
37 {
38 
39 /** Class to store test configuration
40  */
41 template <typename InputType, typename OutputType>
42 class TestConfiguration
43 {
44 public:
45 	/* Public functions */
46 	TestConfiguration(glw::GLsizei nInputComponents, glw::GLsizei nOutputComponents, glw::GLenum target,
47 					  glw::GLenum inputInternalFormat, glw::GLenum outputInternalFormat, glw::GLenum filtering,
48 					  glw::GLenum inputFormat, glw::GLenum outputFormat, glw::GLuint width, glw::GLuint height,
49 					  glw::GLuint depth, InputType initValue, InputType initBorderColor, OutputType expectedValue,
50 					  OutputType expectedBorderColor, glw::GLenum inputType, glw::GLenum outputType);
51 
52 	TestConfiguration(const TestConfiguration& configuration);
53 
~TestConfiguration()54 	virtual ~TestConfiguration()
55 	{
56 	}
57 
get_n_in_components(void) const58 	inline glw::GLsizei get_n_in_components(void) const
59 	{
60 		return m_n_in_components;
61 	}
get_n_out_components(void) const62 	inline glw::GLsizei get_n_out_components(void) const
63 	{
64 		return m_n_out_components;
65 	}
get_target(void) const66 	inline glw::GLenum get_target(void) const
67 	{
68 		return m_target;
69 	}
get_input_internal_format(void) const70 	inline glw::GLenum get_input_internal_format(void) const
71 	{
72 		return m_input_internal_format;
73 	}
get_output_internal_format(void) const74 	inline glw::GLenum get_output_internal_format(void) const
75 	{
76 		return m_output_internal_format;
77 	}
get_filtering(void) const78 	inline glw::GLenum get_filtering(void) const
79 	{
80 		return m_filtering;
81 	}
get_input_format(void) const82 	inline glw::GLenum get_input_format(void) const
83 	{
84 		return m_input_format;
85 	}
get_output_format(void) const86 	inline glw::GLenum get_output_format(void) const
87 	{
88 		return m_output_format;
89 	}
get_width(void) const90 	inline glw::GLuint get_width(void) const
91 	{
92 		return m_width;
93 	}
get_height(void) const94 	inline glw::GLuint get_height(void) const
95 	{
96 		return m_height;
97 	}
get_depth(void) const98 	inline glw::GLuint get_depth(void) const
99 	{
100 		return m_depth;
101 	}
get_init_value(void) const102 	inline InputType get_init_value(void) const
103 	{
104 		return m_init_value;
105 	}
get_init_border_color(void) const106 	inline InputType get_init_border_color(void) const
107 	{
108 		return m_init_border_color;
109 	}
get_expected_value(void) const110 	inline OutputType get_expected_value(void) const
111 	{
112 		return m_expected_value;
113 	}
get_expected_border_color(void) const114 	inline OutputType get_expected_border_color(void) const
115 	{
116 		return m_expected_border_color;
117 	}
get_input_type(void) const118 	inline glw::GLenum get_input_type(void) const
119 	{
120 		return m_input_type;
121 	}
get_output_type(void) const122 	inline glw::GLenum get_output_type(void) const
123 	{
124 		return m_output_type;
125 	}
126 
127 private:
128 	/* Private variables */
129 	glw::GLsizei m_n_in_components;
130 	glw::GLsizei m_n_out_components;
131 	glw::GLenum  m_target;
132 	glw::GLenum  m_input_internal_format;
133 	glw::GLenum  m_output_internal_format;
134 	glw::GLenum  m_filtering;
135 	glw::GLenum  m_input_format;
136 	glw::GLenum  m_output_format;
137 	glw::GLuint  m_width;
138 	glw::GLuint  m_height;
139 	glw::GLuint  m_depth;
140 	InputType	m_init_value;
141 	InputType	m_init_border_color;
142 	OutputType   m_expected_value;
143 	OutputType   m_expected_border_color;
144 	glw::GLenum  m_input_type;
145 	glw::GLenum  m_output_type;
146 };
147 
148 /*   Implementation of Test 7 from CTS_EXT_texture_border_clamp. Description follows
149  *
150  *    Verify that sampling a texture with GL_CLAMP_TO_BORDER_EXT wrap mode
151  *    enabled for all R/S/T dimensions gives correct results.
152  *
153  *    Category:           Functional test;
154  *
155  *    Suggested priority: Must-have.
156  *
157  *    This test should iterate over the following texture targets supported by
158  *    ES3.1:
159  *
160  *    - 2D textures;
161  *    - 2D array textures;
162  *    - 3D textures;
163  *
164  *    (note that cube-map texture targets are left out, as seamless filtering
165  *    renders the border color effectively useless)
166  *
167  *    For each texture target, the test should iterate over the following the
168  *    set of internal formats:
169  *
170  *    - GL_RGBA32F;
171  *    - GL_R32UI;
172  *    - GL_R32I;
173  *    - GL_RGBA8;
174  *    - GL_DEPTH_COMPONENT32F;
175  *    - GL_DEPTH_COMPONENT16;
176  *    - At least one compressed internal format described in the extension
177  *    specification.
178  *
179  *    Note: For glCompressedTexImage2D() or glCompressedTexImage3D() calls,
180  *          it is expected that predefined valid blobs will be used.
181  *
182  *    The texture size used in the test should be 256x256 for 2d textures,
183  *    256x256x6 for 2d array textures and 3d textures (smaller sizes are
184  *    allowed for compressed internal format).
185  *
186  *    For each texture we should have two iterations, one with GL_LINEAR
187  *    minification filtering, the second with GL_NEAREST minification
188  *    filtering.
189  *
190  *    Reference texture data should be as follows:
191  *
192  *    * Floating-point:         (0.0, 0.0, 0.0, 0.0);
193  *    * Unsigned integer:       (0);
194  *    * Signed integer:         (0);
195  *    * Normalized fixed-point: (0, 0, 0, 0);
196  *    * Depth (floating-point): (0.0);
197  *    * Depth (unsigned short): (0);
198  *
199  *    The border color should be set to:
200  *
201  *    * Floating-point:         (1.0, 1.0, 1.0, 1.0);
202  *    * Unsigned integer:       (255, 255, 255, 255);
203  *    * Signed integer:         (255, 255, 255, 255);
204  *    * Normalized fixed-point: (255, 255, 255, 255);
205  *    * Depth (floating-point): (1.0, 1.0, 1.0, 1.0);
206  *    * Depth (unsigned short): (255, 255, 255, 255);
207  *
208  *    In each iteration, the test should render a full-screen quad to
209  *    a two-dimensional texture of resolution 256x256 (smaller sizes are
210  *    allowed for compressed internal format) and internal format
211  *    compatible with the format of the texture used in this iteration
212  *    (we take into account that values stored in floating-point textures
213  *    are bigger than 0.0 and smaller than 1.0):
214  *
215  *    - GL_RGBA8;
216  *    - GL_R32UI;
217  *    - GL_R32I;
218  *    - GL_RGBA8;
219  *    - GL_R8;
220  *    - GL_R8;
221  *
222  *    The following UVs should be outputted by the vertex shader:
223  *
224  *    - (-1, -1) for bottom-left corner of the viewport;
225  *    - (-1,  2) for top-left corner of the viewport;
226  *    - ( 2,  2) for top-right corner of the viewport;
227  *    - ( 2, -1) for bottom-right corner of the viewport;
228  *
229  *    The fragment shader should sample an iteration-specific texture sampler
230  *    at given UV location. The shader should output the result of this
231  *    sampling as the color value.
232  *
233  *    The test succeeds, if result texture is valid for all texture target +
234  *    internal format combinations.
235  *
236  *    Verification process for each iteration should be as follows:
237  *
238  *    1) Download rendered data to process space;
239  *    2) The expected rendering outcome for GL_NEAREST minification filtering
240  *    is as depicted below:
241  *
242  *                 (-1, -1)    (0, -1)  (1,  -1)     (2, -1)
243  *                         *-------+-------+-------*
244  *                         |       |       |       |
245  *                         |  BC   |  BC   |   BC  |
246  *                         |       |       |       |
247  *                 (-1, 0) +-------+-------+-------+ (2, 0)
248  *                         |       |       |       |
249  *                         |  BC   |   0   |   BC  |
250  *                         |       |       |       |
251  *                 (-1, 1) +-------+-------+-------+ (2, 1)
252  *                         |       |       |       |
253  *                         |  BC   |  BC   |   BC  |
254  *                         |       |       |       |
255  *                         *-------+-------+-------*
256  *                 (-1, 2)      (0, 2)  (1, 2)       (2, 2)
257  *
258  *    BC means the border color for the used internal format.
259  *
260  *    Values in the brackets correspond to UV space. Top-left corner corresponds
261  *    to bottom-left corner of the data in GL orientation (that is: as retrieved
262  *    by glReadPixels() call).
263  *
264  *    Note for 2D array texture: assuming a texture of depth n_layers,
265  *    for which 0..n_layers-1 have been defined (inclusive), the test should
266  *    sample data from -1, 0 .. n_layers layers. It is expected that for sampling
267  *    outside of <0, n_layers-1> set of layers the layer number will be clamped
268  *    the the range <0, n_layers-1>. This means that result textures for border
269  *    cases should be the same as for sampling from inside of <0, n_layers-1>
270  *    range.
271  *
272  *    Note for 3D texture: assuming a texture of depth n_layers,
273  *    for which 0..n_layers-1 have been defined (inclusive), the test should
274  *    sample data from -1, 0 .. n_layers layers. It is expected that sampling
275  *    outside <0, n_layers-1> set of layers or slices of the texture should
276  *    return the border color defined for the texture object being sampled.
277  *    This means that result textures for border cases should be completely
278  *    filled with BC color.
279  *
280  *    Iteration passes if centres of all rectangles contain the correct colors.
281  *
282  *    3) The expected rendering outcome for GL_LINEAR minification filtering is
283  *    to some extent similar to the one for GL_NEAREST, with the difference that
284  *    the transition between 0 and BC values is smooth (some values in between 0
285  *    and BC may appear on the edge of the rectangles). For this case we need
286  *    a different way of checking if the rendering outcome is correct. We should
287  *    start in the middle of the texture and check values of texels moving in four
288  *    directions - to the left, right, bottom, top. In each direction the values of
289  *    the texels should form a monotonically increasing series.
290  */
291 template <typename InputType, typename OutputType>
292 class TextureBorderClampSamplingTexture : public TestCaseBase
293 {
294 public:
295 	/* Public methods */
296 	TextureBorderClampSamplingTexture(Context& context, const ExtParameters& extParams, const char* name,
297 									  const char* description,
298 									  const TestConfiguration<InputType, OutputType>& configuration);
299 
~TextureBorderClampSamplingTexture()300 	virtual ~TextureBorderClampSamplingTexture()
301 	{
302 	}
303 
304 	virtual void		  deinit(void);
305 	virtual IterateResult iterate(void);
306 
307 private:
308 	/* Private methods */
309 	void initTest(void);
310 	void setInitData(std::vector<InputType>& buffer);
311 	void checkFramebufferStatus(glw::GLenum framebuffer);
312 	bool checkResult(OutputType expectedValue, OutputType expectedBorderColor, glw::GLint layer);
313 	bool checkNearest(std::vector<OutputType>& buffer, OutputType expectedValue, OutputType expectedBorderColor,
314 					  glw::GLint layer);
315 	bool checkLinear(std::vector<OutputType>& buffer, glw::GLint layer);
316 	void		 createTextures(void);
317 	glw::GLfloat getCoordinateValue(glw::GLint index);
318 	std::string getFragmentShaderCode(void);
319 	std::string getVertexShaderCode(void);
320 	glw::GLint  getStartingLayerIndex();
321 	glw::GLint  getLastLayerIndex();
322 
323 	/* Private variables */
324 	glw::GLint  m_attr_position_location;
325 	glw::GLint  m_attr_texcoord_location;
326 	glw::GLuint m_fbo_id;
327 	glw::GLuint m_fs_id;
328 	glw::GLuint m_po_id;
329 	glw::GLuint m_sampler_id;
330 	TestConfiguration<InputType, OutputType> m_test_configuration;
331 	glw::GLuint m_input_to_id;
332 	glw::GLuint m_output_to_id;
333 	glw::GLuint m_position_vbo_id;
334 	glw::GLuint m_text_coord_vbo_id;
335 	glw::GLuint m_vs_id;
336 	glw::GLuint m_vao_id;
337 
338 	/* Private static variables */
339 	static const glw::GLuint m_texture_unit;
340 };
341 
342 } // namespace glcts
343 
344 #endif // _ESEXTCTEXTUREBORDERCLAMPSAMPLINGTEXTURE_HPP
345