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