• 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 /*!
25  * \file  esextcTextureBufferPrecision.hpp
26  * \brief Texture Buffer Precision Qualifier (Test 10)
27  */ /*-------------------------------------------------------------------*/
28 
29 #include "esextcTextureBufferPrecision.hpp"
30 #include "gluContextInfo.hpp"
31 #include "gluDefs.hpp"
32 #include "gluShaderUtil.hpp"
33 #include "glwEnums.hpp"
34 #include "glwFunctions.hpp"
35 #include "tcuTestLog.hpp"
36 #include <cstring>
37 #include <stddef.h>
38 
39 namespace glcts
40 {
41 /* Head of the compute shader. */
42 const char* const TextureBufferPrecision::m_cs_code_head = "${VERSION}\n"
43 														   "\n"
44 														   "${TEXTURE_BUFFER_REQUIRE}\n"
45 														   "\n";
46 
47 /* Variables declarations for the compute shader without usage of the precision qualifier. */
48 const char* const TextureBufferPrecision::m_cs_code_declaration_without_precision[3] = {
49 	"layout (r32f)  uniform  imageBuffer image_buffer;\n"
50 	"\n"
51 	"buffer ComputeSSBO\n"
52 	"{\n"
53 	"    float value;\n"
54 	"} computeSSBO;\n",
55 
56 	"layout (r32i)  uniform iimageBuffer image_buffer;\n"
57 	"\n"
58 	"buffer ComputeSSBO\n"
59 	"{\n"
60 	"    int value;\n"
61 	"} computeSSBO;\n",
62 
63 	"layout (r32ui) uniform uimageBuffer image_buffer;\n"
64 	"\n"
65 	"buffer ComputeSSBO\n"
66 	"{\n"
67 	"    uint value;\n"
68 	"} computeSSBO;\n"
69 };
70 
71 /* Variables declarations for the compute shader with usage of the precision qualifier. */
72 const char* const TextureBufferPrecision::m_cs_code_declaration_with_precision[3] = {
73 	"layout (r32f)  uniform highp  imageBuffer image_buffer;\n"
74 	"\n"
75 	"buffer ComputeSSBO\n"
76 	"{\n"
77 	"    float value;\n"
78 	"} computeSSBO;\n",
79 
80 	"layout (r32i)  uniform highp iimageBuffer image_buffer;\n"
81 	"\n"
82 	"buffer ComputeSSBO\n"
83 	"{\n"
84 	"    int value;\n"
85 	"} computeSSBO;\n",
86 
87 	"layout (r32ui) uniform highp uimageBuffer image_buffer;\n"
88 	"\n"
89 	"buffer ComputeSSBO\n"
90 	"{\n"
91 	"    uint value;\n"
92 	"} computeSSBO;\n"
93 };
94 
95 /* The default precision qualifier declarations for the compute shader. */
96 const char* const TextureBufferPrecision::m_cs_code_global_precision[3] = { "precision highp  imageBuffer;\n",
97 																			"precision highp iimageBuffer;\n",
98 																			"precision highp uimageBuffer;\n" };
99 
100 /* The compute shader body. */
101 const char* const TextureBufferPrecision::m_cs_code_body = "\n"
102 														   "void main()\n"
103 														   "{\n"
104 														   "    computeSSBO.value = imageLoad(image_buffer, 0).x;\n"
105 														   "}";
106 
107 /* Head of the fragment shader. */
108 const char* const TextureBufferPrecision::m_fs_code_head = "${VERSION}\n"
109 														   "\n"
110 														   "${TEXTURE_BUFFER_REQUIRE}\n"
111 														   "\n";
112 
113 /* Variables declarations for the fragment shader without usage of the precision qualifier. */
114 const char* const TextureBufferPrecision::m_fs_code_declaration_without_precision[3] = {
115 	"uniform  samplerBuffer sampler_buffer;\n"
116 	"\n"
117 	"layout(location = 0) out highp vec4 color;\n",
118 
119 	"uniform isamplerBuffer sampler_buffer;\n"
120 	"\n"
121 	"layout(location = 0) out highp ivec4 color;\n",
122 
123 	"uniform usamplerBuffer sampler_buffer;\n"
124 	"\n"
125 	"layout(location = 0) out highp uvec4 color;\n"
126 };
127 
128 /* Variables declarations for the fragment shader with usage of the precision qualifier. */
129 const char* const TextureBufferPrecision::m_fs_code_declaration_with_precision[3] = {
130 	"uniform highp  samplerBuffer sampler_buffer;\n"
131 	"\n"
132 	"layout(location = 0) out highp vec4 color;\n",
133 
134 	"uniform highp isamplerBuffer sampler_buffer;\n"
135 	"\n"
136 	"layout(location = 0) out highp ivec4 color;\n",
137 
138 	"uniform highp usamplerBuffer sampler_buffer;\n"
139 	"\n"
140 	"layout(location = 0) out highp uvec4 color;\n",
141 };
142 
143 /* The default precision qualifier declarations for the fragment shader. */
144 const char* const TextureBufferPrecision::m_fs_code_global_precision[3] = {
145 	"precision highp  samplerBuffer;\n", "precision highp isamplerBuffer;\n", "precision highp usamplerBuffer;\n",
146 };
147 
148 /* The fragment shader body. */
149 const char* const TextureBufferPrecision::m_fs_code_body = "\n"
150 														   "void main()\n"
151 														   "{\n"
152 														   "    color = texelFetch( sampler_buffer, 0 );\n"
153 														   "}";
154 
155 /** Constructor
156  *
157  * @param context     Test context
158  * @param name        Test case's name
159  * @param description Test case's description
160  **/
TextureBufferPrecision(Context & context,const ExtParameters & extParams,const char * name,const char * description)161 TextureBufferPrecision::TextureBufferPrecision(Context& context, const ExtParameters& extParams, const char* name,
162 											   const char* description)
163 	: TestCaseBase(context, extParams, name, description), m_po_id(0), m_sh_id(0)
164 {
165 	//Bug-15063 Only GLSL 4.50 supports opaque types
166 	if (m_glslVersion >= glu::GLSL_VERSION_130)
167 	{
168 		m_glslVersion = glu::GLSL_VERSION_450;
169 	}
170 }
171 
172 /** Deinitializes GLES objects created during the test */
deinit(void)173 void TextureBufferPrecision::deinit(void)
174 {
175 	/* Retrieve GLES entry points. */
176 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
177 
178 	/* Delete GLES objects */
179 	if (m_po_id != 0)
180 	{
181 		gl.deleteProgram(m_po_id);
182 		m_po_id = 0;
183 	}
184 
185 	if (m_sh_id != 0)
186 	{
187 		gl.deleteShader(m_sh_id);
188 		m_sh_id = 0;
189 	}
190 
191 	/* Deinitialize base class */
192 	TestCaseBase::deinit();
193 }
194 
195 /** Check if the shader compiles.
196  *
197  *  Note the function throws exception should an error occur!
198  *
199  *  @param shader_type      GL shader type.
200  *  @param sh_code_parts    Shader source parts
201  *  @param parts_count      Shader source parts count
202  *
203  *  @return true if the shader compiles, return false otherwise.
204  **/
verifyShaderCompilationStatus(glw::GLenum shader_type,const char ** sh_code_parts,const glw::GLuint parts_count,const glw::GLint expected_status)205 glw::GLboolean TextureBufferPrecision::verifyShaderCompilationStatus(glw::GLenum	   shader_type,
206 																	 const char**	  sh_code_parts,
207 																	 const glw::GLuint parts_count,
208 																	 const glw::GLint  expected_status)
209 {
210 	/* Retrieve GLES entry points. */
211 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
212 
213 	glw::GLboolean test_passed = true;
214 
215 	m_po_id = gl.createProgram();
216 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create program object");
217 
218 	m_sh_id = gl.createShader(shader_type);
219 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object");
220 
221 	std::string shader_code		= specializeShader(parts_count, sh_code_parts);
222 	const char* shader_code_ptr = shader_code.c_str();
223 	gl.shaderSource(m_sh_id, 1, &shader_code_ptr, DE_NULL);
224 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set shader source");
225 
226 	gl.compileShader(m_sh_id);
227 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to perform compilation of shader object");
228 
229 	/* Retrieving compilation status */
230 	glw::GLint compilation_status = GL_FALSE;
231 	gl.getShaderiv(m_sh_id, GL_COMPILE_STATUS, &compilation_status);
232 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not retrieve shader compilation status");
233 
234 	if (compilation_status != expected_status)
235 	{
236 		test_passed = false;
237 
238 		glw::GLsizei info_log_length = 0;
239 		gl.getShaderiv(m_sh_id, GL_INFO_LOG_LENGTH, &info_log_length);
240 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not get shader info log length");
241 
242 		if (info_log_length > 0)
243 		{
244 			glw::GLchar* info_log = new glw::GLchar[info_log_length];
245 			memset(info_log, 0, info_log_length * sizeof(glw::GLchar));
246 			gl.getShaderInfoLog(m_sh_id, info_log_length, DE_NULL, info_log);
247 
248 			m_testCtx.getLog() << tcu::TestLog::Message << "The following shader:\n\n"
249 							   << shader_code << "\n\n did compile with result different than expected:\n"
250 							   << expected_status << "\n\n Compilation info log: \n"
251 							   << info_log << "\n"
252 							   << tcu::TestLog::EndMessage;
253 
254 			delete[] info_log;
255 
256 			GLU_EXPECT_NO_ERROR(gl.getError(), "Could not get shader info log");
257 		}
258 	}
259 
260 	/* Clean up */
261 	if (m_po_id != 0)
262 	{
263 		gl.deleteProgram(m_po_id);
264 		m_po_id = 0;
265 	}
266 
267 	if (m_sh_id != 0)
268 	{
269 		gl.deleteShader(m_sh_id);
270 		m_sh_id = 0;
271 	}
272 
273 	return test_passed;
274 }
275 
276 /** Executes the test.
277  *
278  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
279  *
280  *  Note the function throws exception should an error occur!
281  *
282  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
283  **/
iterate(void)284 tcu::TestNode::IterateResult TextureBufferPrecision::iterate(void)
285 {
286 	/* Skip if required extensions are not supported. */
287 	if (!m_is_texture_buffer_supported)
288 	{
289 		throw tcu::NotSupportedError(TEXTURE_BUFFER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
290 	}
291 
292 	glu::ContextType contextType   = m_context.getRenderContext().getType();
293 	glw::GLboolean   test_passed   = true;
294 	glw::GLint		 expected_fail = glu::glslVersionIsES(m_glslVersion) ? GL_FALSE : GL_TRUE;
295 
296 	/* Default precision qualifiers for opaque types are not supported prior to GLSL 4.50. */
297 	if (glu::contextSupports(contextType, glu::ApiType::core(4, 5)) ||
298 		glu::contextSupports(contextType, glu::ApiType::es(3, 1)))
299 	{
300 		/* Compute Shader Tests */
301 		for (glw::GLuint i = 0; i < 3; ++i) /* For each from the set {imageBuffer, iimageBuffer, uimageBuffer} */
302 		{
303 			const char* cs_code_without_precision[3] = { m_cs_code_head, m_cs_code_declaration_without_precision[i],
304 														 m_cs_code_body };
305 
306 			const char* cs_code_with_precision[3] = { m_cs_code_head, m_cs_code_declaration_with_precision[i],
307 													  m_cs_code_body };
308 
309 			const char* cs_code_with_global_precision[4] = { m_cs_code_head, m_cs_code_global_precision[i],
310 															 m_cs_code_declaration_without_precision[i],
311 															 m_cs_code_body };
312 
313 			test_passed =
314 				verifyShaderCompilationStatus(GL_COMPUTE_SHADER, cs_code_without_precision, 3, expected_fail) &&
315 				test_passed;
316 			test_passed =
317 				verifyShaderCompilationStatus(GL_COMPUTE_SHADER, cs_code_with_precision, 3, GL_TRUE) && test_passed;
318 			test_passed = verifyShaderCompilationStatus(GL_COMPUTE_SHADER, cs_code_with_global_precision, 4, GL_TRUE) &&
319 						  test_passed;
320 		}
321 	}
322 
323 	/* Fragment Shader Tests */
324 	for (glw::GLuint i = 0; i < 3; ++i) /* For each from the set {samplerBuffer, isamplerBuffer, usamplerBuffer} */
325 	{
326 		const char* fs_code_without_precision[3] = { m_fs_code_head, m_fs_code_declaration_without_precision[i],
327 													 m_fs_code_body };
328 
329 		const char* fs_code_with_precision[3] = { m_fs_code_head, m_fs_code_declaration_with_precision[i],
330 												  m_fs_code_body };
331 
332 		const char* fs_code_with_global_precision[4] = { m_fs_code_head, m_fs_code_global_precision[i],
333 														 m_fs_code_declaration_without_precision[i], m_fs_code_body };
334 
335 		test_passed = verifyShaderCompilationStatus(GL_FRAGMENT_SHADER, fs_code_without_precision, 3, expected_fail) &&
336 					  test_passed;
337 		test_passed =
338 			verifyShaderCompilationStatus(GL_FRAGMENT_SHADER, fs_code_with_precision, 3, GL_TRUE) && test_passed;
339 		test_passed =
340 			verifyShaderCompilationStatus(GL_FRAGMENT_SHADER, fs_code_with_global_precision, 4, GL_TRUE) && test_passed;
341 	}
342 
343 	if (test_passed)
344 	{
345 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
346 	}
347 	else
348 	{
349 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
350 	}
351 
352 	return STOP;
353 }
354 
355 } /* namespace glcts */
356