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