Fix tests in KHR-GLES32.robust.*
[platform/upstream/VK-GL-CTS.git] / external / openglcts / modules / common / glcRobustBufferAccessBehaviorTests.hpp
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 };
517
518 /** Implementation of test UniformBuffer. Description follows:
519  *
520  * This test verifies that any "out-of-bound" read from uniform buffer result
521  * in zero;
522  *
523  * Modify StorageBuffer test in the following aspects:
524  * - use uniform buffer for source instead of storage buffer;
525  * - ignore the case with invalid value of dst_index.
526  **/
527 class UniformBufferTest : public deqp::TestCase
528 {
529 public:
530         /* Public methods */
531         UniformBufferTest(deqp::Context& context);
532         UniformBufferTest(deqp::Context& context, const char* name, const char* description);
533         virtual ~UniformBufferTest()
534         {
535         }
536
537         /* Public methods inherited from TestCase */
538         virtual tcu::TestNode::IterateResult iterate(void);
539
540 protected:
541         /* Protected enums */
542         enum VERSION
543         {
544                 VALID,
545                 SOURCE_INVALID,
546                 /* */
547                 LAST
548         };
549
550         /* Protected methods */
551         virtual std::string getComputeShader();
552         virtual bool verifyResults(glw::GLfloat* buffer_data);
553
554         /* Protected fields */
555         VERSION m_test_case;
556 };
557 } /* RobustBufferAccessBehavior */
558
559 /** Group class for multi bind conformance tests */
560 class RobustBufferAccessBehaviorTests : public deqp::TestCaseGroup
561 {
562 public:
563         /* Public methods */
564         RobustBufferAccessBehaviorTests(deqp::Context& context);
565         virtual ~RobustBufferAccessBehaviorTests(void)
566         {
567         }
568
569         virtual void init(void);
570
571 private:
572         /* Private methods */
573         RobustBufferAccessBehaviorTests(const RobustBufferAccessBehaviorTests& other);
574         RobustBufferAccessBehaviorTests& operator=(const RobustBufferAccessBehaviorTests& other);
575 };
576
577 } /* deqp */
578
579 #endif // _GLCROBUSTBUFFERACCESSBEHAVIORTESTS_HPP