1 #ifndef _ESEXTCGPUSHADER5TEXTUREGATHEROFFSET_HPP 2 #define _ESEXTCGPUSHADER5TEXTUREGATHEROFFSET_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 esextcGPUShader5TextureGatherOffset.hpp 28 * \brief gpu_shader5 extension - texture gather offset tests (Test 9 and 10) 29 */ /*-------------------------------------------------------------------*/ 30 31 #include "../esextcTestCaseBase.hpp" 32 33 #include <string> 34 #include <vector> 35 36 namespace glcts 37 { 38 /** Base class for texture gather offset tests (9, 10 and 11) 39 * 40 **/ 41 class GPUShader5TextureGatherOffsetTestBase : public TestCaseBase 42 { 43 public: 44 /* Public methods */ 45 virtual void deinit(void); 46 virtual IterateResult iterate(void); 47 48 protected: 49 /* Protected types */ 50 struct VertexBufferInfo 51 { 52 const glw::GLchar* attribute_name; 53 glw::GLuint n_components; 54 glw::GLenum type; 55 glw::GLvoid* data; 56 glw::GLuint data_size; 57 }; 58 59 /* Protected methods */ 60 GPUShader5TextureGatherOffsetTestBase(Context& context, const ExtParameters& extParams, const char* name, 61 const char* description); 62 ~GPUShader5TextureGatherOffsetTestBase(void)63 virtual ~GPUShader5TextureGatherOffsetTestBase(void) 64 { 65 } 66 67 virtual void initTest(void); 68 69 /* To be implemented by inheriting classes */ 70 virtual void getBorderColor(glw::GLfloat out_color[4]) = 0; 71 virtual void getShaderParts(std::vector<const glw::GLchar*>& out_vertex_shader_parts) = 0; 72 73 virtual void getTextureInfo(glw::GLuint& out_width, glw::GLenum& out_texture_internal_format, 74 glw::GLenum& out_texture_format, glw::GLenum& out_texture_type, 75 glw::GLuint& out_bytes_per_pixel) = 0; 76 77 virtual void getTextureWrapMode(glw::GLenum& out_wrap_mode) = 0; 78 79 virtual void getTransformFeedBackDetails(glw::GLuint& buffer_size, 80 std::vector<const glw::GLchar*>& captured_varyings) = 0; 81 82 virtual void isTextureArray(bool& out_is_texture_array) = 0; 83 virtual void prepareTextureData(glw::GLubyte* data) = 0; 84 virtual void prepareVertexBuffersData(std::vector<VertexBufferInfo>& vertex_buffer_infos) = 0; 85 virtual bool verifyResult(const void* result_data) = 0; 86 87 /* Utilities */ 88 void logArray(const glw::GLint* data, unsigned int length, const char* description); 89 90 void logCoordinates(unsigned int index); 91 92 /* Protected fields */ 93 /* GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET and GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET pname values */ 94 glw::GLint m_min_texture_gather_offset; 95 glw::GLint m_max_texture_gather_offset; 96 97 /* Number of drawn vertices */ 98 static const unsigned int m_n_vertices; 99 100 /* Number of components in captured varyings */ 101 static const unsigned int m_n_components_per_varying; 102 103 private: 104 /* Private methods */ 105 void prepareProgramInput(); 106 void prepareTexture(); 107 void prepareVertexBufferInfoForCoordinates(); 108 void setCoordinatesData(glw::GLfloat x, glw::GLfloat y, unsigned int index); 109 void setCoordinatesData(glw::GLfloat x, glw::GLfloat y, glw::GLfloat z, unsigned int index); 110 111 /* Private fields */ 112 /* Program and shader ids */ 113 glw::GLuint m_fragment_shader_id; 114 glw::GLuint m_program_object_id; 115 glw::GLuint m_vertex_shader_id; 116 117 /* Vertex array object */ 118 glw::GLuint m_vertex_array_object_id; 119 120 /* Texture id */ 121 glw::GLuint m_texture_object_id; 122 123 /* Sampler id */ 124 glw::GLuint m_sampler_object_id; 125 126 /* Shaders' code */ 127 static const glw::GLchar* const m_fragment_shader_code; 128 std::vector<const glw::GLchar*> m_vertex_shader_parts; 129 130 /* Name of uniforms */ 131 static const glw::GLchar* const m_sampler_uniform_name; 132 static const glw::GLchar* const m_reference_sampler_uniform_name; 133 134 /* Vertex buffer infos */ 135 std::vector<VertexBufferInfo> m_vertex_buffer_infos; 136 std::vector<glw::GLuint> m_vertex_buffer_ids; 137 138 /* Texture info */ 139 bool m_is_texture_array; 140 glw::GLuint m_texture_bytes_per_pixel; 141 glw::GLenum m_texture_format; 142 glw::GLenum m_texture_internal_format; 143 glw::GLenum m_texture_type; 144 glw::GLuint m_texture_size; 145 glw::GLenum m_texture_wrap_mode; 146 147 /* Texture array length */ 148 static const unsigned int m_n_texture_array_length; 149 150 /* Name of varyings */ 151 std::vector<const glw::GLchar*> m_captured_varying_names; 152 153 /* Size of buffer used for transform feedback */ 154 glw::GLuint m_transform_feedback_buffer_size; 155 156 /* Buffer object used in transform feedback */ 157 glw::GLuint m_transform_feedback_buffer_object_id; 158 159 /* Storage for texture coordinates */ 160 std::vector<glw::GLfloat> m_coordinates_buffer_data; 161 162 /* Number of texture coordinates per vertex */ 163 unsigned int m_n_coordinates_components; 164 165 /* Name of texture coordinate attribute */ 166 static const glw::GLchar* const m_coordinates_attribute_name; 167 168 /* Configuration of texture coordinate values generation */ 169 static const int m_max_coordinate_value; 170 static const int m_min_coordinate_value; 171 static const int m_coordinate_resolution; 172 }; 173 174 /** Base class for test 9 and 11 175 * 176 **/ 177 class GPUShader5TextureGatherOffsetColorTestBase : public GPUShader5TextureGatherOffsetTestBase 178 { 179 protected: 180 /* Protected types */ 181 struct CapturedVaryings 182 { 183 glw::GLint without_offset_0[4]; 184 glw::GLint without_offset_1[4]; 185 glw::GLint without_offset_2[4]; 186 glw::GLint without_offset_3[4]; 187 188 glw::GLint with_offset_0[4]; 189 glw::GLint with_offset_1[4]; 190 glw::GLint with_offset_2[4]; 191 glw::GLint with_offset_3[4]; 192 }; 193 194 /* Protected methods */ 195 GPUShader5TextureGatherOffsetColorTestBase(Context& context, const ExtParameters& extParams, const char* name, 196 const char* description); 197 ~GPUShader5TextureGatherOffsetColorTestBase(void)198 virtual ~GPUShader5TextureGatherOffsetColorTestBase(void) 199 { 200 } 201 202 /* Virtual methods from GPUShader5TextureGatherOffsetTestBase */ 203 virtual void getBorderColor(glw::GLfloat out_color[4]); 204 205 virtual void getTextureInfo(glw::GLuint& out_size, glw::GLenum& out_texture_internal_format, 206 glw::GLenum& out_texture_format, glw::GLenum& out_texture_type, 207 glw::GLuint& out_bytes_per_pixel); 208 209 virtual void getTextureWrapMode(glw::GLenum& out_wrap_mode); 210 211 virtual void getTransformFeedBackDetails(glw::GLuint& out_buffer_size, 212 std::vector<const glw::GLchar*>& out_captured_varyings); 213 214 virtual void isTextureArray(bool& out_is_texture_array); 215 virtual void prepareTextureData(glw::GLubyte* data); 216 virtual bool verifyResult(const void* result_data); 217 218 /* Methods to be implemented by child classes */ 219 virtual bool checkResult(const CapturedVaryings& captured_data, unsigned int index, 220 unsigned int m_texture_size) = 0; 221 222 /* Utilities */ 223 void logVaryings(const CapturedVaryings& varyings); 224 225 private: 226 /* Texture size */ 227 static const glw::GLuint m_texture_size; 228 229 /* Number of varyings captured per vertex */ 230 unsigned int m_n_varyings_per_vertex; 231 }; 232 233 /** Base class for test 10 and 11 234 * 235 **/ 236 class GPUShader5TextureGatherOffsetDepthTestBase : public GPUShader5TextureGatherOffsetTestBase 237 { 238 protected: 239 /* Protected types */ 240 struct CapturedVaryings 241 { 242 glw::GLint floor_tex_coord[4]; 243 glw::GLint without_offset[4]; 244 glw::GLint with_offset[4]; 245 }; 246 247 /* Protected methods */ 248 GPUShader5TextureGatherOffsetDepthTestBase(Context& context, const ExtParameters& extParams, const char* name, 249 const char* description); 250 ~GPUShader5TextureGatherOffsetDepthTestBase(void)251 virtual ~GPUShader5TextureGatherOffsetDepthTestBase(void) 252 { 253 } 254 255 /* Virtual methods from GPUShader5TextureGatherOffsetTestBase */ 256 virtual void getBorderColor(glw::GLfloat out_color[4]); 257 258 virtual void getTextureInfo(glw::GLuint& out_width, glw::GLenum& out_texture_internal_format, 259 glw::GLenum& out_texture_format, glw::GLenum& out_texture_type, 260 glw::GLuint& out_bytes_per_pixel); 261 262 virtual void getTextureWrapMode(glw::GLenum& out_wrap_mode); 263 264 virtual void getTransformFeedBackDetails(glw::GLuint& out_buffer_size, 265 std::vector<const glw::GLchar*>& out_captured_varyings); 266 267 virtual void isTextureArray(bool& out_is_texture_array); 268 virtual void prepareTextureData(glw::GLubyte* data); 269 virtual bool verifyResult(const void* result_data); 270 271 /* Methods to be implemented by child classes */ 272 virtual bool checkResult(const CapturedVaryings& captured_data, unsigned int index, unsigned int texture_size) = 0; 273 274 virtual void getVaryings(std::vector<const glw::GLchar*>& out_captured_varyings); 275 276 /* Utilities */ 277 void logVaryings(const CapturedVaryings& varyings); 278 279 private: 280 /* Texture size */ 281 static const glw::GLuint m_texture_size; 282 283 /* Number of varyings captured per vertex */ 284 unsigned int m_n_varyings_per_vertex; 285 }; 286 287 /** Implementation of "Test 9" from CTS_EXT_gpu_shader5. Test description follows: 288 * 289 * Test whether using non constant offsets in the textureGatherOffset 290 * and constant offsets in the textureGatherOffsets family of 291 * functions works as expected for sampler2D and sampler2DArray and 292 * GL_REPEAT wrap mode. 293 * 294 * Category: API, 295 * Functional Test. 296 * 297 * Create a 64 x 64 texture with internal format GL_RGBA32I. 298 * 299 * Set both GL_TEXTURE_MIN_FILTER and GL_TEXTURE_MAG_FILTER to GL_NEAREST. 300 * 301 * Set both GL_TEXTURE_WRAP_S and GL_TEXTURE_WRAP_T to GL_REPEAT. 302 * 303 * Fill the 4 components of each texel with values corresponding to texel 304 * row and column number (x,y) -> (x,y,x,y) 305 * 306 * Write a vertex shader that defines: 307 * 308 * uniform isampler2D sampler; 309 * 310 * in ivec2 tgoOffset; 311 * in vec2 texCoords; 312 * 313 * out ivec4 withoutOffset0; 314 * out ivec4 withOffset0; 315 * 316 * out ivec4 withoutOffset1; 317 * out ivec4 withOffset1; 318 * 319 * out ivec4 withoutOffset2; 320 * out ivec4 withOffset2; 321 * 322 * out ivec4 withoutOffset3; 323 * out ivec4 withOffset3; 324 * 325 * Bind the sampler to texture unit the texture we created is assigned to. 326 * 327 * Initialize a buffer object to be assigned as input attribute tgoOffset 328 * data source. The buffer object should hold 128 integer tuples. Fill it 329 * with some random integer values but falling into a range of 330 * (MIN_PROGRAM_TEXTURE_GATHER_OFFSET, 331 * MAX_PROGRAM_TEXTURE_GATHER_OFFSET). 332 * 333 * Initialize a buffer object to be assigned as input attribute texCoords 334 * data source. The buffer object should hold 128 elements. Fill the first 335 * 4 tuples with (0.0, 0.0) , (0.0, 1.0), (1.0, 0.0), (1.0, 1.0) and the 336 * rest with some random float values in the range [-8.0..8.0]. 337 * 338 * In the vertex shader perform the following operation: 339 * 340 * withoutOffset0 = textureGather(sampler, texCoords, 0); 341 * withOffset0 = textureGatherOffset(sampler, texCoords, tgoOffset, 0); 342 * 343 * withoutOffset1 = textureGather(sampler, texCoords, 1); 344 * withOffset1 = textureGatherOffset(sampler, texCoords, tgoOffset, 1); 345 * 346 * withoutOffset2 = textureGather(sampler, texCoords, 2); 347 * withOffset2 = textureGatherOffset(sampler, texCoords, tgoOffset, 2); 348 * 349 * withoutOffset3 = textureGather(sampler, texCoords, 3); 350 * withOffset3 = textureGatherOffset(sampler, texCoords, tgoOffset, 3); 351 * 352 * Configure transform feedback to capture the values of withoutOffset* 353 * and withOffset*. 354 * 355 * Write a boilerplate fragment shader. 356 * 357 * Create a program from the above vertex shader and fragment shader 358 * and use it. 359 * 360 * Execute a draw call glDrawArrays(GL_POINTS, 0, 128). 361 * 362 * Copy the captured results from the buffer objects bound to transform 363 * feedback binding points. 364 * 365 * Using the captured values for each of the 128 results compute 366 * 367 * (Pseudocode) 368 * 369 * i = 0...127 370 * 371 * ivec2 referenceOffset = offsets[i]; 372 * 373 * if(referenceOffset[0] < 0 ) 374 * { 375 * referenceOffset[0] = sizeX - (referenceOffset[0] % sizeX); 376 * } 377 * if(referenceOffset[1] < 0 ) 378 * { 379 * referenceOffset[1] = sizeY - (referenceOffset[1] % sizeY); 380 * } 381 * 382 * for(int tNr = 0 tNr < 4; ++tNr) 383 * { 384 * ivec2 referenceTexelValue01 = ivec2( 385 * ((tgoResults[i].withoutOffset0[tNr] + referenceOffset[0]) % sizeX), 386 * ((tgoResults[i].withoutOffset1[tNr] + referenceOffset[1]) % sizeY)); 387 * 388 * ivec2 referenceTexelValue23 = ivec2( 389 * ((tgoResults[i].withoutOffset2[tNr] + referenceOffset[0]) % sizeX), 390 * ((tgoResults[i].withoutOffset3[tNr] + referenceOffset[1]) % sizeY)); 391 * 392 * ivec2 texelValue01 = ivec2( 393 * tgoResults[i].withOffset0[tNr], tgoResults[i].withOffset1[tNr]); 394 * 395 * ivec2 texelValue23 = ivec2( 396 * tgoResults[i].withOffset2[tNr], tgoResults[i].withOffset3[tNr]); 397 * } 398 * 399 * The test passes if in all cases we have 400 * referenceTexelValue01 == texelValue01 and 401 * referenceTexelValue23 == texelValue23. 402 * 403 * Repeat the same type of test for sampler2DArray. 404 * 405 * Repeat the same type of test using textureGatherOffsets instead of 406 * textureGatherOffset inputing constant offsets 407 * offsets[4] = { 408 * (MIN_PROGRAM_TEXTURE_GATHER_OFFSET, MIN_PROGRAM_TEXTURE_GATHER_OFFSET), 409 * (MIN_PROGRAM_TEXTURE_GATHER_OFFSET, MAX_PROGRAM_TEXTURE_GATHER_OFFSET), 410 * (MAX_PROGRAM_TEXTURE_GATHER_OFFSET, MIN_PROGRAM_TEXTURE_GATHER_OFFSET), 411 * (MAX_PROGRAM_TEXTURE_GATHER_OFFSET, MAX_PROGRAM_TEXTURE_GATHER_OFFSET) 412 * }; 413 **/ 414 415 /** Test configuration: wrap mode GL_REPEAT, sampler isampler2D, function textureGatherOffset 416 */ 417 class GPUShader5TextureGatherOffsetColor2DRepeatCaseTest : public GPUShader5TextureGatherOffsetColorTestBase 418 { 419 public: 420 /* Public methods */ 421 GPUShader5TextureGatherOffsetColor2DRepeatCaseTest(Context& context, const ExtParameters& extParams, 422 const char* name, const char* description); 423 ~GPUShader5TextureGatherOffsetColor2DRepeatCaseTest(void)424 virtual ~GPUShader5TextureGatherOffsetColor2DRepeatCaseTest(void) 425 { 426 } 427 428 protected: 429 /* Protected methods */ 430 /* Virtual methods from GPUShader5TextureGatherOffsetTestBase */ 431 virtual void getShaderParts(std::vector<const glw::GLchar*>& out_vertex_shader_parts); 432 virtual void prepareVertexBuffersData(std::vector<VertexBufferInfo>& vertex_buffer_infos); 433 434 /* Virtual methods from GPUShader5TextureGatherOffsetColorTestBase */ 435 virtual bool checkResult(const CapturedVaryings& captured_data, unsigned int index, unsigned int texture_size); 436 437 /* Utilities */ 438 void getOffsets(glw::GLint& out_x_offset, glw::GLint& out_y_offset, unsigned int index); 439 440 private: 441 /* Private fields */ 442 /* Vertex shader code */ 443 static const glw::GLchar* const m_vertex_shader_code; 444 445 /* Number of offsets per vertex */ 446 static const unsigned int m_n_offsets_components; 447 448 /* Name of offset attribute */ 449 static const glw::GLchar* const m_offsets_attribute_name; 450 451 /* Storage for offsets */ 452 std::vector<glw::GLint> m_offsets_buffer_data; 453 }; 454 455 /** Test configuration: wrap mode GL_REPEAT, sampler isampler2DArray, function textureGatherOffset 456 */ 457 class GPUShader5TextureGatherOffsetColor2DArrayCaseTest : public GPUShader5TextureGatherOffsetColor2DRepeatCaseTest 458 { 459 public: 460 /* Public methods */ 461 GPUShader5TextureGatherOffsetColor2DArrayCaseTest(Context& context, const ExtParameters& extParams, 462 const char* name, const char* description); 463 ~GPUShader5TextureGatherOffsetColor2DArrayCaseTest(void)464 virtual ~GPUShader5TextureGatherOffsetColor2DArrayCaseTest(void) 465 { 466 } 467 468 protected: 469 /* Protected methods */ 470 /* Virtual methods from GPUShader5TextureGatherOffsetTestBase */ 471 virtual void getShaderParts(std::vector<const glw::GLchar*>& out_vertex_shader_parts); 472 virtual void isTextureArray(bool& out_is_texture_array); 473 474 private: 475 /* Private fields */ 476 /* Vertex shader code */ 477 static const glw::GLchar* const m_vertex_shader_code; 478 }; 479 480 /** Test configuration: wrap mode GL_REPEAT, sampler isampler2D, function textureGatherOffsets 481 */ 482 class GPUShader5TextureGatherOffsetColor2DOffsetsCaseTest : public GPUShader5TextureGatherOffsetColorTestBase 483 { 484 public: 485 /* Public methods */ 486 GPUShader5TextureGatherOffsetColor2DOffsetsCaseTest(Context& context, const ExtParameters& extParams, 487 const char* name, const char* description); 488 ~GPUShader5TextureGatherOffsetColor2DOffsetsCaseTest(void)489 virtual ~GPUShader5TextureGatherOffsetColor2DOffsetsCaseTest(void) 490 { 491 } 492 493 protected: 494 /* Protected methods */ 495 /* Virtual methods from GPUShader5TextureGatherOffsetTestBase */ 496 virtual void getShaderParts(std::vector<const glw::GLchar*>& out_vertex_shader_parts); 497 virtual void prepareVertexBuffersData(std::vector<VertexBufferInfo>& vertex_buffer_infos); 498 499 /* Virtual methods from GPUShader5TextureGatherOffsetColorTestBase */ 500 virtual bool checkResult(const CapturedVaryings& captured_data, unsigned int index, unsigned int texture_size); 501 502 private: 503 /* Private fields */ 504 /* Vertex shader code */ 505 static const glw::GLchar* const m_vertex_shader_code_preamble; 506 static const glw::GLchar* const m_vertex_shader_code_body; 507 508 /* String used for definition of constant offsets */ 509 std::string m_vertex_shader_code_offsets; 510 }; 511 512 /** Implementation of "Test 10" from CTS_EXT_gpu_shader5. Test description follows: 513 * 514 * Test whether using non constant offsets in the textureGatherOffset 515 * and constant offsets in the textureGatherOffsets family of 516 * functions works as expected for sampler2DShadow 517 * and sampler2DArrayShadow and GL_REPEAT wrap mode. 518 * 519 * Category: API, 520 * Functional Test. 521 * 522 * Create a 64 x 64 texture with internal format GL_DEPTH_COMPONENT and 523 * type GL_FLOAT. 524 * 525 * Set both GL_TEXTURE_MIN_FILTER and GL_TEXTURE_MAG_FILTER to GL_NEAREST. 526 * 527 * Set both GL_TEXTURE_WRAP_S and GL_TEXTURE_WRAP_T to GL_REPEAT. 528 * 529 * Setup the texture parameters 530 * 531 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, 532 * COMPARE_REF_TO_TEXTURE); 533 * 534 * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LESS); 535 * 536 * Fill each texel with depth value corresponding to its position 537 * in the texture for the X axis: (x, y) -> (x / sizeX); 538 * 539 * Write a vertex shader that defines: 540 * 541 * uniform sampler2DShadow sampler; 542 * 543 * in ivec2 tgoOffset; 544 * in vec2 texCoords; 545 * 546 * out ivec4 withoutOffset; 547 * out ivec4 withOffset; 548 * 549 * Bind the sampler to texture unit the texture we created is assigned to. 550 * 551 * Initialize a buffer object to be assigned as input attribute tgoOffset 552 * data source. The buffer object should hold 128 integer tuples. Fill it 553 * with some random integer values but falling into a range of 554 * (MIN_PROGRAM_TEXTURE_GATHER_OFFSET, 555 * MAX_PROGRAM_TEXTURE_GATHER_OFFSET). 556 * 557 * Initialize a buffer object to be assigned as input attribute texCoords 558 * data source. The buffer object should hold 128 elements. Fill the first 559 * 4 tuples with (0.0, 0.0) , (0.0, 1.0), (1.0, 0.0), (1.0, 1.0) and the 560 * rest with some random float values in the range [-8.0..8.0]. 561 * 562 * In the vertex shader perform the following operation: 563 * 564 * withoutOffset = ivec4(0,0,0,0); 565 * withOffset = ivec4(0,0,0,0); 566 * 567 * ivec2 texSize = textureSize2D(sampler, 0); 568 * 569 * for(int texelNr = 0 texelNr < texSize.x; ++texelNr) 570 * { 571 * float refZ = float(texelNr) / float(texSize.x); 572 * 573 * withoutOffset += textureGather( sampler, texCoords, refZ ); 574 * withOffset += textureGatherOffset(sampler,texCoords,offset,refZ); 575 * } 576 * 577 * Configure transform feedback to capture the values of withoutOffset 578 * and withOffset. 579 * 580 * Write a boilerplate fragment shader. 581 * 582 * Create a program from the above vertex shader and fragment shader 583 * and use it. 584 * 585 * Execute a draw call glDrawArrays(GL_POINTS, 0, 128). 586 * 587 * Copy the captured results from the buffer objects bound to transform 588 * feedback binding points. 589 * 590 * Using the captured values for each of the 128 results compute 591 * 592 * (Pseudocode) 593 * 594 * i = 0...127 595 * 596 * int referenceOffsetX = offsets[i].x; 597 * 598 * if(referenceOffsetX < 0 ) 599 * { 600 * referenceOffsetX = sizeX - (referenceOffsetX % sizeX); 601 * } 602 * 603 * for(int tNr = 0 tNr < 4; ++tNr) 604 * { 605 * int referenceTexelValueX = 606 * (tgoResults[i].withoutOffset[tNr] + referenceOffsetX) % sizeX; 607 * 608 * int texelValueX = tgoResults[i].withOffset[tNr]; 609 * } 610 * 611 * The test passes if in all cases we have 612 * referenceTexelValueX == texelValueX. 613 * 614 * Repeat the same test for Y axis. 615 * 616 * Repeat the same type of test for sampler2DArrayShadow. 617 * 618 * Repeat the same type of test using textureGatherOffsets instead of 619 * textureGatherOffset inputting constant offsets 620 * offsets[4] = { 621 * (MIN_PROGRAM_TEXTURE_GATHER_OFFSET,MIN_PROGRAM_TEXTURE_GATHER_OFFSET), 622 * (MIN_PROGRAM_TEXTURE_GATHER_OFFSET,MAX_PROGRAM_TEXTURE_GATHER_OFFSET), 623 * (MAX_PROGRAM_TEXTURE_GATHER_OFFSET,MIN_PROGRAM_TEXTURE_GATHER_OFFSET), 624 * (MAX_PROGRAM_TEXTURE_GATHER_OFFSET,MAX_PROGRAM_TEXTURE_GATHER_OFFSET) 625 * }; 626 * 627 **/ 628 629 /** Test configuration: wrap mode GL_REPEAT, sampler isampler2DShadow, function textureGatherOffset, axis X 630 */ 631 class GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest : public GPUShader5TextureGatherOffsetDepthTestBase 632 { 633 public: 634 /* Public methods */ 635 GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest(Context& context, const ExtParameters& extParams, 636 const char* name, const char* description); 637 ~GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest(void)638 virtual ~GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest(void) 639 { 640 } 641 642 protected: 643 /* Protected methods */ 644 /* Virtual methods from GPUShader5TextureGatherOffsetTestBase */ 645 virtual void getShaderParts(std::vector<const glw::GLchar*>& out_vertex_shader_parts); 646 virtual void prepareVertexBuffersData(std::vector<VertexBufferInfo>& vertex_buffer_infos); 647 648 /* Virtual methods from GPUShader5TextureGatherOffsetDepthTestBase */ 649 virtual bool checkResult(const CapturedVaryings& captured_data, unsigned int index, unsigned int texture_size); 650 651 /* Utilities */ 652 void getOffsets(glw::GLint& out_x_offset, glw::GLint& out_y_offset, unsigned int index); 653 654 /* Number of offsets per vertex */ 655 static const unsigned int m_n_offsets_components; 656 657 /* Name of offset attribute */ 658 static const glw::GLchar* const m_offsets_attribute_name; 659 660 /* Storage for offsets */ 661 std::vector<glw::GLint> m_offsets_buffer_data; 662 663 private: 664 /* Private fields */ 665 /* Vertex shader code */ 666 static const glw::GLchar* const m_vertex_shader_code; 667 }; 668 669 /** Test configuration: wrap mode GL_REPEAT, sampler isampler2DShadow, function textureGatherOffset, axis Y 670 */ 671 class GPUShader5TextureGatherOffsetDepth2DRepeatYCaseTest : public GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest 672 { 673 public: 674 /* Public methods */ 675 GPUShader5TextureGatherOffsetDepth2DRepeatYCaseTest(Context& context, const ExtParameters& extParams, 676 const char* name, const char* description); 677 ~GPUShader5TextureGatherOffsetDepth2DRepeatYCaseTest(void)678 virtual ~GPUShader5TextureGatherOffsetDepth2DRepeatYCaseTest(void) 679 { 680 } 681 682 protected: 683 /* Protected methods */ 684 /* Virtual methods from GPUShader5TextureGatherOffsetTestBase */ 685 virtual void getShaderParts(std::vector<const glw::GLchar*>& out_vertex_shader_parts); 686 virtual void prepareTextureData(glw::GLubyte* data); 687 688 /* Virtual methods from GPUShader5TextureGatherOffsetDepthTestBase */ 689 virtual bool checkResult(const CapturedVaryings& captured_data, unsigned int index, unsigned int texture_size); 690 691 private: 692 /* Private fields */ 693 /* Vertex shader code */ 694 static const glw::GLchar* const m_vertex_shader_code; 695 }; 696 697 /** Test configuration: wrap mode GL_REPEAT, sampler isampler2DShadowArray, function textureGatherOffset, axis X 698 */ 699 class GPUShader5TextureGatherOffsetDepth2DArrayCaseTest : public GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest 700 { 701 public: 702 /* Public methods */ 703 GPUShader5TextureGatherOffsetDepth2DArrayCaseTest(Context& context, const ExtParameters& extParams, 704 const char* name, const char* description); 705 ~GPUShader5TextureGatherOffsetDepth2DArrayCaseTest(void)706 virtual ~GPUShader5TextureGatherOffsetDepth2DArrayCaseTest(void) 707 { 708 } 709 710 protected: 711 /* Protected methods */ 712 /* Virtual methods from GPUShader5TextureGatherOffsetTestBase */ 713 virtual void getShaderParts(std::vector<const glw::GLchar*>& out_vertex_shader_parts); 714 virtual void isTextureArray(bool& out_is_texture_array); 715 716 private: 717 /* Private fields */ 718 /* Vertex shader code */ 719 static const glw::GLchar* const m_vertex_shader_code; 720 }; 721 722 /** Test configuration: wrap mode GL_REPEAT, sampler isampler2DShadow, function textureGatherOffsets, axis X 723 */ 724 class GPUShader5TextureGatherOffsetDepth2DOffsetsCaseTest : public GPUShader5TextureGatherOffsetDepthTestBase 725 { 726 public: 727 /* Public methods */ 728 GPUShader5TextureGatherOffsetDepth2DOffsetsCaseTest(Context& context, const ExtParameters& extParams, 729 const char* name, const char* description); 730 ~GPUShader5TextureGatherOffsetDepth2DOffsetsCaseTest(void)731 virtual ~GPUShader5TextureGatherOffsetDepth2DOffsetsCaseTest(void) 732 { 733 } 734 735 protected: 736 /* Protected methods */ 737 /* Virtual methods from GPUShader5TextureGatherOffsetTestBase */ 738 virtual void getShaderParts(std::vector<const glw::GLchar*>& out_vertex_shader_parts); 739 virtual void prepareVertexBuffersData(std::vector<VertexBufferInfo>& vertex_buffer_infos); 740 741 /* Virtual methods from GPUShader5TextureGatherOffsetDepthTestBase */ 742 virtual bool checkResult(const CapturedVaryings& captured_data, unsigned int index, unsigned int texture_size); 743 744 private: 745 /* Private fields */ 746 /* Vertex shader code */ 747 static const glw::GLchar* const m_vertex_shader_code_preamble; 748 static const glw::GLchar* const m_vertex_shader_code_body; 749 750 /* String used for definition of constant offsets */ 751 std::string m_vertex_shader_code_offsets; 752 }; 753 754 /** Implementation of "Test 11" from CTS_EXT_gpu_shader5. Test description follows: 755 * 756 * Test whether using non constant offsets in the textureGatherOffset 757 * function works as expected for sampler2D and CLAMP_TO_BORDER_EXT 758 * ( CLAMP_TO_EDGE ) wrap mode. 759 * 760 * Category: API, 761 * Functional Test, 762 * dependency with EXT_texture_border_clamp. 763 * 764 * Create two (lets name them A and B) 64 (texWidth) x 64 (texHeight) 765 * textures with internal format GL_RGBA32I. 766 * 767 * Bind texture A to texture unit 0. 768 * Bind texture B to texture unit 1. 769 * 770 * Set for both textures GL_TEXTURE_MIN_FILTER and GL_TEXTURE_MAG_FILTER 771 * to GL_NEAREST. 772 * 773 * For the A texture set GL_TEXTURE_WRAP_S and GL_TEXTURE_WRAP_T 774 * to CLAMP_TO_BORDER_EXT. 775 * For the B texture set GL_TEXTURE_WRAP_S and GL_TEXTURE_WRAP_T 776 * to CLAMP_TO_BORDER_EXT ( CLAMP TO EDGE ). 777 * 778 * For both textures fill the 4 components of each texel with values 779 * corresponding to texel row and column number (x,y) -> (x,y,x,y) 780 * 781 * Set the GL_TEXTURE_BORDER_COLOR_EXT to (-1,-1,-1,-1). 782 * 783 * Write a vertex shader that defines: 784 * 785 * uniform isampler2D samplerWithoutOffset; 786 * uniform isampler2D samplerWithOffset; 787 * 788 * in ivec2 tgoOffset; 789 * in vec2 texCoords; 790 * 791 * out ivec4 withoutOffset0; 792 * out ivec4 withoutOffset1; 793 * out ivec2 intFloorTexCoords; 794 * 795 * out ivec4 withOffset0; 796 * out ivec4 withOffset1; 797 * out ivec4 withOffset2; 798 * out ivec4 withOffset3; 799 * 800 * Bind samplerWithoutOffset to texture unit 0. 801 * Bind samplerWithOffset to texture unit 1. 802 * 803 * Initialize a buffer object to be assigned as input attribute tgoOffset 804 * data source. The buffer object should hold 128 integer tuples. Fill it 805 * with some random integer values but falling into a range of 806 * (MIN_PROGRAM_TEXTURE_GATHER_OFFSET, 807 * MAX_PROGRAM_TEXTURE_GATHER_OFFSET). 808 * 809 * Initialize a buffer object to be assigned as input attribute texCoords 810 * data source. The buffer object should hold 128 elements. Fill the first 811 * 4 tuples with (0.0, 0.0) , (0.0, 1.0), (1.0, 0.0), (1.0, 1.0) and the 812 * rest with some random float values in the range [-8.0..8.0]. 813 * 814 * In the vertex shader perform the following operation: 815 * 816 * vec2 floorTexCoords = floor(texCoords); 817 * vec2 fractTexCoords = texCoords - floorTexCoords; 818 * 819 * withoutOffset0 = textureGather(samplerWithoutOffset,fractTexCoords, 0); 820 * withoutOffset1 = textureGather(samplerWithoutOffset,fractTexCoords, 1); 821 * intFloorTexCoords = ivec2(int(floorTexCoords.x),int(floorTexCoords.y)); 822 * 823 * withOffset0 = textureGatherOffset(samplerWithOffset, 824 * texCoords, tgoOffset, 0); 825 * withOffset1 = textureGatherOffset(samplerWithOffset, 826 * texCoords, tgoOffset, 1); 827 * withOffset2 = textureGatherOffset(samplerWithOffset, 828 * texCoords, tgoOffset, 2); 829 * withOffset3 = textureGatherOffset(samplerWithOffset, 830 * texCoords, tgoOffset, 3); 831 * 832 * Configure transform feedback to capture the values of withoutOffset*, 833 * withOffset* and intFloorTexCoords. 834 * 835 * Write a boilerplate fragment shader. 836 * 837 * Create a program from the above vertex shader and fragment shader 838 * and use it. 839 * 840 * Execute a draw call glDrawArrays(GL_POINTS, 0, 128). 841 * 842 * Copy the captured results from the buffer objects bound to transform 843 * feedback binding points. 844 * 845 * Using the captured values for each of the 128 results perform 846 * the following algorithm: 847 * 848 * From the captured withoutOffset0 and withoutOffset1 variables extract 849 * 4 texelPos values 850 * 851 * (Pseudocode) 852 * 853 * texelPos[i] = ivec2( withoutOffset0[i] , withoutOffset1[i] ); 854 * 855 * Find a texel that has not been clamped. It's value should be 856 * different than (texWidth, texHeight). Let's asume that the found 857 * texel has index 'foundIndex'. 858 * 859 * If we can't find such texel we must throw an exception, because it means 860 * that the sampling algorithm has failed. 861 * 862 * Extract the offset that has to be applied to the chosen texel to get it's 863 * absolute position (the one we would get if we haven't clamped the texture 864 * coordinates for textureGather to the range [0,1]) 865 * 866 * (Pseudocode) 867 * 868 * ivec2 absoluteOffset = ivec2( intFloorTexCoords.x * texWidth , 869 * intFloorTexCoords.y * texHeight ); 870 * 871 * Next apply the offset to the texel position 872 * 873 * (Pseudocode) 874 * 875 * texelAbsolutePos[foundIndex] = texelPos[foundIndex] + absoluteOffset; 876 * 877 * Now we have to set the absolute positions of the remaining 3 texels. 878 * We can do this because the foundIndex gives us information which 879 * texel we are dealing with in a 2x2 texel matrix returned by 880 * textureGather. The remaining texels will have their absolute positions 881 * computed by adding or substacting 1 to their x and y components 882 * depending on their position in the matrix relative to foundIndex. 883 * 884 * In the next step we have to apply the offset used in 885 * textureGatherOffset function to each of the absolute positions. 886 * 887 * (Pseudocode) 888 * 889 * texelAbsolutePos[i] += tgoOffset; 890 * 891 * We have to examine each absolute position in order to know if it should 892 * been clamped or not. 893 * 894 * In case of CLAMP_TO_BORDER_EXT if the absolute position goes beyond the 895 * texture bounds set it to value of GL_TEXTURE_BORDER_COLOR_EXT -> (-1,-1) 896 * 897 * In case of CLAMP_TO_EDGE if the absolute position goes beyond the 898 * texture bounds we have to clamp the value of absolute position 899 * to the edge that has been crossed. 900 * 901 * The test passes for each of the 4 absolute positions we have 902 * 903 * (Pseudocode) 904 * 905 * texelAbsolutePos[i] == ivec2( withOffset0[i], withOffset1[i] ) and 906 * texelAbsolutePos[i] == ivec2( withOffset2[i], withOffset3[i] ). 907 **/ 908 909 /** Test configuration: wrap mode GL_CLAMP_TO_BORDER_EXT, sampler isampler2D, function textureGatherOffset 910 */ 911 class GPUShader5TextureGatherOffsetColor2DClampToBorderCaseTest 912 : public GPUShader5TextureGatherOffsetColor2DRepeatCaseTest 913 { 914 public: 915 /* Public methods */ 916 GPUShader5TextureGatherOffsetColor2DClampToBorderCaseTest(Context& context, const ExtParameters& extParams, 917 const char* name, const char* description); 918 ~GPUShader5TextureGatherOffsetColor2DClampToBorderCaseTest(void)919 virtual ~GPUShader5TextureGatherOffsetColor2DClampToBorderCaseTest(void) 920 { 921 } 922 923 protected: 924 /* Protected methods */ 925 /* Virtual methods from GPUShader5TextureGatherOffsetTestBase */ 926 virtual void getTextureWrapMode(glw::GLenum& out_wrap_mode); 927 virtual void getShaderParts(std::vector<const glw::GLchar*>& out_vertex_shader_parts); 928 929 /* Virtual methods from GPUShader5TextureGatherOffsetColorTestBase */ 930 virtual bool checkResult(const CapturedVaryings& captured_data, unsigned int index, unsigned int texture_size); 931 932 virtual void initTest(void); 933 934 private: 935 /* Private fields */ 936 /* Vertex shader code */ 937 static const glw::GLchar* const m_vertex_shader_code; 938 }; 939 940 /** Test configuration: wrap mode GL_CLAMP_TO_EDGE, sampler isampler2D, function textureGatherOffset 941 */ 942 class GPUShader5TextureGatherOffsetColor2DClampToEdgeCaseTest 943 : public GPUShader5TextureGatherOffsetColor2DRepeatCaseTest 944 { 945 public: 946 /* Public methods */ 947 GPUShader5TextureGatherOffsetColor2DClampToEdgeCaseTest(Context& context, const ExtParameters& extParams, 948 const char* name, const char* description); 949 ~GPUShader5TextureGatherOffsetColor2DClampToEdgeCaseTest(void)950 virtual ~GPUShader5TextureGatherOffsetColor2DClampToEdgeCaseTest(void) 951 { 952 } 953 954 protected: 955 /* Protected methods */ 956 /* Virtual methods from GPUShader5TextureGatherOffsetTestBase */ 957 virtual void getTextureWrapMode(glw::GLenum& out_wrap_mode); 958 virtual void getShaderParts(std::vector<const glw::GLchar*>& out_vertex_shader_parts); 959 960 /* Virtual methods from GPUShader5TextureGatherOffsetColorTestBase */ 961 virtual bool checkResult(const CapturedVaryings& captured_data, unsigned int index, unsigned int texture_size); 962 virtual void initTest(void); 963 964 private: 965 /* Private fields */ 966 /* Vertex shader code */ 967 static const glw::GLchar* const m_vertex_shader_code; 968 }; 969 970 /** Test configuration: wrap mode GL_CLAMP_TO_BORDER_EXT, sampler isampler2DShadow, function textureGatherOffset, axis X 971 */ 972 class GPUShader5TextureGatherOffsetDepth2DClampToBorderCaseTest 973 : public GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest 974 { 975 public: 976 /* Public methods */ 977 GPUShader5TextureGatherOffsetDepth2DClampToBorderCaseTest(Context& context, const ExtParameters& extParams, 978 const char* name, const char* description); 979 ~GPUShader5TextureGatherOffsetDepth2DClampToBorderCaseTest(void)980 virtual ~GPUShader5TextureGatherOffsetDepth2DClampToBorderCaseTest(void) 981 { 982 } 983 984 protected: 985 /* Protected methods */ 986 /* Virtual methods from GPUShader5TextureGatherOffsetTestBase */ 987 virtual void getTextureWrapMode(glw::GLenum& out_wrap_mode); 988 virtual void getShaderParts(std::vector<const glw::GLchar*>& out_vertex_shader_parts); 989 virtual void prepareVertexBuffersData(std::vector<VertexBufferInfo>& vertex_buffer_infos); 990 991 /* Virtual methods from GPUShader5TextureGatherOffsetDepthTestBase */ 992 virtual bool checkResult(const CapturedVaryings& captured_data, unsigned int index, unsigned int texture_size); 993 994 virtual void getVaryings(std::vector<const glw::GLchar*>& out_captured_varyings); 995 virtual void initTest(void); 996 997 private: 998 /* Private fields */ 999 /* Vertex shader code */ 1000 static const glw::GLchar* const m_vertex_shader_code; 1001 }; 1002 1003 /** Test configuration: wrap mode GL_CLAMP_TO_EDGE, sampler isampler2DShadow, function textureGatherOffset, axis X 1004 */ 1005 class GPUShader5TextureGatherOffsetDepth2DClampToEdgeCaseTest 1006 : public GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest 1007 { 1008 public: 1009 /* Public methods */ 1010 GPUShader5TextureGatherOffsetDepth2DClampToEdgeCaseTest(Context& context, const ExtParameters& extParams, 1011 const char* name, const char* description); 1012 ~GPUShader5TextureGatherOffsetDepth2DClampToEdgeCaseTest(void)1013 virtual ~GPUShader5TextureGatherOffsetDepth2DClampToEdgeCaseTest(void) 1014 { 1015 } 1016 1017 protected: 1018 /* Protected methods */ 1019 /* Virtual methods from GPUShader5TextureGatherOffsetTestBase */ 1020 virtual void getTextureWrapMode(glw::GLenum& out_wrap_mode); 1021 virtual void getShaderParts(std::vector<const glw::GLchar*>& out_vertex_shader_parts); 1022 1023 /* Virtual methods from GPUShader5TextureGatherOffsetDepthTestBase */ 1024 virtual bool checkResult(const CapturedVaryings& captured_data, unsigned int index, unsigned int texture_size); 1025 1026 virtual void getVaryings(std::vector<const glw::GLchar*>& out_captured_varyings); 1027 virtual void initTest(void); 1028 1029 private: 1030 /* Private fields */ 1031 /* Vertex shader code */ 1032 static const glw::GLchar* const m_vertex_shader_code; 1033 }; 1034 1035 } /* glcts */ 1036 1037 #endif // _ESEXTCGPUSHADER5TEXTUREGATHEROFFSET_HPP 1038