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 /* Variables declarations for the compute shader with usage of the precision qualifier. */
71 const char *const TextureBufferPrecision::m_cs_code_declaration_with_precision[3] = {
72 "layout (r32f) uniform highp imageBuffer image_buffer;\n"
73 "\n"
74 "buffer ComputeSSBO\n"
75 "{\n"
76 " float value;\n"
77 "} computeSSBO;\n",
78
79 "layout (r32i) uniform highp iimageBuffer image_buffer;\n"
80 "\n"
81 "buffer ComputeSSBO\n"
82 "{\n"
83 " int value;\n"
84 "} computeSSBO;\n",
85
86 "layout (r32ui) uniform highp uimageBuffer image_buffer;\n"
87 "\n"
88 "buffer ComputeSSBO\n"
89 "{\n"
90 " uint value;\n"
91 "} computeSSBO;\n"};
92
93 /* The default precision qualifier declarations for the compute shader. */
94 const char *const TextureBufferPrecision::m_cs_code_global_precision[3] = {
95 "precision highp imageBuffer;\n", "precision highp iimageBuffer;\n", "precision highp uimageBuffer;\n"};
96
97 /* The compute shader body. */
98 const char *const TextureBufferPrecision::m_cs_code_body = "\n"
99 "void main()\n"
100 "{\n"
101 " computeSSBO.value = imageLoad(image_buffer, 0).x;\n"
102 "}";
103
104 /* Head of the fragment shader. */
105 const char *const TextureBufferPrecision::m_fs_code_head = "${VERSION}\n"
106 "\n"
107 "${TEXTURE_BUFFER_REQUIRE}\n"
108 "\n";
109
110 /* Variables declarations for the fragment shader without usage of the precision qualifier. */
111 const char *const TextureBufferPrecision::m_fs_code_declaration_without_precision[3] = {
112 "uniform samplerBuffer sampler_buffer;\n"
113 "\n"
114 "layout(location = 0) out highp vec4 color;\n",
115
116 "uniform isamplerBuffer sampler_buffer;\n"
117 "\n"
118 "layout(location = 0) out highp ivec4 color;\n",
119
120 "uniform usamplerBuffer sampler_buffer;\n"
121 "\n"
122 "layout(location = 0) out highp uvec4 color;\n"};
123
124 /* Variables declarations for the fragment shader with usage of the precision qualifier. */
125 const char *const TextureBufferPrecision::m_fs_code_declaration_with_precision[3] = {
126 "uniform highp samplerBuffer sampler_buffer;\n"
127 "\n"
128 "layout(location = 0) out highp vec4 color;\n",
129
130 "uniform highp isamplerBuffer sampler_buffer;\n"
131 "\n"
132 "layout(location = 0) out highp ivec4 color;\n",
133
134 "uniform highp usamplerBuffer sampler_buffer;\n"
135 "\n"
136 "layout(location = 0) out highp uvec4 color;\n",
137 };
138
139 /* The default precision qualifier declarations for the fragment shader. */
140 const char *const TextureBufferPrecision::m_fs_code_global_precision[3] = {
141 "precision highp samplerBuffer;\n",
142 "precision highp isamplerBuffer;\n",
143 "precision highp usamplerBuffer;\n",
144 };
145
146 /* The fragment shader body. */
147 const char *const TextureBufferPrecision::m_fs_code_body = "\n"
148 "void main()\n"
149 "{\n"
150 " color = texelFetch( sampler_buffer, 0 );\n"
151 "}";
152
153 /** Constructor
154 *
155 * @param context Test context
156 * @param name Test case's name
157 * @param description Test case's description
158 **/
TextureBufferPrecision(Context & context,const ExtParameters & extParams,const char * name,const char * description)159 TextureBufferPrecision::TextureBufferPrecision(Context &context, const ExtParameters &extParams, const char *name,
160 const char *description)
161 : TestCaseBase(context, extParams, name, description)
162 , m_po_id(0)
163 , 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], m_cs_code_body};
311
312 test_passed =
313 verifyShaderCompilationStatus(GL_COMPUTE_SHADER, cs_code_without_precision, 3, expected_fail) &&
314 test_passed;
315 test_passed =
316 verifyShaderCompilationStatus(GL_COMPUTE_SHADER, cs_code_with_precision, 3, GL_TRUE) && test_passed;
317 test_passed = verifyShaderCompilationStatus(GL_COMPUTE_SHADER, cs_code_with_global_precision, 4, GL_TRUE) &&
318 test_passed;
319 }
320 }
321
322 /* Fragment Shader Tests */
323 for (glw::GLuint i = 0; i < 3; ++i) /* For each from the set {samplerBuffer, isamplerBuffer, usamplerBuffer} */
324 {
325 const char *fs_code_without_precision[3] = {m_fs_code_head, m_fs_code_declaration_without_precision[i],
326 m_fs_code_body};
327
328 const char *fs_code_with_precision[3] = {m_fs_code_head, m_fs_code_declaration_with_precision[i],
329 m_fs_code_body};
330
331 const char *fs_code_with_global_precision[4] = {m_fs_code_head, m_fs_code_global_precision[i],
332 m_fs_code_declaration_without_precision[i], m_fs_code_body};
333
334 test_passed = verifyShaderCompilationStatus(GL_FRAGMENT_SHADER, fs_code_without_precision, 3, expected_fail) &&
335 test_passed;
336 test_passed =
337 verifyShaderCompilationStatus(GL_FRAGMENT_SHADER, fs_code_with_precision, 3, GL_TRUE) && test_passed;
338 test_passed =
339 verifyShaderCompilationStatus(GL_FRAGMENT_SHADER, fs_code_with_global_precision, 4, GL_TRUE) && test_passed;
340 }
341
342 if (test_passed)
343 {
344 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
345 }
346 else
347 {
348 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
349 }
350
351 return STOP;
352 }
353
354 } /* namespace glcts */
355