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 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 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 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