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