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
36namespace glcts
37{
38
39/** Class to store test configuration
40 */
41template <typename InputType, typename OutputType>
42class TestConfiguration
43{
44public:
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
54	virtual ~TestConfiguration()
55	{
56	}
57
58	inline glw::GLsizei get_n_in_components(void) const
59	{
60		return m_n_in_components;
61	}
62	inline glw::GLsizei get_n_out_components(void) const
63	{
64		return m_n_out_components;
65	}
66	inline glw::GLenum get_target(void) const
67	{
68		return m_target;
69	}
70	inline glw::GLenum get_input_internal_format(void) const
71	{
72		return m_input_internal_format;
73	}
74	inline glw::GLenum get_output_internal_format(void) const
75	{
76		return m_output_internal_format;
77	}
78	inline glw::GLenum get_filtering(void) const
79	{
80		return m_filtering;
81	}
82	inline glw::GLenum get_input_format(void) const
83	{
84		return m_input_format;
85	}
86	inline glw::GLenum get_output_format(void) const
87	{
88		return m_output_format;
89	}
90	inline glw::GLuint get_width(void) const
91	{
92		return m_width;
93	}
94	inline glw::GLuint get_height(void) const
95	{
96		return m_height;
97	}
98	inline glw::GLuint get_depth(void) const
99	{
100		return m_depth;
101	}
102	inline InputType get_init_value(void) const
103	{
104		return m_init_value;
105	}
106	inline InputType get_init_border_color(void) const
107	{
108		return m_init_border_color;
109	}
110	inline OutputType get_expected_value(void) const
111	{
112		return m_expected_value;
113	}
114	inline OutputType get_expected_border_color(void) const
115	{
116		return m_expected_border_color;
117	}
118	inline glw::GLenum get_input_type(void) const
119	{
120		return m_input_type;
121	}
122	inline glw::GLenum get_output_type(void) const
123	{
124		return m_output_type;
125	}
126
127private:
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 */
291template <typename InputType, typename OutputType>
292class TextureBorderClampSamplingTexture : public TestCaseBase
293{
294public:
295	/* Public methods */
296	TextureBorderClampSamplingTexture(Context& context, const ExtParameters& extParams, const char* name,
297									  const char* description,
298									  const TestConfiguration<InputType, OutputType>& configuration);
299
300	virtual ~TextureBorderClampSamplingTexture()
301	{
302	}
303
304	virtual void		  deinit(void);
305	virtual IterateResult iterate(void);
306
307private:
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