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 } /* Utility namespace */ 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 } /* ClipDistance namespace */ 317 } /* gl3cts namespace */ 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), m_vertex_buffer_object_id(0), m_target(target), m_size(0) 333 { 334 m_gl.genBuffers(1, &m_vertex_buffer_object_id); 335 GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGenBuffers call failed."); 336 337 if (m_vertex_buffer_object_id) 338 { 339 m_size = (glw::GLsizei)(sizeof(T) * data.size()); 340 341 bind(); 342 343 m_gl.bufferData(m_target, m_size, &data[0], GL_STATIC_DRAW); 344 GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBufferData call failed."); 345 } 346 } 347 348 /** @brief Vertex Buffer Object destructor. */ 349 template <class T> ~VertexBufferObject()350 gl3cts::ClipDistance::Utility::VertexBufferObject<T>::~VertexBufferObject() 351 { 352 m_gl.deleteBuffers(1, &m_vertex_buffer_object_id); /* Delete silently unbinds the buffer. */ 353 GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDeleteBuffers call failed."); 354 355 for (std::vector<glw::GLint>::iterator i_enabled_array = m_enabled_arrays.begin(); 356 i_enabled_array != m_enabled_arrays.end(); ++i_enabled_array) 357 { 358 m_gl.disableVertexAttribArray(*i_enabled_array); 359 } 360 } 361 362 /** @brief Bind Vertex Buffer Object to its target. 363 * 364 * @note It binds also to indexed binding point for GL_TRANSFORM_FEEDBACK_BUFFER target. 365 */ 366 template <class T> bind()367 bool gl3cts::ClipDistance::Utility::VertexBufferObject<T>::bind() 368 { 369 if (m_vertex_buffer_object_id) 370 { 371 m_gl.bindBuffer(m_target, m_vertex_buffer_object_id); 372 GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBuffer call failed."); 373 374 if (m_target == GL_TRANSFORM_FEEDBACK_BUFFER) 375 { 376 m_gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_vertex_buffer_object_id); 377 GLU_EXPECT_NO_ERROR(m_gl.getError(), "glBindBufferBase call failed."); 378 } 379 380 return true; 381 } 382 383 return false; 384 } 385 386 /** @brief Use VBO as attribute vertex array. 387 * 388 * @note It silently binds VBO. 389 * 390 * @param [in] program GLSL Program to which VBO shall be bound. 391 * @param [in] input_attribute_name Name of GLSL asttribute. 392 * @param [in] number_of_components Number of attribute's components. 393 * 394 * @return True on success, false otherwise. 395 */ 396 template <class T> useAsShaderInput(Program program,std::string input_attribute_name,glw::GLint number_of_components)397 bool gl3cts::ClipDistance::Utility::VertexBufferObject<T>::useAsShaderInput(Program program, 398 std::string input_attribute_name, 399 glw::GLint number_of_components) 400 { 401 if (program.ProgramStatus().program_id) 402 { 403 glw::GLint location = m_gl.getAttribLocation(program.ProgramStatus().program_id, input_attribute_name.c_str()); 404 GLU_EXPECT_NO_ERROR(m_gl.getError(), "glGetAttribLocation call failed."); 405 406 if (location >= 0) 407 { 408 const std::type_info& buffer_type = typeid(T); 409 const std::type_info& float_type = typeid(glw::GLfloat); 410 const std::type_info& int_type = typeid(glw::GLint); 411 412 m_gl.enableVertexAttribArray(location); 413 GLU_EXPECT_NO_ERROR(m_gl.getError(), "glEnableVertexAttribArray call failed."); 414 m_enabled_arrays.push_back(location); 415 416 bind(); 417 418 if (buffer_type == float_type) 419 { 420 m_gl.vertexAttribPointer(location, number_of_components, GL_FLOAT, false, 0, NULL); 421 GLU_EXPECT_NO_ERROR(m_gl.getError(), "glVertexAttribPointer call failed."); 422 } 423 else if (buffer_type == int_type) 424 { 425 m_gl.vertexAttribIPointer(location, number_of_components, GL_FLOAT, 0, NULL); 426 GLU_EXPECT_NO_ERROR(m_gl.getError(), "glVertexAttribIPointer call failed."); 427 } 428 else 429 { 430 return false; 431 } 432 433 return true; 434 } 435 } 436 437 return false; 438 } 439 440 /** @brief Read VBO content (potentially set by transform feedback). 441 * 442 * @return Content of VBO. 443 */ 444 template <class T> readBuffer()445 std::vector<T> gl3cts::ClipDistance::Utility::VertexBufferObject<T>::readBuffer() 446 { 447 std::vector<T> buffer_data(m_size / sizeof(T)); 448 449 bind(); 450 451 glw::GLvoid* results = m_gl.mapBuffer(m_target, GL_READ_ONLY); 452 453 if (results) 454 { 455 memcpy(&buffer_data[0], results, m_size); 456 } 457 458 m_gl.unmapBuffer(m_target); 459 460 return buffer_data; 461 } 462 #endif // _GL3CCLIPDISTANCE_HPP 463