Home | History | Annotate | Download | only in gl
      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>
    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>
    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>
    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>
    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>
    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