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