1 #ifndef _GLCROBUSTBUFFERACCESSBEHAVIORTESTS_HPP 2 #define _GLCROBUSTBUFFERACCESSBEHAVIORTESTS_HPP 3 /*------------------------------------------------------------------------- 4 * OpenGL Conformance Test Suite 5 * ----------------------------- 6 * 7 * Copyright (c) 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 * \file glcRobustBufferAccessBehaviorTests.hpp 27 * \brief Declares test classes for "Robust Buffer Access Behavior" functionality. 28 */ /*-------------------------------------------------------------------*/ 29 30 #include "glcTestCase.hpp" 31 #include "glwDefs.hpp" 32 #include "glwEnums.hpp" 33 34 namespace deqp 35 { 36 namespace RobustBufferAccessBehavior 37 { 38 /** Replace first occurance of <token> with <text> in <string> starting at <search_posistion> 39 **/ 40 void replaceToken(const glw::GLchar* token, size_t& search_position, const glw::GLchar* text, std::string& string); 41 42 /** Represents buffer instance 43 * Provides basic buffer functionality 44 **/ 45 class Buffer 46 { 47 public: 48 /* Public methods */ 49 /* Ctr & Dtr */ 50 Buffer(deqp::Context& context); 51 ~Buffer(); 52 53 /* Init & Release */ 54 void InitData(glw::GLenum target, glw::GLenum usage, glw::GLsizeiptr size, const glw::GLvoid* data); 55 void Release(); 56 57 /* Functionality */ 58 void Bind() const; 59 void BindBase(glw::GLuint index) const; 60 61 /* Public static routines */ 62 /* Functionality */ 63 static void Bind(const glw::Functions& gl, glw::GLuint id, glw::GLenum target); 64 static void BindBase(const glw::Functions& gl, glw::GLuint id, glw::GLenum target, glw::GLuint index); 65 static void Data(const glw::Functions& gl, glw::GLenum target, glw::GLenum usage, glw::GLsizeiptr size, 66 const glw::GLvoid* data); 67 static void Generate(const glw::Functions& gl, glw::GLuint& out_id); 68 static void SubData(const glw::Functions& gl, glw::GLenum target, glw::GLintptr offset, glw::GLsizeiptr size, 69 glw::GLvoid* data); 70 71 /* Public fields */ 72 glw::GLuint m_id; 73 74 /* Public constants */ 75 static const glw::GLuint m_invalid_id; 76 static const glw::GLuint m_n_targets = 13; 77 static const glw::GLenum m_targets[m_n_targets]; 78 79 private: 80 /* Private enums */ 81 82 /* Private fields */ 83 deqp::Context& m_context; 84 glw::GLenum m_target; 85 }; 86 87 /** Represents framebuffer 88 * Provides basic functionality 89 **/ 90 class Framebuffer 91 { 92 public: 93 /* Public methods */ 94 /* Ctr & Dtr */ 95 Framebuffer(deqp::Context& context); 96 ~Framebuffer(); 97 98 /* Init & Release */ 99 void Release(); 100 101 /* Public static routines */ 102 static void AttachTexture(const glw::Functions& gl, glw::GLenum target, glw::GLenum attachment, 103 glw::GLuint texture_id, glw::GLint level, glw::GLuint width, glw::GLuint height); 104 105 static void Bind(const glw::Functions& gl, glw::GLenum target, glw::GLuint id); 106 static void Generate(const glw::Functions& gl, glw::GLuint& out_id); 107 108 /* Public fields */ 109 glw::GLuint m_id; 110 111 /* Public constants */ 112 static const glw::GLuint m_invalid_id; 113 114 private: 115 /* Private fields */ 116 deqp::Context& m_context; 117 }; 118 119 /** Represents shader instance. 120 * Provides basic functionality for shaders. 121 **/ 122 class Shader 123 { 124 public: 125 /* Public methods */ 126 /* Ctr & Dtr */ 127 Shader(deqp::Context& context); 128 ~Shader(); 129 130 /* Init & Realese */ 131 void Init(glw::GLenum stage, const std::string& source); 132 void Release(); 133 134 /* Public static routines */ 135 /* Functionality */ 136 static void Compile(const glw::Functions& gl, glw::GLuint id); 137 static void Create(const glw::Functions& gl, glw::GLenum stage, glw::GLuint& out_id); 138 static void Source(const glw::Functions& gl, glw::GLuint id, const std::string& source); 139 140 /* Public fields */ 141 glw::GLuint m_id; 142 143 /* Public constants */ 144 static const glw::GLuint m_invalid_id; 145 146 private: 147 /* Private fields */ 148 deqp::Context& m_context; 149 }; 150 151 /** Represents program instance. 152 * Provides basic functionality 153 **/ 154 class Program 155 { 156 public: 157 /* Public methods */ 158 /* Ctr & Dtr */ 159 Program(deqp::Context& context); 160 ~Program(); 161 162 /* Init & Release */ 163 void Init(const std::string& compute_shader, const std::string& fragment_shader, const std::string& geometry_shader, 164 const std::string& tesselation_control_shader, const std::string& tesselation_evaluation_shader, 165 const std::string& vertex_shader); 166 167 void Release(); 168 169 /* Functionality */ 170 void Use() const; 171 172 /* Public static routines */ 173 /* Functionality */ 174 static void Attach(const glw::Functions& gl, glw::GLuint program_id, glw::GLuint shader_id); 175 static void Create(const glw::Functions& gl, glw::GLuint& out_id); 176 static void Link(const glw::Functions& gl, glw::GLuint id); 177 static void Use(const glw::Functions& gl, glw::GLuint id); 178 179 /* Public fields */ 180 glw::GLuint m_id; 181 182 Shader m_compute; 183 Shader m_fragment; 184 Shader m_geometry; 185 Shader m_tess_ctrl; 186 Shader m_tess_eval; 187 Shader m_vertex; 188 189 /* Public constants */ 190 static const glw::GLuint m_invalid_id; 191 192 private: 193 /* Private fields */ 194 deqp::Context& m_context; 195 }; 196 197 /** Represents texture instance 198 **/ 199 class Texture 200 { 201 public: 202 /* Public methods */ 203 /* Ctr & Dtr */ 204 Texture(deqp::Context& context); 205 ~Texture(); 206 207 /* Init & Release */ 208 void Release(); 209 210 /* Public static routines */ 211 /* Functionality */ 212 static void Bind(const glw::Functions& gl, glw::GLuint id, glw::GLenum target); 213 214 static void CompressedImage(const glw::Functions& gl, glw::GLenum target, glw::GLint level, 215 glw::GLenum internal_format, glw::GLuint width, glw::GLuint height, glw::GLuint depth, 216 glw::GLsizei image_size, const glw::GLvoid* data); 217 218 static void Generate(const glw::Functions& gl, glw::GLuint& out_id); 219 220 static void GetData(const glw::Functions& gl, glw::GLint level, glw::GLenum target, glw::GLenum format, 221 glw::GLenum type, glw::GLvoid* out_data); 222 223 static void GetData(const glw::Functions& gl, glw::GLuint id, glw::GLint level, glw::GLuint width, 224 glw::GLuint height, glw::GLenum format, glw::GLenum type, glw::GLvoid* out_data); 225 226 static void GetLevelParameter(const glw::Functions& gl, glw::GLenum target, glw::GLint level, glw::GLenum pname, 227 glw::GLint* param); 228 229 static void Image(const glw::Functions& gl, glw::GLenum target, glw::GLint level, glw::GLenum internal_format, 230 glw::GLuint width, glw::GLuint height, glw::GLuint depth, glw::GLenum format, glw::GLenum type, 231 const glw::GLvoid* data); 232 233 static void Storage(const glw::Functions& gl, glw::GLenum target, glw::GLsizei levels, glw::GLenum internal_format, 234 glw::GLuint width, glw::GLuint height, glw::GLuint depth); 235 236 static void SubImage(const glw::Functions& gl, glw::GLenum target, glw::GLint level, glw::GLint x, glw::GLint y, 237 glw::GLint z, glw::GLsizei width, glw::GLsizei height, glw::GLsizei depth, glw::GLenum format, 238 glw::GLenum type, const glw::GLvoid* pixels); 239 240 /* Public fields */ 241 glw::GLuint m_id; 242 243 /* Public constants */ 244 static const glw::GLuint m_invalid_id; 245 246 private: 247 /* Private fields */ 248 deqp::Context& m_context; 249 }; 250 251 /** Represents Vertex array object 252 * Provides basic functionality 253 **/ 254 class VertexArray 255 { 256 public: 257 /* Public methods */ 258 /* Ctr & Dtr */ 259 VertexArray(deqp::Context& Context); 260 ~VertexArray(); 261 262 /* Init & Release */ 263 void Release(); 264 265 /* Public static methods */ 266 static void Bind(const glw::Functions& gl, glw::GLuint id); 267 static void Generate(const glw::Functions& gl, glw::GLuint& out_id); 268 269 /* Public fields */ 270 glw::GLuint m_id; 271 272 /* Public constants */ 273 static const glw::GLuint m_invalid_id; 274 275 private: 276 /* Private fields */ 277 deqp::Context& m_context; 278 }; 279 280 /** Implementation of test VertexBufferObjects. Description follows: 281 * 282 * This test verifies that any "out-of-bound" read from vertex buffer result with abnormal program exit 283 * 284 * Steps: 285 * - prepare vertex buffer with the following vertices: 286 * * 0 - [ 0, 0, 0], 287 * * 1 - [-1, 0, 0], 288 * * 2 - [-1, 1, 0], 289 * * 3 - [ 0, 1, 0], 290 * * 4 - [ 1, 1, 0], 291 * * 5 - [ 1, 0, 0], 292 * * 6 - [ 1, -1, 0], 293 * * 7 - [ 0, -1, 0], 294 * * 8 - [-1, -1, 0]; 295 * - prepare element buffer: 296 * * valid: 297 * 0, 1, 2, 298 * 0, 2, 3, 299 * 0, 3, 4, 300 * 0, 4, 5, 301 * 0, 5, 6, 302 * 0, 6, 7, 303 * 0, 7, 8, 304 * 0, 8, 1; 305 * * invalid: 306 * 9, 1, 2, 307 * 10, 2, 3, 308 * 11, 3, 4, 309 * 12, 4, 5, 310 * 13, 5, 6, 311 * 14, 6, 7, 312 * 15, 7, 8, 313 * 16, 8, 1; 314 * - prepare program consisting of vertex and fragment shader that will output 315 * value 1; 316 * - prepare framebuffer with R8UI texture attached as color 0, filled with 317 * value 128; 318 * - execute draw call with invalid element buffer; 319 * - inspect contents of framebuffer, it is expected that it is filled with 320 * value 1; 321 * - clean framebuffer to value 128; 322 * - execute draw call with valid element buffer; 323 * - inspect contents of framebuffer, it is expected that it is filled with 324 * value 1. 325 **/ 326 class VertexBufferObjectsTest : public deqp::TestCase 327 { 328 public: 329 /* Public methods */ 330 VertexBufferObjectsTest(deqp::Context& context); 331 VertexBufferObjectsTest(deqp::Context& context, const char* name, const char* description); 332 virtual ~VertexBufferObjectsTest() 333 { 334 } 335 336 /* Public methods inherited from TestCase */ 337 virtual tcu::TestNode::IterateResult iterate(void); 338 339 protected: 340 /* Protected methods */ 341 virtual std::string getFragmentShader(); 342 virtual std::string getVertexShader(); 343 virtual void cleanTexture(glw::GLuint texture_id); 344 virtual bool verifyInvalidResults(glw::GLuint texture_id); 345 virtual bool verifyValidResults(glw::GLuint texture_id); 346 virtual bool verifyResults(glw::GLuint texture_id); 347 }; 348 349 /** Implementation of test TexelFetch. Description follows: 350 * 351 * This test verifies that any "out-of-bound" fetch from texture result in 352 * "zero". 353 * 354 * Steps: 355 * - prepare program consisting of vertex, geometry and fragment shader that 356 * will output full-screen quad; Each fragment should receive value of 357 * corresponding texel from source texture; Use texelFetch function; 358 * - prepare 16x16 2D R8UI source texture filled with unique values; 359 * - prepare framebuffer with 16x16 R8UI texture as color attachment, filled 360 * with value 0; 361 * - execute draw call; 362 * - inspect contents of framebuffer, it is expected to match source texture; 363 * - modify program so it will fetch invalid texels; 364 * - execute draw call; 365 * - inspect contents of framebuffer, it is expected that it will be filled 366 * with value 0 for RGB channels and with 0, 1 or the biggest representable 367 * integral number for alpha channel. 368 * 369 * Repeat steps for: 370 * - R8 texture; 371 * - RG8_SNORM texture; 372 * - RGBA32F texture; 373 * - mipmap at level 1; 374 * - a texture with 4 samples. 375 **/ 376 class TexelFetchTest : public deqp::TestCase 377 { 378 public: 379 /* Public methods */ 380 TexelFetchTest(deqp::Context& context); 381 TexelFetchTest(deqp::Context& context, const glw::GLchar* name, const glw::GLchar* description); 382 virtual ~TexelFetchTest() 383 { 384 } 385 386 /* Public methods inherited from TestCase */ 387 virtual tcu::TestNode::IterateResult iterate(void); 388 389 protected: 390 /* Protected enums */ 391 enum TEST_CASES 392 { 393 R8, 394 RG8_SNORM, 395 R32UI_MULTISAMPLE, 396 RGBA32F, 397 R32UI_MIPMAP, 398 /* */ 399 LAST 400 }; 401 402 enum VERSION 403 { 404 VALID, 405 SOURCE_INVALID, 406 DESTINATION_INVALID, 407 }; 408 409 /* Protected methods */ 410 virtual const glw::GLchar* getTestCaseName() const; 411 virtual void prepareTexture(bool is_source, glw::GLuint texture_id); 412 413 /* Protected fields */ 414 TEST_CASES m_test_case; 415 416 protected: 417 /* Protected methods */ 418 virtual std::string getFragmentShader(bool is_case_valid); 419 virtual std::string getGeometryShader(); 420 virtual std::string getVertexShader(); 421 virtual bool verifyInvalidResults(glw::GLuint texture_id); 422 virtual bool verifyValidResults(glw::GLuint texture_id); 423 }; 424 425 /** Implementation of test ImageLoadStore. Description follows: 426 * 427 * This test verifies that any "out-of-bound" access to image result in "zero" 428 * or is discarded. 429 * 430 * Modify TexelFetch test in the following aspects: 431 * - use compute shader instead of "draw" pipeline; 432 * - use imageLoad instead of texelFetch; 433 * - use destination image instead of framebuffer; Store texel with imageStore; 434 * - for each case from TexelFetch verify: 435 * * valid coordinates for source and destination images; 436 * * invalid coordinates for destination and valid ones for source image; 437 * * valid coordinates for destination and invalid ones for source image. 438 **/ 439 class ImageLoadStoreTest : public TexelFetchTest 440 { 441 public: 442 /* Public methods */ 443 ImageLoadStoreTest(deqp::Context& context); 444 ImageLoadStoreTest(deqp::Context& context, const char* name, const char* description); 445 virtual ~ImageLoadStoreTest() 446 { 447 } 448 449 /* Public methods inherited from TestCase */ 450 virtual tcu::TestNode::IterateResult iterate(void); 451 452 protected: 453 /* Protected methods */ 454 virtual std::string getComputeShader(VERSION version); 455 virtual void setTextures(glw::GLuint id_destination, glw::GLuint id_source); 456 virtual bool verifyInvalidResults(glw::GLuint texture_id); 457 virtual bool verifyValidResults(glw::GLuint texture_id); 458 }; 459 460 /** Implementation of test StorageBuffer. Description follows: 461 * 462 * This test verifies that any "out-of-bound" access to buffer result in zero 463 * or is discarded. 464 * 465 * Steps: 466 * - prepare compute shader based on the following code snippet: 467 * 468 * uint dst_index = gl_LocalInvocationID.x; 469 * uint src_index = gl_LocalInvocationID.x; 470 * destination[dst_index] = source[src_index]; 471 * 472 * where source and destination are storage buffers, defined as unsized arrays 473 * of floats; 474 * - prepare two buffers of 4 floats: 475 * * destination filled with value 1; 476 * * source filled with unique values; 477 * - dispatch program to copy all 4 values; 478 * - inspect program to verify that contents of source buffer were copied to 479 * destination; 480 * - repeat steps for the following cases: 481 * * value of dst_index is equal to gl_LocalInvocationID.x + 16; It is 482 * expected that destination buffer will not be modified; 483 * * value of src_index is equal to gl_LocalInvocationID.x + 16; It is 484 * expected that destination buffer will be filled with value 0. 485 **/ 486 class StorageBufferTest : public deqp::TestCase 487 { 488 public: 489 /* Public methods */ 490 StorageBufferTest(deqp::Context& context); 491 StorageBufferTest(deqp::Context& context, const char* name, const char* description); 492 virtual ~StorageBufferTest() 493 { 494 } 495 496 /* Public methods inherited from TestCase */ 497 virtual tcu::TestNode::IterateResult iterate(void); 498 499 protected: 500 /* Protected enums */ 501 enum VERSION 502 { 503 VALID, 504 SOURCE_INVALID, 505 DESTINATION_INVALID, 506 /* */ 507 LAST 508 }; 509 510 /* Private methods */ 511 virtual std::string getComputeShader(); 512 virtual bool verifyResults(glw::GLfloat* buffer_data); 513 514 /* Protected fields */ 515 VERSION m_test_case; 516 bool m_hasKhrRobustBufferAccess; 517 518 /* Protected constants */ 519 static const glw::GLfloat m_destination_data[4]; 520 static const glw::GLfloat m_source_data[4]; 521 }; 522 523 /** Implementation of test UniformBuffer. Description follows: 524 * 525 * This test verifies that any "out-of-bound" read from uniform buffer result 526 * in zero; 527 * 528 * Modify StorageBuffer test in the following aspects: 529 * - use uniform buffer for source instead of storage buffer; 530 * - ignore the case with invalid value of dst_index. 531 **/ 532 class UniformBufferTest : public deqp::TestCase 533 { 534 public: 535 /* Public methods */ 536 UniformBufferTest(deqp::Context& context); 537 UniformBufferTest(deqp::Context& context, const char* name, const char* description); 538 virtual ~UniformBufferTest() 539 { 540 } 541 542 /* Public methods inherited from TestCase */ 543 virtual tcu::TestNode::IterateResult iterate(void); 544 545 protected: 546 /* Protected enums */ 547 enum VERSION 548 { 549 VALID, 550 SOURCE_INVALID, 551 /* */ 552 LAST 553 }; 554 555 /* Protected methods */ 556 virtual std::string getComputeShader(); 557 virtual bool verifyResults(glw::GLfloat* buffer_data); 558 559 /* Protected fields */ 560 VERSION m_test_case; 561 }; 562 } /* RobustBufferAccessBehavior */ 563 564 /** Group class for multi bind conformance tests */ 565 class RobustBufferAccessBehaviorTests : public deqp::TestCaseGroup 566 { 567 public: 568 /* Public methods */ 569 RobustBufferAccessBehaviorTests(deqp::Context& context); 570 virtual ~RobustBufferAccessBehaviorTests(void) 571 { 572 } 573 574 virtual void init(void); 575 576 private: 577 /* Private methods */ 578 RobustBufferAccessBehaviorTests(const RobustBufferAccessBehaviorTests& other); 579 RobustBufferAccessBehaviorTests& operator=(const RobustBufferAccessBehaviorTests& other); 580 }; 581 582 } /* deqp */ 583 584 #endif // _GLCROBUSTBUFFERACCESSBEHAVIORTESTS_HPP 585