Home | History | Annotate | Download | only in common
      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