xref: /aosp_15_r20/external/deqp/external/openglcts/modules/gl/gl3cClipDistance.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 #ifndef _GL3CCLIPDISTANCE_HPP
2 #define _GL3CCLIPDISTANCE_HPP
3 /*-------------------------------------------------------------------------
4  * OpenGL Conformance Test Suite
5  * -----------------------------
6  *
7  * Copyright (c) 2015-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  */ /*!
28  * \file  gl3cClipDistance.hpp
29  * \brief Conformance tests for Clip Distance feature functionality.
30  */ /*-------------------------------------------------------------------*/
31 
32 #include "glcTestCase.hpp"
33 #include "gluDefs.hpp"
34 #include "glwDefs.hpp"
35 #include "tcuDefs.hpp"
36 
37 /* Includes. */
38 #include <cstring>
39 #include <map>
40 #include <typeinfo>
41 #include <vector>
42 
43 #include "glwEnums.hpp"
44 #include "glwFunctions.hpp"
45 
46 namespace gl3cts
47 {
48 namespace ClipDistance
49 {
50 namespace Utility
51 {
52 /** @class Program
53  *
54  *  @brief GLSL program encapsulation class.
55  */
56 class Program
57 {
58 public:
59     /* Public type definitions */
60 
61     /** @struct CompilationStatus
62      *
63      *  @brief GLSL shader encapsulation class.
64      */
65     struct CompilationStatus
66     {
67         glw::GLuint shader_id;
68         glw::GLint shader_compilation_status;
69         std::string shader_log;
70     };
71 
72     /** @struct CompilationStatus
73      *
74      *  @brief GLSL shader encapsulation class.
75      */
76     struct LinkageStatus
77     {
78         glw::GLuint program_id;
79         glw::GLint program_linkage_status;
80         std::string program_linkage_log;
81     };
82 
83     /* Public member variables */
84     Program(const glw::Functions &gl, const std::string &vertex_shader_code, const std::string &fragment_shader_code,
85             std::vector<std::string> transform_feedback_varyings = std::vector<std::string>());
86 
87     ~Program();
88 
89     const CompilationStatus &VertexShaderStatus() const;
90     const CompilationStatus &FragmentShaderStatus() const;
91     const LinkageStatus &ProgramStatus() const;
92 
93     void UseProgram() const;
94 
95 private:
96     /* Private member variables */
97     CompilationStatus m_vertex_shader_status;
98     CompilationStatus m_fragment_shader_status;
99     LinkageStatus m_program_status;
100 
101     const glw::Functions &m_gl;
102 
103     /* Private member functions */
104     CompilationStatus compileShader(const glw::GLenum shader_type, const glw::GLchar *const *shader_code);
105 
106     LinkageStatus linkShaders(const CompilationStatus &vertex_shader, const CompilationStatus &fragment_shader,
107                               std::vector<std::string> &transform_feedback_varyings);
108 };
109 /* Program class */
110 
111 /** @class Framebuffer
112  *
113  *  @brief OpenGL's Framebuffer encapsulation class.
114  *
115  *  @note Created framebuffer is red-color-only and float type.
116  */
117 class Framebuffer
118 {
119 public:
120     Framebuffer(const glw::Functions &gl, const glw::GLsizei size_x, const glw::GLsizei size_y);
121     ~Framebuffer();
122 
123     bool isValid();
124     void bind();
125     std::vector<glw::GLfloat> readPixels();
126     void clear();
127 
128 private:
129     const glw::Functions &m_gl;
130     const glw::GLsizei m_size_x;
131     const glw::GLsizei m_size_y;
132     glw::GLuint m_framebuffer_id;
133     glw::GLuint m_renderbuffer_id;
134 };
135 /* Framebuffer class */
136 
137 /** @class Vertex Array Object
138  *
139  *  @brief OpenGL's Vertex Array Object encapsulation class.
140  */
141 class VertexArrayObject
142 {
143 public:
144     VertexArrayObject(const glw::Functions &gl, const glw::GLenum primitive_type); // create empty vao
145     ~VertexArrayObject();
146 
147     void bind();
148     void draw(glw::GLuint first, glw::GLuint count);
149     void drawWithTransformFeedback(glw::GLuint first, glw::GLuint count, bool discard_rasterizer);
150 
151 private:
152     const glw::Functions &m_gl;
153     glw::GLuint m_vertex_array_object_id;
154     glw::GLenum m_primitive_type;
155 };
156 /* VertexArrayObject class */
157 
158 /** @class Vertex Buffer Object
159  *
160  *  @brief OpenGL's Vertex Buffer Object encapsulation template class.
161  *
162  *  @note Input data type is a template parameter.
163  */
164 template <class T>
165 class VertexBufferObject
166 {
167 public:
168     VertexBufferObject(const glw::Functions &gl, const glw::GLenum target, std::vector<T> data);
169     ~VertexBufferObject();
170 
171     bool bind();
172     bool useAsShaderInput(Program program, std::string input_attribute_name, glw::GLint number_of_components);
173     std::vector<T> readBuffer();
174 
175 private:
176     const glw::Functions &m_gl;
177     glw::GLuint m_vertex_buffer_object_id;
178     glw::GLenum m_target;
179     glw::GLsizei m_size;
180 
181     std::vector<glw::GLint> m_enabled_arrays;
182 };
183 /* VertexBufferObject template class */
184 
185 std::string preprocessCode(std::string source, std::string key, std::string value);
186 std::string itoa(glw::GLint i);
187 } // namespace Utility
188 
189 /** @class Tests
190  *
191  *  @brief Clip distance test group.
192  */
193 class Tests : public deqp::TestCaseGroup
194 {
195 public:
196     /* Public member functions */
197     Tests(deqp::Context &context);
198 
199     void init();
200 
201 private:
202     /* Private member functions */
203     Tests(const Tests &other);
204     Tests &operator=(const Tests &other);
205 };
206 
207 /** @class CoverageTest
208  *
209  *  @brief Clip distance API Coverage test cases.
210  */
211 class CoverageTest : public deqp::TestCase
212 {
213 public:
214     /* Public member functions */
215     CoverageTest(deqp::Context &context);
216 
217     virtual tcu::TestNode::IterateResult iterate();
218 
219 private:
220     /* Private member functions */
221     CoverageTest(const CoverageTest &other);
222     CoverageTest &operator=(const CoverageTest &other);
223 
224     bool MaxClipDistancesValueTest(const glw::Functions &gl);
225     bool EnableDisableTest(const glw::Functions &gl);
226     bool MaxClipDistancesValueInVertexShaderTest(const glw::Functions &gl);
227     bool MaxClipDistancesValueInFragmentShaderTest(const glw::Functions &gl);
228     bool ClipDistancesValuePassing(const glw::Functions &gl);
229 
230     /* Private member variables */
231     glw::GLint m_gl_max_clip_distances_value;
232 
233     /* Private static constants */
234     static const glw::GLchar *m_vertex_shader_code_case_0;
235     static const glw::GLchar *m_fragment_shader_code_case_0;
236 
237     static const glw::GLchar *m_vertex_shader_code_case_1;
238     static const glw::GLchar *m_fragment_shader_code_case_1;
239 
240     static const glw::GLchar *m_vertex_shader_code_case_2;
241     static const glw::GLchar *m_fragment_shader_code_case_2;
242 };
243 
244 /** @class FunctionalTest
245  *
246  *  @brief Clip distance Functional test cases.
247  */
248 class FunctionalTest : public deqp::TestCase
249 {
250 public:
251     /* Public member functions */
252     FunctionalTest(deqp::Context &context);
253 
254     virtual void init();
255     virtual tcu::TestNode::IterateResult iterate();
256 
257 private:
258     /* Private member functions */
259     FunctionalTest(const FunctionalTest &other);
260     FunctionalTest &operator=(const FunctionalTest &other);
261 
262     std::string prepareVertexShaderCode(bool explicit_redeclaration, bool dynamic_setter, glw::GLuint clip_count,
263                                         glw::GLuint clip_function, glw::GLenum primitive_type);
264 
265     gl3cts::ClipDistance::Utility::VertexBufferObject<glw::GLfloat> *prepareGeometry(const glw::Functions &gl,
266                                                                                      const glw::GLenum primitive_type);
267 
268     bool checkResults(glw::GLenum primitive_type, glw::GLuint clip_function, std::vector<glw::GLfloat> &results);
269 
270     /* Private member variables */
271     glw::GLint m_gl_max_clip_distances_value;
272 
273     /* Private static constants */
274     static const glw::GLchar *m_vertex_shader_code;
275     static const glw::GLchar *m_fragment_shader_code;
276     static const glw::GLchar *m_dynamic_array_setter;
277     static const glw::GLchar *m_static_array_setter;
278     static const glw::GLchar *m_explicit_redeclaration;
279     static const glw::GLchar *m_clip_function[];
280     static const glw::GLuint m_clip_function_count;
281 
282     static const glw::GLenum m_primitive_types[];
283     static const glw::GLenum m_primitive_indices[];
284     static const glw::GLuint m_primitive_types_count;
285 
286     static const glw::GLfloat m_expected_integral[];
287 };
288 
289 /** @class NegativeTest
290  *
291  *  @brief Clip distance API Negative test cases.
292  */
293 class NegativeTest : public deqp::TestCase
294 {
295 public:
296     /* Public member functions */
297     NegativeTest(deqp::Context &context);
298 
299     virtual tcu::TestNode::IterateResult iterate();
300 
301 private:
302     /* Private member functions */
303     NegativeTest(const NegativeTest &other);
304     NegativeTest &operator=(const NegativeTest &other);
305 
306     bool testClipVertexBuildingErrors(const glw::Functions &gl);
307     bool testMaxClipDistancesBuildingErrors(const glw::Functions &gl);
308     bool testClipDistancesRedeclarationBuildingErrors(const glw::Functions &gl);
309 
310     /* Private static constants */
311     static const glw::GLchar *m_vertex_shader_code_case_0;
312     static const glw::GLchar *m_vertex_shader_code_case_1;
313     static const glw::GLchar *m_vertex_shader_code_case_2;
314     static const glw::GLchar *m_fragment_shader_code;
315 };
316 } // namespace ClipDistance
317 } // namespace gl3cts
318 
319 /* Template classes' implementation */
320 
321 /** @brief Vertex Buffer Object constructor.
322  *
323  *  @note It silently binds VAO to OpenGL.
324  *
325  *  @param [in] gl               OpenGL functions access.
326  *  @param [in] target           Binding target of the VBO.
327  *  @param [in] data             Data of the buffer (may be empty).
328  */
329 template <class T>
VertexBufferObject(const glw::Functions & gl,const glw::GLenum target,std::vector<T> data)330 gl3cts::ClipDistance::Utility::VertexBufferObject<T>::VertexBufferObject(const glw::Functions &gl,
331                                                                          const glw::GLenum target, std::vector<T> data)
332     : m_gl(gl)
333     , m_vertex_buffer_object_id(0)
334     , m_target(target)
335     , m_size(0)
336 {
337     m_gl.genBuffers(1, &m_vertex_buffer_object_id);
338     GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenBuffers call failed.");
339 
340     if (m_vertex_buffer_object_id)
341     {
342         m_size = (glw::GLsizei)(sizeof(T) * data.size());
343 
344         bind();
345 
346         m_gl.bufferData(m_target, m_size, &data[0], GL_STATIC_DRAW);
347         GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferData call failed.");
348     }
349 }
350 
351 /** @brief Vertex Buffer Object destructor. */
352 template <class T>
~VertexBufferObject()353 gl3cts::ClipDistance::Utility::VertexBufferObject<T>::~VertexBufferObject()
354 {
355     m_gl.deleteBuffers(1, &m_vertex_buffer_object_id); /* Delete silently unbinds the buffer. */
356     GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDeleteBuffers call failed.");
357 
358     for (std::vector<glw::GLint>::iterator i_enabled_array = m_enabled_arrays.begin();
359          i_enabled_array != m_enabled_arrays.end(); ++i_enabled_array)
360     {
361         m_gl.disableVertexAttribArray(*i_enabled_array);
362     }
363 }
364 
365 /** @brief Bind Vertex Buffer Object to its target.
366  *
367  *  @note It binds also to indexed binding point for GL_TRANSFORM_FEEDBACK_BUFFER target.
368  */
369 template <class T>
bind()370 bool gl3cts::ClipDistance::Utility::VertexBufferObject<T>::bind()
371 {
372     if (m_vertex_buffer_object_id)
373     {
374         m_gl.bindBuffer(m_target, m_vertex_buffer_object_id);
375         GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer call failed.");
376 
377         if (m_target == GL_TRANSFORM_FEEDBACK_BUFFER)
378         {
379             m_gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_vertex_buffer_object_id);
380             GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBufferBase call failed.");
381         }
382 
383         return true;
384     }
385 
386     return false;
387 }
388 
389 /** @brief Use VBO as attribute vertex array.
390  *
391  *  @note It silently binds VBO.
392  *
393  *  @param [in] program                 GLSL Program to which VBO shall be bound.
394  *  @param [in] input_attribute_name    Name of GLSL asttribute.
395  *  @param [in] number_of_components    Number of attribute's components.
396  *
397  *  @return True on success, false otherwise.
398  */
399 template <class T>
useAsShaderInput(Program program,std::string input_attribute_name,glw::GLint number_of_components)400 bool gl3cts::ClipDistance::Utility::VertexBufferObject<T>::useAsShaderInput(Program program,
401                                                                             std::string input_attribute_name,
402                                                                             glw::GLint number_of_components)
403 {
404     if (program.ProgramStatus().program_id)
405     {
406         glw::GLint location = m_gl.getAttribLocation(program.ProgramStatus().program_id, input_attribute_name.c_str());
407         GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGetAttribLocation call failed.");
408 
409         if (location >= 0)
410         {
411             const std::type_info &buffer_type = typeid(T);
412             const std::type_info &float_type  = typeid(glw::GLfloat);
413             const std::type_info &int_type    = typeid(glw::GLint);
414 
415             m_gl.enableVertexAttribArray(location);
416             GLU_EXPECT_NO_ERROR(m_gl.getError(), "glEnableVertexAttribArray call failed.");
417             m_enabled_arrays.push_back(location);
418 
419             bind();
420 
421             if (buffer_type == float_type)
422             {
423                 m_gl.vertexAttribPointer(location, number_of_components, GL_FLOAT, false, 0, NULL);
424                 GLU_EXPECT_NO_ERROR(m_gl.getError(), "glVertexAttribPointer call failed.");
425             }
426             else if (buffer_type == int_type)
427             {
428                 m_gl.vertexAttribIPointer(location, number_of_components, GL_FLOAT, 0, NULL);
429                 GLU_EXPECT_NO_ERROR(m_gl.getError(), "glVertexAttribIPointer call failed.");
430             }
431             else
432             {
433                 return false;
434             }
435 
436             return true;
437         }
438     }
439 
440     return false;
441 }
442 
443 /** @brief Read VBO content (potentially set by transform feedback).
444  *
445  *  @return Content of VBO.
446  */
447 template <class T>
readBuffer()448 std::vector<T> gl3cts::ClipDistance::Utility::VertexBufferObject<T>::readBuffer()
449 {
450     std::vector<T> buffer_data(m_size / sizeof(T));
451 
452     bind();
453 
454     glw::GLvoid *results = m_gl.mapBuffer(m_target, GL_READ_ONLY);
455 
456     if (results)
457     {
458         memcpy(&buffer_data[0], results, m_size);
459     }
460 
461     m_gl.unmapBuffer(m_target);
462 
463     return buffer_data;
464 }
465 #endif // _GL3CCLIPDISTANCE_HPP
466