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