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