• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef _GLCCULLDISTANCE_HPP
2 #define _GLCCULLDISTANCE_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  gl3cCullDistanceTests.hpp
29  * \brief  Cull Distance Test Suite Interface
30  */ /*-------------------------------------------------------------------*/
31 
32 #include "glcTestCase.hpp"
33 #include "glwDefs.hpp"
34 
35 #include <map>
36 
37 namespace glcts
38 {
39 namespace CullDistance
40 {
41 /** @brief Cull Distance Test utility class
42  *
43  *  This class contains utility static function members
44  *  helpful to OpenGL shader template based construction
45  *  and building process.
46  */
47 class Utilities
48 {
49 public:
50     /* Public static methods */
51     static void buildProgram(const glw::Functions &gl, tcu::TestContext &testCtx, const glw::GLchar *cs_body,
52                              const glw::GLchar *fs_body, const glw::GLchar *gs_body, const glw::GLchar *tc_body,
53                              const glw::GLchar *te_body, const glw::GLchar *vs_body, const glw::GLuint &n_tf_varyings,
54                              const glw::GLchar **tf_varyings, glw::GLuint *out_program);
55 
56     static void replaceAll(std::string &str, const std::string &from, const std::string &to);
57 
58     static std::string intToString(glw::GLint integer);
59 };
60 
61 /** @class CullDistanceTestBase
62  *
63  *  @brief Cull distance test cases base class.
64  */
65 class CullDistanceTestBase : public deqp::TestCase
66 {
67 public:
68     /* Public member functions */
69     CullDistanceTestBase(deqp::Context &context, const char *name, const char *description);
70 
71     tcu::TestNode::IterateResult iterate() override;
72 
73 protected:
74     /* Protected methods */
75     virtual void test(void) = 0;
76 
77 protected:
78     /* Protected constants */
79     std::map<std::string, std::string> specializationMap;
80 
81     bool m_extensionSupported;
82     bool m_isContextES;
83 };
84 
85 /** @brief Cull Distance API Coverage Test class
86  *
87  *  This class contains basic API coverage test,
88  *  which check if the implementation provides
89  *  basic cull distance structures:
90  *
91  *   * Checks that calling GetIntegerv with MAX_CULL_DISTANCES doesn't generate
92  *    any errors and returns a value at least 8.
93  *
94  *   * Checks that calling GetIntegerv with MAX_COMBINED_CLIP_AND_CULL_DISTANCES
95  *     doesn't generate any errors and returns a value at least 8.
96  *
97  *   * Checks that using the GLSL built-in constant gl_MaxCullDistance in any
98  *     shader stage (including compute shader) compiles and links successfully
99  *     and that the value of the built-in constant is at least 8.
100  *
101  *   * Checks that using the GLSL built-in constant gl_MaxCombinedClipAndCull-
102  *     Distances in any shader stage (including compute shader) compiles and
103  *     links successfully and that the value of the built-in constant is at
104  *     least 8.
105  */
106 class APICoverageTest : public CullDistanceTestBase
107 {
108 public:
109     /* Public methods */
110     APICoverageTest(deqp::Context &context);
111 
112 protected:
113     /* Protected methods */
114     void deinit() override;
115 
116     void test(void) override;
117 
118 private:
119     /* Private fields */
120     glw::GLuint m_bo_id;
121     glw::GLuint m_cs_id;
122     glw::GLuint m_cs_to_id;
123     glw::GLuint m_fbo_draw_id;
124     glw::GLuint m_fbo_draw_to_id;
125     glw::GLuint m_fbo_read_id;
126     glw::GLuint m_fs_id;
127     glw::GLuint m_gs_id;
128     glw::GLuint m_po_id;
129     glw::GLuint m_tc_id;
130     glw::GLuint m_te_id;
131     glw::GLuint m_vao_id;
132     glw::GLuint m_vs_id;
133 };
134 
135 /** @brief Cull Distance Functional Test class
136  *
137  *  This class contains functional test cases,
138  *  which check if the implementation works
139  *  in specified way. For each functional test:
140  *    * Use the basic outline to test the basic functionality of cull distances.
141  *    * Use the basic outline but don't redeclare gl_ClipDistance with a size.
142  *    * Use the basic outline but don't redeclare gl_CullDistance with a size.
143  *    * Use the basic outline but don't redeclare either gl_ClipDistance or
144  *      gl_CullDistance with a size.
145  *    * Use the basic outline but use dynamic indexing when writing the elements
146  *      of the gl_ClipDistance and gl_CullDistance arrays.
147  *    * Use the basic outline but add a geometry shader to the program that
148  *      simply passes through all written clip and cull distances.
149  *    * Use the basic outline but add a tessellation control and tessellation
150  *      evaluation shader to the program which simply pass through all written
151  *      clip and cull distances.
152  *    * Test that using #extension with GL_ARB_cull_distance allows using the
153  *      feature even with an earlier version of GLSL. Also test that the
154  *      extension name is available as preprocessor #define.
155  *  a basic outline is used to check the implementation:
156  *    * Enable disjunct cull distances using Enable with CLIP_DISTANCE<i>.
157  *    * Use a program that has only a vertex shader and a fragment shader.
158  *      The vertex shader should redeclare gl_ClipDistance with a size that
159  *      fits all enabled cull distances. Also redeclare gl_CullDistance with a
160  *      size. The sum of the two sizes should not be more than MAX_COMBINED_-
161  *      CLIP_AND_CULL_DISTANCES. The fragment shader should output the cull
162  *      distances written by the vertex shader by reading them from the built-in
163  *      array gl_CullDistance.
164  *    * Write different positive and negative values for all the enabled clip
165  *      distances to gl_ClipDistance in the vertex shader. Also write different
166  *      positive and negative values for all the elements of gl_CullDistance.
167  *      Use constant indices when writing to gl_ClipDistance and gl_CullDistance.
168  *    * Render point, line and triangle primitives. Expect primitives that for
169  *      a given index <i> all of their vertices have a negative value set for
170  *      gl_CullDistance[i] to be discarded. Otherwise, they should be clipped
171  *      according to the enabled clip distances as without this extension.
172  *      Check the output image to make sure that the color output for each
173  *      fragment matches the expected interpolated values of the written cull
174  *      distances.
175  * */
176 class FunctionalTest : public CullDistanceTestBase
177 {
178 public:
179     struct _test_item
180     {
181         int test_id;
182         bool redeclare_clipdistances_array;
183         bool redeclare_culldistances_array;
184         bool dynamic_index_writes;
185         bool use_passthrough_gs;
186         bool use_passthrough_ts;
187         bool use_core_functionality;
188         bool fetch_culldistances;
189     };
190 
191     enum _primitive_mode
192     {
193         PRIMITIVE_MODE_LINES,
194         PRIMITIVE_MODE_POINTS,
195         PRIMITIVE_MODE_TRIANGLES,
196 
197         PRIMITIVE_MODE_COUNT
198     };
199     /* Public methods */
200     FunctionalTest(deqp::Context &context, _test_item test_item, _primitive_mode primitive_mode, glw::GLint iteration);
201 
202 protected:
203     /* Protected methods */
204     void deinit() override;
205 
206     void test(void) override;
207 
208 private:
209     /* Private methods */
210     void buildPO(glw::GLuint clipdistances_array_size, glw::GLuint culldistances_array_size, bool dynamic_index_writes,
211                  _primitive_mode primitive_mode, bool redeclare_clipdistances, bool redeclare_culldistances,
212                  bool use_core_functionality, bool use_gs, bool use_ts, bool fetch_culldistance_from_fs);
213 
214     void configureVAO(glw::GLuint clipdistances_array_size, glw::GLuint culldistances_array_size,
215                       _primitive_mode primitive_mode);
216 
217     void deinitPO();
218 
219     void executeRenderTest(glw::GLuint clipdistances_array_size, glw::GLuint culldistances_array_size,
220                            _primitive_mode primitive_mode, bool use_tesselation, bool fetch_culldistance_from_fs);
221 
222     glw::GLfloat readRedPixelValue(glw::GLint x, glw::GLint y);
223 
224     void readTexturePixels();
225     std::string primitiveModeToString(_primitive_mode mode);
226 
227     /* Private fields */
228     std::vector<glw::GLfloat> m_bo_data;
229     glw::GLuint m_bo_id;
230     glw::GLuint m_fbo_id;
231     glw::GLuint m_po_id;
232     glw::GLsizei m_render_primitives;
233     glw::GLsizei m_render_vertices;
234     glw::GLint m_sub_grid_cell_size;
235     glw::GLuint m_to_id;
236     glw::GLuint m_vao_id;
237 
238     const glw::GLuint m_to_height;
239     const glw::GLuint m_to_width;
240     static const glw::GLuint m_to_pixel_data_cache_color_components = 4;
241     std::vector<glw::GLfloat> m_to_pixel_data_cache;
242 
243     _test_item m_test_item;
244     _primitive_mode m_primitive_mode;
245     glw::GLint m_iteration;
246 };
247 
248 /** @brief Cull Distance Negative Test class
249  *
250  *  This class contains negative test cases,
251  *  which check if the implementation returns
252  *  properly in case of unsupport state
253  *  configuration. Following cases are checked:
254  *    * Use the basic outline but redeclare gl_ClipDistance and gl_CullDistance
255  *      with sizes whose sum is more than MAX_COMBINED_CLIP_AND_CULL_DISTANCES.
256  *      Expect a compile-time or link-time error.
257  *    * Use the basic outline but don't redeclare gl_ClipDistance and/or
258  *      gl_CullDistance with a size and statically write values to such elements
259  *      of gl_ClipDistance and gl_CullDistance that the sum of these element
260  *      indices is greater than MAX_COMBINED_CLIP_AND_CULL_DISTANCES minus two
261  *      (the "minus two" part is needed because the indices are zero-based).
262  *      Expect a compile-time or link-time error.
263  *    * Use the basic outline but don't redeclare gl_ClipDistance and/or
264  *      gl_CullDistance with a size and use dynamic indexing when writing their
265  *      elements. Expect a compile-time or link-time error.
266  */
267 class NegativeTest : public CullDistanceTestBase
268 {
269 public:
270     /* Public methods */
271     NegativeTest(deqp::Context &context);
272 
273 protected:
274     /* Protected methods */
275     void deinit() override;
276 
277     void test(void) override;
278 
279 private:
280     /* Private methods */
281     std::string getTestDescription(glw::GLint n_test_iteration, bool should_redeclare_output_variables,
282                                    bool use_dynamic_index_based_writes);
283 
284     /* Private fields */
285     glw::GLuint m_fs_id;
286     glw::GLuint m_po_id;
287     glw::GLchar *m_temp_buffer;
288     glw::GLuint m_vs_id;
289 };
290 
291 /** @brief Grouping class for Cull Distance Tests */
292 class Tests : public deqp::TestCaseGroup
293 {
294 public:
295     /* Public methods */
296     Tests(deqp::Context &context);
297 
298     void init(void);
299 
300 private:
301     Tests(const CullDistance::Tests &other);
302     Tests &operator=(const CullDistance::Tests &other);
303 
304     void addFunctionalTest();
305 };
306 } // namespace CullDistance
307 /* CullDistance namespace */
308 } // namespace glcts
309 
310 #endif // _GLCCULLDISTANCE_HPP
311