1 #ifndef _GLCVIEWPORTARRAYTESTS_HPP 2 #define _GLCVIEWPORTARRAYTESTS_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 glcViewportArrayTests.hpp 28 * \brief Declares test classes for "Viewport Array" functionality. 29 */ /*-------------------------------------------------------------------*/ 30 31 #include "glcTestCase.hpp" 32 #include "glwDefs.hpp" 33 34 #include "esextcTestCaseBase.hpp" 35 36 namespace tcu 37 { 38 class MessageBuilder; 39 } /* namespace tcu */ 40 41 namespace glcts 42 { 43 namespace ViewportArray 44 { 45 46 class Utils 47 { 48 public: 49 enum SHADER_STAGES 50 { 51 COMPUTE_SHADER = 0, 52 VERTEX_SHADER, 53 TESS_CTRL_SHADER, 54 TESS_EVAL_SHADER, 55 GEOMETRY_SHADER, 56 FRAGMENT_SHADER, 57 58 /* */ 59 SHADER_STAGES_MAX 60 }; 61 62 /* Public types */ 63 struct buffer 64 { 65 buffer(deqp::Context &context); 66 ~buffer(); 67 68 void bind() const; 69 70 void bindRange(glw::GLuint index, glw::GLintptr offset, glw::GLsizeiptr size); 71 72 void generate(glw::GLenum target); 73 void *map(glw::GLenum access) const; 74 void unmap() const; 75 76 void update(glw::GLsizeiptr size, glw::GLvoid *data, glw::GLenum usage); 77 78 glw::GLuint m_id; 79 80 private: 81 deqp::Context &m_context; 82 glw::GLenum m_target; 83 }; 84 85 struct framebuffer 86 { 87 framebuffer(deqp::Context &context); 88 ~framebuffer(); 89 90 void attachTexture(glw::GLenum attachment, glw::GLuint texture_id, glw::GLuint width, glw::GLuint height); 91 92 void bind(); 93 void clear(glw::GLenum mask); 94 95 void clearColor(glw::GLfloat red, glw::GLfloat green, glw::GLfloat blue, glw::GLfloat alpha); 96 97 void generate(); 98 99 glw::GLuint m_id; 100 101 private: 102 deqp::Context &m_context; 103 }; 104 105 class shaderCompilationException : public std::exception 106 { 107 public: 108 shaderCompilationException(const glw::GLchar *source, const glw::GLchar *message); 109 ~shaderCompilationException()110 virtual ~shaderCompilationException() throw() 111 { 112 } 113 114 virtual const char *what() const throw(); 115 116 std::string m_shader_source; 117 std::string m_error_message; 118 }; 119 120 class programLinkageException : public std::exception 121 { 122 public: 123 programLinkageException(const glw::GLchar *error_message); 124 ~programLinkageException()125 virtual ~programLinkageException() throw() 126 { 127 } 128 129 virtual const char *what() const throw(); 130 131 std::string m_error_message; 132 }; 133 134 /** Store information about program object 135 * 136 **/ 137 struct program 138 { 139 program(deqp::Context &context); 140 ~program(); 141 142 void build(const glw::GLchar *compute_shader_code, const glw::GLchar *fragment_shader_code, 143 const glw::GLchar *geometry_shader_code, const glw::GLchar *tesselation_control_shader_code, 144 const glw::GLchar *tesselation_evaluation_shader_code, const glw::GLchar *vertex_shader_code, 145 const glw::GLchar *const *varying_names, glw::GLuint n_varying_names, bool is_separable = false); 146 147 void compile(glw::GLuint shader_id, const glw::GLchar *source) const; 148 149 glw::GLint getAttribLocation(const glw::GLchar *name) const; 150 151 glw::GLuint getSubroutineIndex(const glw::GLchar *subroutine_name, glw::GLenum shader_stage) const; 152 153 glw::GLint getSubroutineUniformLocation(const glw::GLchar *uniform_name, glw::GLenum shader_stage) const; 154 155 glw::GLint getUniformLocation(const glw::GLchar *uniform_name) const; 156 157 void link() const; 158 void remove(); 159 void use() const; 160 161 /* */ 162 static void printShaderSource(const glw::GLchar *source, tcu::MessageBuilder &log); 163 164 static const glw::GLenum ARB_COMPUTE_SHADER; 165 166 glw::GLuint m_compute_shader_id; 167 glw::GLuint m_fragment_shader_id; 168 glw::GLuint m_geometry_shader_id; 169 glw::GLuint m_program_object_id; 170 glw::GLuint m_tesselation_control_shader_id; 171 glw::GLuint m_tesselation_evaluation_shader_id; 172 glw::GLuint m_vertex_shader_id; 173 174 private: 175 deqp::Context &m_context; 176 }; 177 178 struct texture 179 { 180 texture(deqp::Context &context); 181 ~texture(); 182 183 void bind() const; 184 185 void create(glw::GLuint width, glw::GLuint height, glw::GLenum internal_format); 186 187 void create(glw::GLuint width, glw::GLuint height, glw::GLuint depth, glw::GLenum internal_format); 188 189 void get(glw::GLenum format, glw::GLenum type, glw::GLvoid *out_data) const; 190 191 void release(); 192 193 void update(glw::GLuint width, glw::GLuint height, glw::GLuint depth, glw::GLenum format, glw::GLenum type, 194 glw::GLvoid *data); 195 196 glw::GLuint m_id; 197 glw::GLuint m_width; 198 glw::GLuint m_height; 199 glw::GLuint m_depth; 200 201 private: 202 deqp::Context &m_context; 203 bool m_is_array; 204 }; 205 206 struct vertexArray 207 { 208 vertexArray(deqp::Context &Context); 209 ~vertexArray(); 210 211 void generate(); 212 void bind(); 213 214 glw::GLuint m_id; 215 216 private: 217 deqp::Context &m_context; 218 }; 219 220 class DepthFuncWrapper 221 { 222 public: DepthFuncWrapper(deqp::Context & context)223 DepthFuncWrapper(deqp::Context &context) : m_gl(context.getRenderContext().getFunctions()) 224 { 225 } ~DepthFuncWrapper()226 ~DepthFuncWrapper() 227 { 228 } 229 depthRangeArray(glw::GLuint first,glw::GLsizei count,const glw::GLfloat * v)230 void depthRangeArray(glw::GLuint first, glw::GLsizei count, const glw::GLfloat *v) 231 { 232 m_gl.depthRangeArrayfvOES(first, count, v); 233 } 234 depthRangeArray(glw::GLuint first,glw::GLsizei count,const glw::GLdouble * v)235 void depthRangeArray(glw::GLuint first, glw::GLsizei count, const glw::GLdouble *v) 236 { 237 m_gl.depthRangeArrayv(first, count, v); 238 } 239 depthRangeIndexed(glw::GLuint index,glw::GLfloat n,glw::GLfloat f)240 void depthRangeIndexed(glw::GLuint index, glw::GLfloat n, glw::GLfloat f) 241 { 242 m_gl.depthRangeIndexedfOES(index, n, f); 243 } 244 depthRangeIndexed(glw::GLuint index,glw::GLdouble n,glw::GLdouble f)245 void depthRangeIndexed(glw::GLuint index, glw::GLdouble n, glw::GLdouble f) 246 { 247 m_gl.depthRangeIndexed(index, n, f); 248 } 249 depthRange(glw::GLfloat near,glw::GLfloat far)250 void depthRange(glw::GLfloat near, glw::GLfloat far) 251 { 252 m_gl.depthRangef(near, far); 253 } 254 depthRange(glw::GLdouble near,glw::GLdouble far)255 void depthRange(glw::GLdouble near, glw::GLdouble far) 256 { 257 m_gl.depthRange(near, far); 258 } 259 getDepthi_v(glw::GLenum target,glw::GLuint index,glw::GLfloat * data)260 void getDepthi_v(glw::GLenum target, glw::GLuint index, glw::GLfloat *data) 261 { 262 m_gl.getFloati_v(target, index, data); 263 } 264 getDepthi_v(glw::GLenum target,glw::GLuint index,glw::GLdouble * data)265 void getDepthi_v(glw::GLenum target, glw::GLuint index, glw::GLdouble *data) 266 { 267 m_gl.getDoublei_v(target, index, data); 268 } 269 getFunctions()270 const glw::Functions &getFunctions() 271 { 272 return m_gl; 273 } 274 275 private: 276 const glw::Functions &m_gl; 277 }; 278 }; 279 280 /** Implements test APIErrors, description follows: 281 * 282 * Verify that API generate errors as specified. Check that: 283 * * DepthRangeArrayv generates INVALID_VALUE when <first> + <count> is greater 284 * than or equal to the value of MAX_VIEWPORTS; 285 * * DepthRangeIndexed generates INVALID_VALUE when <index> is greater than or 286 * equal to the value of MAX_VIEWPORTS; 287 * * ViewportArrayv generates INVALID_VALUE when <first> + <count> is greater 288 * than or equal to the value of MAX_VIEWPORTS; 289 * * ViewportIndexedf and ViewportIndexedfv generate INVALID_VALUE when <index> 290 * is greater than or equal to the value of MAX_VIEWPORTS; 291 * * ViewportArrayv, Viewport, ViewportIndexedf and ViewportIndexedfv generate 292 * INVALID_VALUE when <w> or <h> values are negative; 293 * * ScissorArrayv generates INVALID_VALUE when <first> + <count> is greater 294 * than or equal to the value of MAX_VIEWPORTS; 295 * * ScissorIndexed and ScissorIndexedv generate INVALID_VALUE when <index> is 296 * greater than or equal to the value of MAX_VIEWPORTS; 297 * * ScissorArrayv, ScissorIndexed, ScissorIndexedv and Scissor generate 298 * INVALID_VALUE when <width> or <height> values are negative; 299 * * Disablei, Enablei and IsEnabledi generate INVALID_VALUE when <cap> is 300 * SCISSOR_TEST and <index> is greater than or equal to the 301 * value of MAX_VIEWPORTS; 302 * * GetIntegeri_v generates INVALID_VALUE when <target> is SCISSOR_BOX and 303 * <index> is greater than or equal to the value of MAX_VIEWPORTS; 304 * * GetFloati_v generates INVALID_VALUE when <target> is VIEWPORT and <index> 305 * is greater than or equal to the value of MAX_VIEWPORTS; 306 * * GetDoublei_v generates INVALID_VALUE when <target> is DEPTH_RANGE and 307 * <index> is greater than or equal to the value of MAX_VIEWPORTS; 308 **/ 309 class APIErrors : public glcts::TestCaseBase 310 { 311 public: 312 /* Public methods */ 313 APIErrors(deqp::Context &context, const glcts::ExtParameters &extParams); 314 ~APIErrors()315 virtual ~APIErrors() 316 { 317 } 318 319 /* Public methods inherited from TestCaseBase */ 320 virtual IterateResult iterate(void); 321 322 private: 323 template <typename T> 324 void depthRangeArrayHelper(Utils::DepthFuncWrapper &depthFunc, glw::GLint max_viewports, bool &test_result, 325 T *data = NULL); 326 327 template <typename T> 328 void depthRangeIndexedHelper(Utils::DepthFuncWrapper &depthFunc, glw::GLint max_viewports, bool &test_result, 329 T *data = NULL); 330 331 template <typename T> 332 void getDepthHelper(Utils::DepthFuncWrapper &depthFunc, glw::GLint max_viewports, bool &test_result, 333 T *data = NULL); 334 335 void checkGLError(glw::GLenum expected_error, const glw::GLchar *description, bool &out_result); 336 }; 337 338 /** Implements test Queries, description follows: 339 * 340 * Verify that: 341 * * Initial dimensions of VIEWPORT returned by GetFloati_v match dimensions of 342 * the window into which GL is rendering; 343 * * Initial values of DEPTH_RANGE returned by GetDoublei_v are [0, 1]; 344 * * Initial state of SCISSOR_TEST returned by IsEnabledi is FALSE; 345 * * Initial dimensions of SCISSOR_BOX returned by GetIntegeri_v are either 346 * zeros or match dimensions of the window into which GL is rendering; 347 * * Dimensions of MAX_VIEWPORT_DIMS returned by GetFloati_v are at least 348 * as big as supported dimensions of render buffers, see MAX_RENDERBUFFER_SIZE; 349 * * Value of MAX_VIEWPORTS returned by GetIntegeri_v is at least 16; 350 * * Value of VIEWPORT_SUBPIXEL_BITS returned by GetIntegeri_v is at least 0; 351 * * Values of VIEWPORT_BOUNDS_RANGE returned by GetFloatv are 352 * at least [-32768, 32767]; 353 * * Values of LAYER_PROVOKING_VERTEX and VIEWPORT_INDEX_PROVOKING_VERTEX 354 * returned by GetIntegerv are located in the following set 355 * { FIRST_VERTEX_CONVENTION, LAST_VERTEX_CONVENTION, PROVOKING_VERTEX, 356 * UNDEFINED_VERTEX }; 357 **/ 358 class Queries : public glcts::TestCaseBase 359 { 360 public: 361 /* Public methods */ 362 Queries(deqp::Context &context, const glcts::ExtParameters &extParams); 363 ~Queries()364 virtual ~Queries() 365 { 366 } 367 368 /* Public methods inherited from TestCase */ 369 virtual tcu::TestNode::IterateResult iterate(void); 370 371 private: 372 template <typename T> 373 void depthRangeInitialValuesHelper(Utils::DepthFuncWrapper &depthFunc, glw::GLint max_viewports, bool &test_result, 374 T *data = NULL); 375 }; 376 377 /** Implements test ViewportAPI, description follows: 378 * 379 * Verify that VIEWPORT can be set and queried. 380 * Steps: 381 * - get initial dimensions of VIEWPORT for all MAX_VIEWPORTS indices; 382 * - change location and dimensions of all indices at once with 383 * ViewportArrayv; 384 * - get VIEWPORT for all MAX_VIEWPORTS indices and verify results; 385 * - for each index: 386 * * modify with ViewportIndexedf, 387 * * get VIEWPORT for all MAX_VIEWPORTS indices and verify results; 388 * * modify with ViewportIndexedfv, 389 * * get VIEWPORT for all MAX_VIEWPORTS indices and verify results; 390 * - for each index: 391 * * modify all indices before and after current one with ViewportArrayv, 392 * * get VIEWPORT for all MAX_VIEWPORTS indices and verify results; 393 * - change location and dimensions of all indices at once with Viewport; 394 * - get VIEWPORT for all MAX_VIEWPORTS indices and verify results; 395 **/ 396 class ViewportAPI : public glcts::TestCaseBase 397 { 398 public: 399 /* Public methods */ 400 ViewportAPI(deqp::Context &context, const glcts::ExtParameters &extParams); 401 ~ViewportAPI()402 virtual ~ViewportAPI() 403 { 404 } 405 406 /* Public methods inherited from TestCase */ 407 virtual tcu::TestNode::IterateResult iterate(void); 408 409 private: 410 /* Private methods */ 411 void compareViewports(std::vector<glw::GLfloat> &left, std::vector<glw::GLfloat> &right, 412 const glw::GLchar *description, bool &out_result); 413 414 void getViewports(glw::GLint max_viewports, std::vector<glw::GLfloat> &out_data); 415 416 /* Private constants */ 417 static const glw::GLuint m_n_elements; 418 }; 419 420 /** Implements test ScissorAPI, description follows: 421 * 422 * Verify that SCISSOR_BOX can be set and queried. 423 * Steps: 424 * - get initial dimensions of SCISSOR_BOX for all MAX_VIEWPORTS indices; 425 * - change location and dimensions of all indices at once with 426 * ScissorArrayv; 427 * - get SCISSOR_BOX for all MAX_VIEWPORTS indices and verify results; 428 * - for each index: 429 * * modify with ScissorIndexed, 430 * * get SCISSOR_BOX for all MAX_VIEWPORTS indices and verify results; 431 * * modify with ScissorIndexedv, 432 * * get SCISSOR_BOX for all MAX_VIEWPORTS indices and verify results; 433 * - for each index: 434 * * modify all indices before and after current one with ScissorArrayv, 435 * * get SCISSOR_BOX for all MAX_VIEWPORTS indices and verify results; 436 * - change location and dimensions of all indices at once with Scissor; 437 * - get SCISSOR_BOX for all MAX_VIEWPORTS indices and verify results; 438 **/ 439 class ScissorAPI : public glcts::TestCaseBase 440 { 441 public: 442 /* Public methods */ 443 ScissorAPI(deqp::Context &context, const glcts::ExtParameters &extParams); 444 ~ScissorAPI()445 virtual ~ScissorAPI() 446 { 447 } 448 449 /* Public methods inherited from TestCase */ 450 virtual tcu::TestNode::IterateResult iterate(void); 451 452 private: 453 /* Private methods */ 454 void compareScissorBoxes(std::vector<glw::GLint> &left, std::vector<glw::GLint> &right, 455 const glw::GLchar *description, bool &out_result); 456 457 void getScissorBoxes(glw::GLint max_viewports, std::vector<glw::GLint> &out_data); 458 459 /* Private constants */ 460 static const glw::GLuint m_n_elements; 461 }; 462 463 /** Implements test DepthRangeAPI, description follows: 464 * 465 * Verify that DEPTH_RANGE can be set and queried. 466 * Steps: 467 * - get initial values of DEPTH_RANGE for all MAX_VIEWPORTS indices; 468 * - change values of all indices at once with DepthRangeArrayv; 469 * - get DEPTH_RANGE for all MAX_VIEWPORTS indices and verify results; 470 * - for each index: 471 * * modify with DepthRangeIndexed, 472 * * get DEPTH_RANGE for all MAX_VIEWPORTS indices and verify results; 473 * - for each index: 474 * * modify all indices before and after current one with DepthRangeArrayv, 475 * * get DEPTH_RANGE for all MAX_VIEWPORTS indices and verify results; 476 * - change values of all indices at once with DepthRange; 477 * - get DEPTH_RANGE for all MAX_VIEWPORTS indices and verify results; 478 **/ 479 class DepthRangeAPI : public glcts::TestCaseBase 480 { 481 public: 482 /* Public methods */ 483 DepthRangeAPI(deqp::Context &context, const glcts::ExtParameters &extParams); 484 ~DepthRangeAPI()485 virtual ~DepthRangeAPI() 486 { 487 } 488 489 /* Public methods inherited from TestCase */ 490 virtual tcu::TestNode::IterateResult iterate(void); 491 492 private: 493 /* Private methods */ 494 template <typename T> 495 void compareDepthRanges(std::vector<T> &left, std::vector<T> &right, const glw::GLchar *description, 496 bool &out_result); 497 498 template <typename T> 499 void getDepthRanges(Utils::DepthFuncWrapper &depthFunc, glw::GLint max_viewports, std::vector<T> &out_data); 500 501 template <typename T> 502 bool iterateHelper(T *data = NULL); 503 504 /* Private constants */ 505 static const glw::GLuint m_n_elements; 506 }; 507 508 /** Implements test ScissorTestStateAPI, description follows: 509 * 510 * Verify that state of SCISSOR_TEST can be set and queried. 511 * Steps: 512 * - get initial state of SCISSOR_TEST for all MAX_VIEWPORTS indices; 513 * - for each index: 514 * * toggle SCISSOR_TEST, 515 * * get state of SCISSOR_TEST for all MAX_VIEWPORTS indices and verify; 516 * - for each index: 517 * * toggle SCISSOR_TEST, 518 * * get state of SCISSOR_TEST for all MAX_VIEWPORTS indices and verify; 519 * - enable SCISSOR_TEST for all indices at once with Enable; 520 * - get state of SCISSOR_TEST for all MAX_VIEWPORTS indices and verify; 521 * - disable SCISSOR_TEST for all indices at once with Disable; 522 * - get state of SCISSOR_TEST for all MAX_VIEWPORTS indices and verify; 523 * - enable SCISSOR_TEST for all indices at once with Enable; 524 * - get state of SCISSOR_TEST for all MAX_VIEWPORTS indices and verify; 525 **/ 526 class ScissorTestStateAPI : public glcts::TestCaseBase 527 { 528 public: 529 /* Public methods */ 530 ScissorTestStateAPI(deqp::Context &context, const glcts::ExtParameters &extParams); 531 ~ScissorTestStateAPI()532 virtual ~ScissorTestStateAPI() 533 { 534 } 535 536 /* Public methods inherited from TestCase */ 537 virtual tcu::TestNode::IterateResult iterate(void); 538 539 private: 540 /* Private methods */ 541 void compareScissorTestStates(std::vector<glw::GLboolean> &left, std::vector<glw::GLboolean> &right, 542 const glw::GLchar *description, bool &out_result); 543 544 void getScissorTestStates(glw::GLint max_viewports, std::vector<glw::GLboolean> &out_data); 545 }; 546 547 class DrawTestBase : public glcts::TestCaseBase 548 { 549 public: 550 /* Public methods */ 551 DrawTestBase(deqp::Context &context, const glcts::ExtParameters &extParams, const glw::GLchar *test_name, 552 const glw::GLchar *test_description); 553 ~DrawTestBase()554 virtual ~DrawTestBase() 555 { 556 } 557 558 /* Public methods inherited from TestCase */ 559 virtual tcu::TestNode::IterateResult iterate(void); 560 561 protected: 562 /* Protected enums */ 563 enum VIEWPORT_METHOD 564 { 565 VIEWPORTARRAYV = 0, 566 VIEWPORTINDEXEDF, 567 VIEWPORTINDEXEDF_V, 568 }; 569 enum SCISSOR_METHOD 570 { 571 SCISSORARRAYV = 0, 572 SCISSORINDEXEDF, 573 SCISSORINDEXEDF_V, 574 }; 575 enum DEPTH_RANGE_METHOD 576 { 577 DEPTHRANGEARRAYV = 0, 578 DEPTHRANGEINDEXED, 579 }; 580 enum PROVOKING_VERTEX 581 { 582 FIRST, 583 LAST, 584 }; 585 enum TEST_TYPE 586 { 587 VIEWPORT, 588 SCISSOR, 589 DEPTHRANGE, 590 PROVOKING, 591 }; 592 593 /* Protected methods to be implemented by child class */ 594 virtual bool checkResults(Utils::texture &texture_0, Utils::texture &texture_1, glw::GLuint draw_call_index); 595 596 virtual void getClearSettings(bool &clear_depth_before_draw, glw::GLuint iteration_index, 597 glw::GLfloat &depth_value); 598 599 virtual glw::GLuint getDrawCallsNumber(); 600 virtual std::string getFragmentShader() = 0; 601 virtual std::string getGeometryShader() = 0; 602 virtual TEST_TYPE getTestType(); 603 virtual bool isClearTest(); 604 605 virtual void prepareTextures(Utils::texture &texture_0, Utils::texture &texture_1); 606 607 virtual void prepareUniforms(Utils::program &program, glw::GLuint draw_call_index); 608 609 virtual void setupFramebuffer(Utils::framebuffer &framebuffer, Utils::texture &texture_0, 610 Utils::texture &texture_1); 611 612 virtual void setupViewports(TEST_TYPE type, glw::GLuint iteration_index); 613 614 /* Methods available for child class */ 615 bool checkRegionR32I(glw::GLuint x, glw::GLuint y, glw::GLint expected_value, glw::GLint *data); 616 617 bool checkRegionR32I(glw::GLuint x, glw::GLuint y, glw::GLuint width, glw::GLuint height, glw::GLint expected_value, 618 glw::GLint *data); 619 620 void prepareTextureR32I(Utils::texture &texture); 621 void prepareTextureR32Ix4(Utils::texture &texture); 622 void prepareTextureArrayR32I(Utils::texture &texture); 623 void prepareTextureR32F(Utils::texture &texture); 624 void prepareTextureD32F(Utils::texture &texture); 625 void setup16x2Depths(DEPTH_RANGE_METHOD method); 626 void setup4x4Scissor(SCISSOR_METHOD method, bool set_zeros); 627 void setup4x4Viewport(VIEWPORT_METHOD method); 628 void setup2x2Viewport(PROVOKING_VERTEX provoking); 629 630 /* Constants available to child class */ 631 static const glw::GLuint m_depth; 632 static const glw::GLuint m_height; 633 static const glw::GLuint m_width; 634 static const glw::GLuint m_r32f_height; 635 static const glw::GLuint m_r32f_width; 636 static const glw::GLuint m_r32ix4_depth; 637 638 private: 639 /* Private methods */ 640 std::string getVertexShader(); 641 642 template <typename T> 643 void setup16x2DepthsHelper(DEPTH_RANGE_METHOD method, T *data = NULL); 644 }; 645 646 /** Implements test DrawToSingleLayerWithMultipleViewports, description follows: 647 * 648 * Verify that multiple viewports can be used to draw to single image. 649 * Steps: 650 * - prepare 2D R32I 128x128 texture filled with value -1 and set it up as 651 * COLOR_ATTACHMENT_0; 652 * - prepare program that consist of: 653 * * boilerplate vertex shader, 654 * * geometry shader, 655 * * fragment shaders; 656 * Geometry shader should output a quad (-1,-1 : 1,1) made of 657 * triangle_strip; gl_ViewportIndex and declared integer varying "color" 658 * should be assigned the value of gl_InvocationID; Amount of geometry shader 659 * invocations should be set to 16; Fragment shader should output value of 660 * varying "color" to attachment 0. 661 * - set up first 16 viewports with following code snippet: 662 * 663 * index = 0; 664 * for (y = 0; y < 4; ++y) 665 * for (x = 0; x < 4; ++x) 666 * ViewportIndexedf(index++, 667 * x * 32 x offset, 668 * y * 32 y offset, 669 * 32 width , 670 * 32 height ); 671 * - draw single vertex; 672 * - inspect contents of COLOR_ATTACHMENT_0; 673 * - test pass if image is filled with the following pattern: 674 * 675 * 0 1 2 3 676 * 4 5 6 7 677 * 8 9 10 11 678 * 12 13 14 15; 679 * 680 * Each area should be 32x32 pixels rectangle; 681 * - repeat test with functions ViewportIndexedf_v and ViewportArrayv; 682 **/ 683 class DrawToSingleLayerWithMultipleViewports : public DrawTestBase 684 { 685 public: 686 /* Public methods */ 687 DrawToSingleLayerWithMultipleViewports(deqp::Context &context, const glcts::ExtParameters &extParams); 688 ~DrawToSingleLayerWithMultipleViewports()689 virtual ~DrawToSingleLayerWithMultipleViewports() 690 { 691 } 692 693 protected: 694 /* Protected methods inherited from DrawTestBase */ 695 virtual std::string getFragmentShader(); 696 virtual std::string getGeometryShader(); 697 }; 698 699 /** Implements test DynamicViewportIndex, description follows: 700 * 701 * Verify that gl_ViewportIndex can be set in dynamic manner. 702 * Modify DrawToSingleLayerWithMultipleViewports in the following aspects: 703 * - geometry shader should declare unsigned integer uniform "index"; 704 * - geometry shader should assign a value of "index" to gl_ViewportIndex and 705 * "color"; 706 * - amount of geometry shader invocations should be set to 1; 707 * - 16 times: 708 * * set "index" to unique value from range <0:15>; 709 * * draw single vertex; 710 * * verify that only area of viewport at "index" has been updated; 711 * - test pass if correct pixels were modified in each draw; 712 **/ 713 class DynamicViewportIndex : public DrawTestBase 714 { 715 public: 716 /* Public methods */ 717 DynamicViewportIndex(deqp::Context &context, const glcts::ExtParameters &extParams); 718 ~DynamicViewportIndex()719 virtual ~DynamicViewportIndex() 720 { 721 } 722 723 protected: 724 /* Protected methods inherited from DrawTestBase */ 725 virtual bool checkResults(Utils::texture &texture_0, Utils::texture &texture_1, glw::GLuint draw_call_index); 726 727 virtual std::string getFragmentShader(); 728 virtual std::string getGeometryShader(); 729 virtual glw::GLuint getDrawCallsNumber(); 730 731 virtual void prepareUniforms(Utils::program &program, glw::GLuint draw_call_index); 732 }; 733 734 /** Implements test DrawMulitpleViewportsWithSingleInvocation, description follows: 735 * 736 * Verify that multiple viewports can be affected by single invocation of 737 * geometry shader. 738 * Modify DrawToSingleLayerWithMultipleViewports in the following aspects: 739 * - geometry shader should output 16 quads, as separate primitives; 740 * - instead of gl_InvocationID, geometry shader should use predefined values 741 * from range <0:15>, unique per quad; 742 * - amount of geometry shader invocations should be set to 1; 743 **/ 744 class DrawMulitpleViewportsWithSingleInvocation : public DrawTestBase 745 { 746 public: 747 /* Public methods */ 748 DrawMulitpleViewportsWithSingleInvocation(deqp::Context &context, const glcts::ExtParameters &extParams); 749 ~DrawMulitpleViewportsWithSingleInvocation()750 virtual ~DrawMulitpleViewportsWithSingleInvocation() 751 { 752 } 753 754 protected: 755 /* Protected methods inherited from DrawTestBase */ 756 virtual std::string getFragmentShader(); 757 virtual std::string getGeometryShader(); 758 }; 759 760 /** Implements test ViewportIndexSubroutine, description follows: 761 * 762 * Verify that gl_ViewportIndex can be assigned by subroutine. 763 * Depends on: ARB_shader_subroutine. 764 * Modify DynamicViewportIndex in the following aspects: 765 * - geometry shader should define two subroutines and single subroutine 766 * uniform; First subroutine should assign value 4 to gl_ViewportIndex and 767 * "color"; Second subroutine should assign value 5 to gl_ViewportIndex and 768 * "color"; subroutine should be called once per emitted vertex; 769 * - uniform "index" should be removed; 770 * - viewport 4 should be configured to span over left half of image; viewport 771 * 5 should span over right half of image; 772 * - set up first subroutine and draw single vertex; 773 * - set up second subroutine and draw single vertex; 774 * - test pass if left half of image is filled with value 4 and right one with 775 * 5; 776 **/ 777 class ViewportIndexSubroutine : public DrawTestBase 778 { 779 public: 780 /* Public methods */ 781 ViewportIndexSubroutine(deqp::Context &context, const glcts::ExtParameters &extParams); 782 ~ViewportIndexSubroutine()783 virtual ~ViewportIndexSubroutine() 784 { 785 } 786 787 /* Public methods inherited from TestCase/DrawTestBase */ 788 virtual tcu::TestNode::IterateResult iterate(void); 789 790 protected: 791 /* Protected methods inherited from DrawTestBase */ 792 virtual bool checkResults(Utils::texture &texture_0, Utils::texture &texture_1, glw::GLuint draw_call_index); 793 794 virtual std::string getFragmentShader(); 795 virtual std::string getGeometryShader(); 796 virtual glw::GLuint getDrawCallsNumber(); 797 798 virtual void prepareUniforms(Utils::program &program, glw::GLuint draw_call_index); 799 800 virtual void setupViewports(TEST_TYPE type, glw::GLuint iteration_index); 801 }; 802 803 /** Implements test DrawMultipleLayers, description follows: 804 * 805 * Verify that single viewport affects multiple layers in the same way. 806 * Modify DynamicViewportIndex in the following aspects: 807 * - texture should be 2D array with 16 layers; 808 * - geometry shader should assign a value of gl_InvocationId to gl_Layer; 809 * - amount of geometry shader invocations should be set to 16; 810 * - verification should be applied to all 16 layers; 811 **/ 812 class DrawMultipleLayers : public DrawTestBase 813 { 814 public: 815 /* Public methods */ 816 DrawMultipleLayers(deqp::Context &context, const glcts::ExtParameters &extParams); 817 818 DrawMultipleLayers(deqp::Context &context, const glcts::ExtParameters &extParams, const glw::GLchar *test_name, 819 const glw::GLchar *test_description); 820 ~DrawMultipleLayers()821 virtual ~DrawMultipleLayers() 822 { 823 } 824 825 protected: 826 /* Protected methods inherited from DrawTestBase */ 827 virtual bool checkResults(Utils::texture &texture_0, Utils::texture &texture_1, glw::GLuint draw_call_index); 828 829 virtual std::string getFragmentShader(); 830 virtual std::string getGeometryShader(); 831 832 virtual void prepareTextures(Utils::texture &texture_0, Utils::texture &texture_1); 833 }; 834 835 /** Implements test Scissor, description follows: 836 * 837 * Verify that scissor test is applied as expected. 838 * Modify DrawMultipleLayers in the following aspects: 839 * - set all viewports to location 0,0 and dimensions 128x128; 840 * - set up first 16 scissor boxes with following code snippet: 841 * 842 * index = 0; 843 * for (y = 0; y < 4; ++y) 844 * for (x = 0; x < 4; ++x) 845 * ScissorIndexed(index++, 846 * x * 32 x offset, 847 * y * 32 y offset, 848 * 32 width , 849 * 32 height ); 850 * 851 * - enable SCISSORT_TEST for first 16 indices; 852 * - verification should be concerned with areas of the scissor boxes not 853 * viewports; 854 * - repeat test with functions ScissorIndexedv and ScissorArrayv; 855 **/ 856 class Scissor : public DrawMultipleLayers 857 { 858 public: 859 /* Public methods */ 860 Scissor(deqp::Context &context, const glcts::ExtParameters &extParams); 861 ~Scissor()862 virtual ~Scissor() 863 { 864 } 865 866 protected: 867 /* Protected methods inherited from DrawTestBase */ 868 virtual TEST_TYPE getTestType(); 869 }; 870 871 /** Implements test ScissorZeroDimension, description follows: 872 * 873 * Verify that scissor test discard all fragments when width and height is set 874 * to zero. 875 * Modify Scissor to set up width and height of scissor boxes to 0. 876 * Test pass if no pixel is modified. 877 **/ 878 class ScissorZeroDimension : public DrawMultipleLayers 879 { 880 public: 881 /* Public methods */ 882 ScissorZeroDimension(deqp::Context &context, const glcts::ExtParameters &extParams); 883 ~ScissorZeroDimension()884 virtual ~ScissorZeroDimension() 885 { 886 } 887 888 protected: 889 /* Protected methods inherited from DrawTestBase */ 890 virtual bool checkResults(Utils::texture &texture_0, Utils::texture &texture_1, glw::GLuint draw_call_index); 891 892 virtual TEST_TYPE getTestType(); 893 894 virtual void setupViewports(TEST_TYPE type, glw::GLuint iteration_index); 895 }; 896 897 /** Implements test ScissorClear, description follows: 898 * 899 * Verify that Clear is affected only by settings of scissor test in first 900 * viewport. 901 * Steps: 902 * - prepare 2D 128x128 R32I texture, filled with value -1 and set it as 903 * COLOR_ATTACHMENT_0; 904 * - configure first 16 viewports as in Scissor; 905 * - enable SCISSOR_TEST for first 16 indices; 906 * - clear framebuffer to (0, 0, 0, 0); 907 * - inspect image; 908 * - test pass if only area corresponding with first SCISSOR_BOX was filled 909 * with 0, while rest of image remain filled with value -1; 910 **/ 911 class ScissorClear : public DrawMultipleLayers 912 { 913 public: 914 /* Public methods */ 915 ScissorClear(deqp::Context &context, const glcts::ExtParameters &extParams); 916 ~ScissorClear()917 virtual ~ScissorClear() 918 { 919 } 920 921 protected: 922 /* Protected methods inherited from DrawTestBase */ 923 virtual bool checkResults(Utils::texture &texture_0, Utils::texture &texture_1, glw::GLuint draw_call_index); 924 925 virtual TEST_TYPE getTestType(); 926 virtual bool isClearTest(); 927 }; 928 929 /** Implements test DepthRange, description follows: 930 * 931 * Verify that depth range is applied as expected. 932 * Steps: 933 * - prepate 2D 16x2 R32F texture filled with value -1.0 and set it up as 934 * COLOR_ATTACHMENT_0; 935 * - prepare program that consist of: 936 * * boilerplate vertex shader, 937 * * geometry shader, 938 * * fragment shader; 939 * Geometry shader should emit two quads: 940 * * -1,0 : 1,1 with z equal -1.0, 941 * * -1,-1 : 1,0 with z equal 1.0, 942 * made of triangle_strip; gl_ViewportIndex should be assigned an value of 943 * gl_InvocationId; Amount of geometry shader invocations should be set to 16; 944 * Fragment shader should output value of gl_FragCoord.z to attachment 0. 945 * - set up first 16 viewports with the following code snippet: 946 * 947 * const double step = 1.0 / 16.0; 948 * for (index = 0; index < 16; ++index) 949 * { 950 * const double near = ((double) i) * step; 951 * VieportIndexed (i, (float) i, 0.0, 1.0, 2.0); 952 * DepthRangeIndexed(i, near, 1.0 - near); 953 * } 954 * 955 * - draw single vertex; 956 * - inspect contents of COLOR_ATTACHMENT_0; 957 * - test pass if: 958 * * top row of image is filled with increasing values, starting at 0 with 959 * step 1/16; 960 * * bottom row of image is filled with decreasing values, starting at 1 with 961 * step 1/16; 962 * - repeat test with function DepthRangeArrayv; 963 **/ 964 class DepthRange : public DrawTestBase 965 { 966 public: 967 /* Public methods */ 968 DepthRange(deqp::Context &context, const glcts::ExtParameters &extParams); ~DepthRange()969 virtual ~DepthRange() 970 { 971 } 972 973 protected: 974 /* Protected methods inherited from DrawTestBase */ 975 virtual bool checkResults(Utils::texture &texture_0, Utils::texture &texture_1, glw::GLuint draw_call_index); 976 977 virtual std::string getFragmentShader(); 978 virtual std::string getGeometryShader(); 979 virtual TEST_TYPE getTestType(); 980 981 virtual void prepareTextures(Utils::texture &texture_0, Utils::texture &texture_1); 982 }; 983 984 /** Implements test DepthRangeDepthTest, description follows: 985 * 986 * Verify that depth test work as expected with multiple viewports. 987 * Modify DepthRange test in the following aspect: 988 * - add second 2D 16x2 DEPTH_COMPONENT32F texture and set it up as 989 * DEPTH_ATTACHMENT; 990 * - enable DEPTH_TEST; 991 * - DepthFunc should be set to LESS (initial value); 992 * - 18 times: 993 * * set ClearDepth to "i" * 1/16, starting at 0 up to 17/16, 994 * * draw single vertex 995 * * verify contents of color attachment; 996 * - test pass when color attachment is filled only with values lower than 997 * current ClearDepth value; 998 **/ 999 class DepthRangeDepthTest : public DrawTestBase 1000 { 1001 public: 1002 /* Public methods */ 1003 DepthRangeDepthTest(deqp::Context &context, const glcts::ExtParameters &extParams); 1004 ~DepthRangeDepthTest()1005 virtual ~DepthRangeDepthTest() 1006 { 1007 } 1008 1009 protected: 1010 /* Protected methods inherited from DrawTestBase */ 1011 virtual bool checkResults(Utils::texture &texture_0, Utils::texture &texture_1, glw::GLuint draw_call_index); 1012 1013 virtual void getClearSettings(bool &clear_depth_before_draw, glw::GLuint iteration_index, 1014 glw::GLfloat &depth_value); 1015 1016 virtual glw::GLuint getDrawCallsNumber(); 1017 virtual std::string getFragmentShader(); 1018 virtual std::string getGeometryShader(); 1019 virtual TEST_TYPE getTestType(); 1020 1021 virtual void prepareTextures(Utils::texture &texture_0, Utils::texture &texture_1); 1022 1023 virtual void setupFramebuffer(Utils::framebuffer &framebuffer, Utils::texture &texture_0, 1024 Utils::texture &texture_1); 1025 1026 virtual void setupViewports(TEST_TYPE type, glw::GLuint iteration_index); 1027 }; 1028 1029 /** Implements test ProvokingVertex, description follows: 1030 * 1031 * Verify that provoking vertex work as expected. 1032 * Steps: 1033 * - prepare 2D array R32I 128x128x4 texture and configure it as 1034 * COLOR_ATTACHMENT_0; 1035 * - prepare program consisting of: 1036 * * boilerplate vertex shader, 1037 * * geometry shader, 1038 * * fragment shader; 1039 * Geometry shader should output a quad (-1,-1 : 1,1); Each vertex should 1040 * receive different gl_ViewportIndex value, first vertex should be assigned an 1041 * 0, second 1, third 2, fourth 3; gl_Layer should be set in the same way as 1042 * gl_ViewportIndex; Fragment shader should output integer of value 1; 1043 * - configure first four viewports to form 2x2 grid, spanning whole image; 1044 * - for each combination of LAYER_PROVOKING_VERTEX and 1045 * VIEWPORT_INDEX_PROVOKING_VERTEX: 1046 * * clear framebuffer to (0,0,0,0), 1047 * * draw single vertex 1048 * * inspect image; 1049 * - test pass if correct area of correct layer is filled with value 1, while 1050 * rest of image remains "clean"; 1051 * Notes: 1052 * - for UNDEFINED_VERTEX any selection is correct; 1053 * - for PROVOKING_VERTEX convention is selected by function ProvokingVertex; 1054 * Test all possible combinations; 1055 **/ 1056 class ProvokingVertex : public DrawTestBase 1057 { 1058 public: 1059 /* Public methods */ 1060 ProvokingVertex(deqp::Context &context, const glcts::ExtParameters &extParams); 1061 ~ProvokingVertex()1062 virtual ~ProvokingVertex() 1063 { 1064 } 1065 1066 protected: 1067 /* Protected methods inherited from DrawTestBase */ 1068 virtual bool checkResults(Utils::texture &texture_0, Utils::texture &texture_1, glw::GLuint draw_call_index); 1069 1070 virtual std::string getFragmentShader(); 1071 virtual std::string getGeometryShader(); 1072 virtual TEST_TYPE getTestType(); 1073 1074 virtual void prepareTextures(Utils::texture &texture_0, Utils::texture &texture_1); 1075 }; 1076 } // namespace ViewportArray 1077 1078 /** Group class for Shader Language 420Pack conformance tests */ 1079 class ViewportArrayTests : public glcts::TestCaseGroupBase 1080 { 1081 public: 1082 /* Public methods */ 1083 ViewportArrayTests(deqp::Context &context, const glcts::ExtParameters &extParams); 1084 ~ViewportArrayTests(void)1085 virtual ~ViewportArrayTests(void) 1086 { 1087 } 1088 1089 virtual void init(void); 1090 1091 private: 1092 /* Private methods */ 1093 ViewportArrayTests(const ViewportArrayTests &other); 1094 ViewportArrayTests &operator=(const ViewportArrayTests &other); 1095 }; 1096 1097 } // namespace glcts 1098 1099 #endif // _GLCVIEWPORTARRAYTESTS_HPP 1100