• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2014-2016 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */ /*!
20  * \file
21  * \brief
22  */ /*-------------------------------------------------------------------*/
23 
24 #include "esextcGeometryShaderClipping.hpp"
25 
26 #include "gluDefs.hpp"
27 #include "glwEnums.hpp"
28 #include "glwFunctions.hpp"
29 #include "tcuTestLog.hpp"
30 #include <cstring>
31 
32 namespace glcts
33 {
34 /* Fragment shader code */
35 const char* GeometryShaderClipping::m_fs_code = "${VERSION}\n"
36 												"\n"
37 												"precision highp float;\n"
38 												"\n"
39 												"out vec4 result;\n"
40 												"\n"
41 												"void main()\n"
42 												"{\n"
43 												"    result = vec4(0, 1, 0, 0);\n"
44 												"}\n";
45 
46 /* Vertex shader code */
47 const char* GeometryShaderClipping::m_vs_code = "${VERSION}\n"
48 												"\n"
49 												"precision highp float;\n"
50 												"\n"
51 												"void main()\n"
52 												"{\n"
53 												"    gl_Position = vec4(-10, -10, -10, 0);\n"
54 												"}\n";
55 
56 /* Geometry shader code */
57 const char* GeometryShaderClipping::m_gs_code = "${VERSION}\n"
58 												"${GEOMETRY_SHADER_REQUIRE}\n"
59 												"\n"
60 												"precision highp float;\n"
61 												"\n"
62 												"layout(points)                                    in;\n"
63 												"layout(triangle_strip, max_vertices=4) out;\n"
64 												"\n"
65 												"void main()\n"
66 												"{\n"
67 												"\n"
68 												"    gl_Position = vec4(1, 1, 0, 1);\n"
69 												"    EmitVertex();\n"
70 												"\n"
71 												"    gl_Position = vec4(1, -1, 0, 1);\n"
72 												"    EmitVertex();\n"
73 												"\n"
74 												"    gl_Position = vec4(-1, 1, 0, 1);\n"
75 												"    EmitVertex();\n"
76 												"\n"
77 												"    gl_Position = vec4(-1, -1, 0, 1);\n"
78 												"    EmitVertex();\n"
79 												"\n"
80 												"    EndPrimitive();\n"
81 												"}\n";
82 
83 /** Constructor
84  *
85  * @param context       Test context
86  * @param name          Test case's name
87  * @param description   Test case's desricption
88  **/
GeometryShaderClipping(Context & context,const ExtParameters & extParams,const char * name,const char * description)89 GeometryShaderClipping::GeometryShaderClipping(Context& context, const ExtParameters& extParams, const char* name,
90 											   const char* description)
91 	: TestCaseBase(context, extParams, name, description)
92 	, m_fbo_id(0)
93 	, m_fs_id(0)
94 	, m_gs_id(0)
95 	, m_po_id(0)
96 	, m_to_id(0)
97 	, m_vao_id(0)
98 	, m_vs_id(0)
99 {
100 }
101 
102 /** Deinitializes GLES objects created during the test.
103  *
104  */
deinit(void)105 void GeometryShaderClipping::deinit(void)
106 {
107 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
108 
109 	/* Reset OpenGL ES state */
110 	gl.useProgram(0);
111 	gl.bindTexture(GL_TEXTURE_2D, 0);
112 	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
113 	gl.bindVertexArray(0);
114 
115 	if (m_po_id != 0)
116 	{
117 		gl.deleteProgram(m_po_id);
118 	}
119 
120 	if (m_fs_id != 0)
121 	{
122 		gl.deleteShader(m_fs_id);
123 	}
124 
125 	if (m_gs_id != 0)
126 	{
127 		gl.deleteShader(m_gs_id);
128 	}
129 
130 	if (m_vs_id != 0)
131 	{
132 		gl.deleteShader(m_vs_id);
133 	}
134 
135 	if (m_to_id != 0)
136 	{
137 		gl.deleteTextures(1, &m_to_id);
138 	}
139 
140 	if (m_fbo_id != 0)
141 	{
142 		gl.deleteFramebuffers(1, &m_fbo_id);
143 	}
144 
145 	if (m_vao_id != 0)
146 	{
147 		gl.deleteVertexArrays(1, &m_vao_id);
148 	}
149 
150 	/* Release base class */
151 	TestCaseBase::deinit();
152 }
153 
154 /** Executes the test.
155  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
156  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
157  *  Note the function throws exception should an error occur!
158  **/
iterate(void)159 tcu::TestNode::IterateResult GeometryShaderClipping::iterate(void)
160 {
161 	unsigned char buffer[m_texture_width * m_texture_height * m_texture_n_components];
162 
163 	const glw::Functions& gl				= m_context.getRenderContext().getFunctions();
164 	const unsigned char   reference_color[] = { 0, 255, 0, 0 };
165 	const unsigned int	row_size			= m_texture_width * m_texture_n_components;
166 
167 	if (!m_is_geometry_shader_extension_supported)
168 	{
169 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
170 	}
171 
172 	/* Create shader objects we'll need */
173 	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
174 	m_gs_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
175 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
176 	m_po_id = gl.createProgram();
177 
178 	if (!buildProgram(m_po_id, m_fs_id, 1 /* part */, &m_fs_code, m_gs_id, 1 /* part */, &m_gs_code, m_vs_id,
179 					  1 /* part */, &m_vs_code))
180 	{
181 		TCU_FAIL("Could not create program object from valid vertex/geometry/fragment shaders!");
182 	}
183 
184 	/* Create and configure texture object we'll be rendering to */
185 	gl.genTextures(1, &m_to_id);
186 	gl.bindTexture(GL_TEXTURE_2D, m_to_id);
187 	gl.texStorage2D(GL_TEXTURE_2D, m_texture_n_levels, GL_RGBA8, m_texture_width, m_texture_height);
188 
189 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating texture object!");
190 
191 	/* Create and configure the framebuffer object */
192 	gl.genFramebuffers(1, &m_fbo_id);
193 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo_id);
194 	gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_to_id, 0 /* level */);
195 
196 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error configuring framebuffer object!");
197 
198 	/* Create and bind vertex array object */
199 	gl.genVertexArrays(1, &m_vao_id);
200 	gl.bindVertexArray(m_vao_id);
201 
202 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error configuring vertex array object");
203 
204 	/* Render */
205 	gl.viewport(0 /* x */, 0 /* y */, m_texture_width /* width */, m_texture_height /* height */);
206 	gl.useProgram(m_po_id);
207 
208 	gl.clearColor(1.0f, 0.0f, 0.0f, 0.0f);
209 	gl.clear(GL_COLOR_BUFFER_BIT);
210 
211 	gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
212 
213 	GLU_EXPECT_NO_ERROR(gl.getError(), "Rendering failed!");
214 
215 	/* Read the rendered data */
216 	gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_id);
217 	gl.readPixels(0 /* x */, 0 /* y */, m_texture_height /* width */, m_texture_width /* height */, GL_RGBA,
218 				  GL_UNSIGNED_BYTE, buffer);
219 
220 	GLU_EXPECT_NO_ERROR(gl.getError(), "Reading pixels failed!");
221 
222 	/* Loop over all pixels and compare the rendered data with reference value */
223 	for (int y = 0; y < m_texture_height; ++y)
224 	{
225 		unsigned char* data_row = buffer + y * row_size;
226 
227 		for (int x = 0; x < m_texture_width; ++x)
228 		{
229 			unsigned char* data = data_row + x * m_texture_n_components;
230 
231 			if (memcmp(data, reference_color, sizeof(reference_color)) != 0)
232 			{
233 				m_testCtx.getLog() << tcu::TestLog::Message << "Rendered data [" << data[0] << ", " << data[1] << ", "
234 								   << data[2] << ", " << data[3] << "] is different from reference data ["
235 								   << reference_color[0] << ", " << reference_color[1] << ", " << reference_color[2]
236 								   << ", " << reference_color[3] << "] !" << tcu::TestLog::EndMessage;
237 
238 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
239 
240 				return STOP;
241 			} /* if (memcmp(data, reference_color, sizeof(reference_color)) != 0) */
242 		}	 /* for (all columns) */
243 	}		  /* for (all rows) */
244 
245 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
246 	return STOP;
247 }
248 
249 } // namespace glcts
250