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 "esextcTestCaseBase.hpp"
25 #include "gluContextInfo.hpp"
26 #include "glwEnums.hpp"
27 #include "glwFunctions.hpp"
28 #include "tcuStringTemplate.hpp"
29 #include "tcuTestLog.hpp"
30 #include <algorithm>
31 #include <cstdarg>
32 #include <iostream>
33
34 namespace glcts
35 {
36
37 /* Predefined shader source code */
38 const char* TestCaseBase::m_boilerplate_vs_code = "${VERSION}\n"
39 "\n"
40 "precision highp float;\n"
41 "\n"
42 "void main()\n"
43 "{\n"
44 " gl_Position = vec4(gl_VertexID, 0, 0, 1);\n"
45 "}\n";
46
47 const float TestCaseBase::m_epsilon_float = 0.0001f;
48
49 /** Constructor
50 *
51 * @param context Test context
52 * @param name Test case's name
53 * @param description Test case's description
54 **/
TestCaseBase(Context & context,const ExtParameters & extParam,const char * name,const char * description)55 TestCaseBase::TestCaseBase(Context& context, const ExtParameters& extParam, const char* name, const char* description)
56 : tcu::TestCase(context.getTestContext(), name, description)
57 , m_context(context)
58 , m_glslVersion(extParam.glslVersion)
59 , m_extType(extParam.extType)
60 , m_is_framebuffer_no_attachments_supported(false)
61 , m_is_geometry_shader_extension_supported(false)
62 , m_is_geometry_shader_point_size_supported(false)
63 , m_is_gpu_shader5_supported(false)
64 , m_is_program_interface_query_supported(false)
65 , m_is_shader_image_load_store_supported(false)
66 , m_is_shader_image_atomic_supported(false)
67 , m_is_texture_storage_multisample_supported(false)
68 , m_is_texture_storage_multisample_2d_array_supported(false)
69 , m_is_tessellation_shader_supported(false)
70 , m_is_tessellation_shader_point_size_supported(false)
71 , m_is_texture_cube_map_array_supported(false)
72 , m_is_texture_border_clamp_supported(false)
73 , m_is_texture_buffer_supported(false)
74 , m_is_viewport_array_supported(false)
75 , seed_value(1)
76 {
77 m_glExtTokens.init(context.getRenderContext().getType());
78 }
79
80 /** Initializes base class that all geometry shader test implementations derive from.
81 *
82 **/
init(void)83 void TestCaseBase::init(void)
84 {
85 initExtensions();
86 initGLSLSpecializationMap();
87 }
88
89 /** Initializes function pointers for ES3.1 extensions, as well as determines
90 * availability of these extensions.
91 **/
initExtensions()92 void TestCaseBase::initExtensions()
93 {
94 const glu::ContextType& context_type = m_context.getRenderContext().getType();
95
96 /* OpenGL 4.0 or higher is minimum expectation for any of these tests */
97 if (glu::contextSupports(context_type, glu::ApiType::core(4, 0)))
98 {
99 m_is_geometry_shader_extension_supported = true;
100 m_is_geometry_shader_point_size_supported = true;
101 m_is_gpu_shader5_supported = true;
102 m_is_tessellation_shader_supported = true;
103 m_is_tessellation_shader_point_size_supported = true;
104 m_is_texture_cube_map_array_supported = true;
105 m_is_texture_border_clamp_supported = true;
106 m_is_texture_buffer_supported = true;
107 m_is_shader_image_atomic_supported = glu::contextSupports(context_type, glu::ApiType::core(4, 2));
108 m_is_texture_storage_multisample_2d_array_supported =
109 glu::contextSupports(context_type, glu::ApiType::core(4, 3));
110 m_is_framebuffer_no_attachments_supported = glu::contextSupports(context_type, glu::ApiType::core(4, 3));
111 m_is_program_interface_query_supported = glu::contextSupports(context_type, glu::ApiType::core(4, 3));
112 m_is_texture_storage_multisample_supported = glu::contextSupports(context_type, glu::ApiType::core(4, 3));
113 m_is_shader_image_load_store_supported = glu::contextSupports(context_type, glu::ApiType::core(4, 2));
114 m_is_viewport_array_supported = glu::contextSupports(context_type, glu::ApiType::core(4, 1));
115 }
116 else if (glu::contextSupports(context_type, glu::ApiType::es(3, 2)))
117 {
118 m_is_geometry_shader_extension_supported = true;
119 m_is_gpu_shader5_supported = true;
120 m_is_tessellation_shader_supported = true;
121 m_is_texture_cube_map_array_supported = true;
122 m_is_texture_border_clamp_supported = true;
123 m_is_texture_buffer_supported = true;
124 m_is_shader_image_atomic_supported = true;
125 m_is_texture_storage_multisample_2d_array_supported = true;
126 m_is_framebuffer_no_attachments_supported = true;
127 m_is_program_interface_query_supported = true;
128 m_is_texture_storage_multisample_supported = true;
129 m_is_shader_image_load_store_supported = true;
130 m_is_geometry_shader_point_size_supported =
131 isExtensionSupported("GL_OES_geometry_point_size") || isExtensionSupported("GL_EXT_geometry_point_size");
132 m_is_tessellation_shader_point_size_supported = isExtensionSupported("GL_OES_tessellation_point_size") ||
133 isExtensionSupported("GL_EXT_tessellation_point_size");
134 m_is_viewport_array_supported = isExtensionSupported("GL_OES_viewport_array");
135 }
136 else
137 {
138 /* ES3.1 core functionality is assumed*/
139 DE_ASSERT(isContextTypeES(context_type));
140 DE_ASSERT(glu::contextSupports(context_type, glu::ApiType::es(3, 1)));
141
142 /* these are part of ES 3.1 */
143 m_is_framebuffer_no_attachments_supported = true;
144 m_is_program_interface_query_supported = true;
145 m_is_texture_storage_multisample_supported = true;
146 m_is_shader_image_load_store_supported = true;
147
148 /* AEP extensions - either test OES variants or EXT variants */
149 if (m_extType == EXTENSIONTYPE_OES)
150 {
151 /* These are all ES 3.1 extensions */
152 m_is_geometry_shader_extension_supported = isExtensionSupported("GL_OES_geometry_shader");
153 m_is_geometry_shader_point_size_supported = isExtensionSupported("GL_OES_geometry_point_size");
154 m_is_gpu_shader5_supported = isExtensionSupported("GL_OES_gpu_shader5");
155 m_is_tessellation_shader_supported = isExtensionSupported("GL_OES_tessellation_shader");
156 m_is_tessellation_shader_point_size_supported = isExtensionSupported("GL_OES_tessellation_point_size");
157 m_is_texture_cube_map_array_supported = isExtensionSupported("GL_OES_texture_cube_map_array");
158 m_is_texture_border_clamp_supported = isExtensionSupported("GL_OES_texture_border_clamp");
159 m_is_texture_buffer_supported = isExtensionSupported("GL_OES_texture_buffer");
160 }
161 else
162 {
163 DE_ASSERT(m_extType == EXTENSIONTYPE_EXT);
164
165 /* These are all ES 3.1 extensions */
166 m_is_geometry_shader_extension_supported = isExtensionSupported("GL_EXT_geometry_shader");
167 m_is_geometry_shader_point_size_supported = isExtensionSupported("GL_EXT_geometry_point_size");
168 m_is_gpu_shader5_supported = isExtensionSupported("GL_EXT_gpu_shader5");
169 m_is_tessellation_shader_supported = isExtensionSupported("GL_EXT_tessellation_shader");
170 m_is_tessellation_shader_point_size_supported = isExtensionSupported("GL_EXT_tessellation_point_size");
171 m_is_texture_cube_map_array_supported = isExtensionSupported("GL_EXT_texture_cube_map_array");
172 m_is_texture_border_clamp_supported = isExtensionSupported("GL_EXT_texture_border_clamp");
173 m_is_texture_buffer_supported = isExtensionSupported("GL_EXT_texture_buffer");
174 }
175
176 /* other ES 3.1 extensions */
177 m_is_shader_image_atomic_supported = isExtensionSupported("GL_OES_shader_image_atomic");
178 m_is_texture_storage_multisample_2d_array_supported =
179 isExtensionSupported("GL_OES_texture_storage_multisample_2d_array");
180 m_is_viewport_array_supported = isExtensionSupported("GL_OES_viewport_array");
181 }
182 }
183
184 /** Initializes function pointers for ES3.1 extensions, as well as determines
185 * availability of these extensions.
186 **/
initGLSLSpecializationMap()187 void TestCaseBase::initGLSLSpecializationMap()
188 {
189 m_specializationMap["VERSION"] = glu::getGLSLVersionDeclaration(m_glslVersion);
190 m_specializationMap["SHADER_IO_BLOCKS_ENABLE"] =
191 getGLSLExtDirective(m_extType, EXTENSIONNAME_SHADER_IO_BLOCKS, EXTENSIONBEHAVIOR_ENABLE);
192 m_specializationMap["SHADER_IO_BLOCKS_REQUIRE"] =
193 getGLSLExtDirective(m_extType, EXTENSIONNAME_SHADER_IO_BLOCKS, EXTENSIONBEHAVIOR_REQUIRE);
194 m_specializationMap["GEOMETRY_SHADER_ENABLE"] =
195 getGLSLExtDirective(m_extType, EXTENSIONNAME_GEOMETRY_SHADER, EXTENSIONBEHAVIOR_ENABLE);
196 m_specializationMap["GEOMETRY_SHADER_REQUIRE"] =
197 getGLSLExtDirective(m_extType, EXTENSIONNAME_GEOMETRY_SHADER, EXTENSIONBEHAVIOR_REQUIRE);
198 m_specializationMap["GEOMETRY_POINT_SIZE_ENABLE"] =
199 getGLSLExtDirective(m_extType, EXTENSIONNAME_GEOMETRY_POINT_SIZE, EXTENSIONBEHAVIOR_ENABLE);
200 m_specializationMap["GEOMETRY_POINT_SIZE_REQUIRE"] =
201 getGLSLExtDirective(m_extType, EXTENSIONNAME_GEOMETRY_POINT_SIZE, EXTENSIONBEHAVIOR_REQUIRE);
202 m_specializationMap["TESSELLATION_SHADER_ENABLE"] =
203 getGLSLExtDirective(m_extType, EXTENSIONNAME_TESSELLATION_SHADER, EXTENSIONBEHAVIOR_ENABLE);
204 m_specializationMap["TESSELLATION_SHADER_REQUIRE"] =
205 getGLSLExtDirective(m_extType, EXTENSIONNAME_TESSELLATION_SHADER, EXTENSIONBEHAVIOR_REQUIRE);
206 m_specializationMap["TESSELLATION_POINT_SIZE_ENABLE"] =
207 getGLSLExtDirective(m_extType, EXTENSIONNAME_TESSELLATION_POINT_SIZE, EXTENSIONBEHAVIOR_ENABLE);
208 m_specializationMap["TESSELLATION_POINT_SIZE_REQUIRE"] =
209 getGLSLExtDirective(m_extType, EXTENSIONNAME_TESSELLATION_POINT_SIZE, EXTENSIONBEHAVIOR_REQUIRE);
210 m_specializationMap["GPU_SHADER5_ENABLE"] =
211 getGLSLExtDirective(m_extType, EXTENSIONNAME_GPU_SHADER5, EXTENSIONBEHAVIOR_ENABLE);
212 m_specializationMap["GPU_SHADER5_REQUIRE"] =
213 getGLSLExtDirective(m_extType, EXTENSIONNAME_GPU_SHADER5, EXTENSIONBEHAVIOR_REQUIRE);
214 m_specializationMap["TEXTURE_BUFFER_ENABLE"] =
215 getGLSLExtDirective(m_extType, EXTENSIONNAME_TEXTURE_BUFFER, EXTENSIONBEHAVIOR_ENABLE);
216 m_specializationMap["TEXTURE_BUFFER_REQUIRE"] =
217 getGLSLExtDirective(m_extType, EXTENSIONNAME_TEXTURE_BUFFER, EXTENSIONBEHAVIOR_REQUIRE);
218 m_specializationMap["TEXTURE_CUBE_MAP_ARRAY_ENABLE"] =
219 getGLSLExtDirective(m_extType, EXTENSIONNAME_TEXTURE_CUBE_MAP_ARRAY, EXTENSIONBEHAVIOR_ENABLE);
220 m_specializationMap["TEXTURE_CUBE_MAP_ARRAY_REQUIRE"] =
221 getGLSLExtDirective(m_extType, EXTENSIONNAME_TEXTURE_CUBE_MAP_ARRAY, EXTENSIONBEHAVIOR_REQUIRE);
222 m_specializationMap["SHADER_IMAGE_ATOMIC_ENABLE"] =
223 getGLSLExtDirective(m_extType, EXTENSIONNAME_SHADER_IMAGE_ATOMIC, EXTENSIONBEHAVIOR_ENABLE);
224 m_specializationMap["SHADER_IMAGE_ATOMIC_REQUIRE"] =
225 getGLSLExtDirective(m_extType, EXTENSIONNAME_SHADER_IMAGE_ATOMIC, EXTENSIONBEHAVIOR_REQUIRE);
226 m_specializationMap["VIEWPORT_ARRAY_ENABLE"] =
227 getGLSLExtDirective(m_extType, EXTENSIONNAME_VIEWPORT_ARRAY, EXTENSIONBEHAVIOR_ENABLE);
228 m_specializationMap["VIEWPORT_ARRAY_REQUIRE"] =
229 getGLSLExtDirective(m_extType, EXTENSIONNAME_VIEWPORT_ARRAY, EXTENSIONBEHAVIOR_REQUIRE);
230
231 if (glu::isContextTypeES(m_context.getRenderContext().getType()))
232 {
233 m_specializationMap["IN_PER_VERTEX_DECL_ARRAY"] = "\n";
234 m_specializationMap["IN_PER_VERTEX_DECL_ARRAY_POINT_SIZE"] = "\n";
235 m_specializationMap["OUT_PER_VERTEX_DECL"] = "\n";
236 m_specializationMap["OUT_PER_VERTEX_DECL_POINT_SIZE"] = "\n";
237 m_specializationMap["OUT_PER_VERTEX_DECL_ARRAY"] = "\n";
238 m_specializationMap["OUT_PER_VERTEX_DECL_ARRAY_POINT_SIZE"] = "\n";
239 m_specializationMap["IN_DATA_DECL"] = "\n";
240 m_specializationMap["POSITION_WITH_IN_DATA"] = "gl_Position = gl_in[0].gl_Position;\n";
241 }
242 else
243 {
244 m_specializationMap["IN_PER_VERTEX_DECL_ARRAY"] = "in gl_PerVertex {\n"
245 " vec4 gl_Position;\n"
246 "} gl_in[];\n";
247 m_specializationMap["IN_PER_VERTEX_DECL_ARRAY_POINT_SIZE"] = "in gl_PerVertex {\n"
248 " vec4 gl_Position;\n"
249 " float gl_PointSize;\n"
250 "} gl_in[];\n";
251 m_specializationMap["OUT_PER_VERTEX_DECL"] = "out gl_PerVertex {\n"
252 " vec4 gl_Position;\n"
253 "};\n";
254 m_specializationMap["OUT_PER_VERTEX_DECL_POINT_SIZE"] = "out gl_PerVertex {\n"
255 " vec4 gl_Position;\n"
256 " float gl_PointSize;\n"
257 "};\n";
258 m_specializationMap["OUT_PER_VERTEX_DECL_ARRAY"] = "out gl_PerVertex {\n"
259 " vec4 gl_Position;\n"
260 "} gl_out[];\n";
261 m_specializationMap["OUT_PER_VERTEX_DECL_ARRAY_POINT_SIZE"] = "out gl_PerVertex {\n"
262 " vec4 gl_Position;\n"
263 " float gl_PointSize;\n"
264 "} gl_out[];\n";
265 m_specializationMap["IN_DATA_DECL"] = "in Data {\n"
266 " vec4 pos;\n"
267 "} input_data[1];\n";
268 m_specializationMap["POSITION_WITH_IN_DATA"] = "gl_Position = input_data[0].pos;\n";
269 }
270 }
271
272 /** Sets the seed for the random generator
273 * @param seed - seed for the random generator
274 */
randomSeed(const glw::GLuint seed)275 void TestCaseBase::randomSeed(const glw::GLuint seed)
276 {
277 seed_value = seed;
278 }
279
280 /** Returns random unsigned integer from the range [0,max)
281 * @param max - the value that is the upper boundary for the returned random numbers
282 * @return random unsigned integer from the range [0,max)
283 */
randomFormula(const glw::GLuint max)284 glw::GLuint TestCaseBase::randomFormula(const glw::GLuint max)
285 {
286 static const glw::GLuint a = 11;
287 static const glw::GLuint b = 17;
288
289 seed_value = (a * seed_value + b) % max;
290
291 return seed_value;
292 }
293
294 /** Executes the test.
295 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
296 *
297 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
298 *
299 * Note the function throws exception should an error occur!
300 **/
iterate(void)301 tcu::TestNode::IterateResult TestCaseBase::iterate(void)
302 {
303 qpTestResult result = QP_TEST_RESULT_FAIL;
304
305 m_testCtx.setTestResult(result, "This location should never be called.");
306
307 return STOP;
308 }
309
310 /** Deinitializes base class that all test implementations inherit from.
311 *
312 **/
deinit(void)313 void TestCaseBase::deinit(void)
314 {
315 /* Left empty on purpose */
316 }
317
318 /** Tells whether particular extension is supported.
319 *
320 * @param extName: The name of the extension
321 *
322 * @return true if given extension name is reported as supported, false otherwise.
323 **/
isExtensionSupported(const std::string & extName) const324 bool TestCaseBase::isExtensionSupported(const std::string& extName) const
325 {
326 const std::vector<std::string>& extensions = m_context.getContextInfo().getExtensions();
327
328 if (std::find(extensions.begin(), extensions.end(), extName) != extensions.end())
329 {
330 return true;
331 }
332
333 return false;
334 }
335
336 /** Helper method for specializing a shader */
specializeShader(const unsigned int parts,const char * const * code) const337 std::string TestCaseBase::specializeShader(const unsigned int parts, const char* const* code) const
338 {
339 std::stringstream code_merged;
340 for (unsigned int i = 0; i < parts; i++)
341 {
342 code_merged << code[i];
343 }
344 return tcu::StringTemplate(code_merged.str().c_str()).specialize(m_specializationMap);
345 }
346
shaderSourceSpecialized(glw::GLuint shader_id,glw::GLsizei shader_count,const glw::GLchar * const * shader_string)347 void TestCaseBase::shaderSourceSpecialized(glw::GLuint shader_id, glw::GLsizei shader_count,
348 const glw::GLchar* const* shader_string)
349 {
350 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
351
352 std::string specialized = specializeShader(shader_count, shader_string);
353 const char* specialized_cstr = specialized.c_str();
354 gl.shaderSource(shader_id, 1, &specialized_cstr, NULL);
355 }
356
getShaderTypeName(glw::GLenum shader_type)357 std::string getShaderTypeName(glw::GLenum shader_type)
358 {
359 switch (shader_type)
360 {
361 case GL_VERTEX_SHADER:
362 return "Vertex shader";
363 case GL_TESS_CONTROL_SHADER:
364 return "Tessellation control shader";
365 case GL_TESS_EVALUATION_SHADER:
366 return "Tessellation evaluation shader";
367 case GL_GEOMETRY_SHADER:
368 return "Geometry shader";
369 case GL_FRAGMENT_SHADER:
370 return "Fragment shader";
371 case GL_COMPUTE_SHADER:
372 return "Compute shader";
373 default:
374 DE_ASSERT(0);
375 return "??? shader";
376 }
377 }
378
379 /** Compiles and links program with variable amount of shaders
380 *
381 * @param po_id Program handle
382 * @param out_has_compilation_failed Deref will be set to true, if shader compilation
383 * failed for any of the submitted shaders.
384 * Will be set to false otherwise. Can be NULL.
385 * @param sh_stages Shader stages
386 * @for all shader stages
387 * {
388 * @param sh_id Shader handle. 0 means "skip"
389 * @param sh_parts Number of shader source code parts.
390 * 0 means that it's already compiled.
391 * @param sh_code Shader source code.
392 * }
393 **/
buildProgramVA(glw::GLuint po_id,bool * out_has_compilation_failed,unsigned int sh_stages,...)394 bool TestCaseBase::buildProgramVA(glw::GLuint po_id, bool* out_has_compilation_failed, unsigned int sh_stages, ...)
395 {
396 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
397 std::vector<glw::GLuint> vec_sh_id;
398
399 va_list values;
400 va_start(values, sh_stages);
401
402 /* Shaders compilation */
403 glw::GLint compilation_status = GL_FALSE;
404
405 for (unsigned int stage = 0; stage < sh_stages; ++stage)
406 {
407 glw::GLuint sh_id = va_arg(values, glw::GLuint);
408 unsigned int sh_parts = va_arg(values, unsigned int);
409 const char* const* sh_code = va_arg(values, const char* const*);
410
411 if (sh_id == 0)
412 {
413 continue;
414 }
415
416 if (sh_parts != 0)
417 {
418 std::string sh_merged_string = specializeShader(sh_parts, sh_code);
419 const char* sh_merged_ptr = sh_merged_string.c_str();
420
421 gl.shaderSource(sh_id, 1, &sh_merged_ptr, NULL);
422 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() failed!");
423
424 gl.compileShader(sh_id);
425 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() failed!");
426
427 gl.getShaderiv(sh_id, GL_COMPILE_STATUS, &compilation_status);
428 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() failed!");
429
430 if (compilation_status != GL_TRUE)
431 {
432 glw::GLint shader_type = 0;
433 std::string info_log = getCompilationInfoLog(sh_id);
434
435 gl.getShaderiv(sh_id, GL_SHADER_TYPE, &shader_type);
436 std::string shader_type_str = getShaderTypeName(shader_type);
437
438 m_testCtx.getLog() << tcu::TestLog::Message << shader_type_str << " compilation failure:\n\n"
439 << info_log << "\n\n"
440 << shader_type_str << " source:\n\n"
441 << sh_merged_string << "\n\n"
442 << tcu::TestLog::EndMessage;
443
444 break;
445 }
446 }
447
448 gl.attachShader(po_id, sh_id);
449 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader(VERTEX_SHADER) call failed");
450
451 vec_sh_id.push_back(sh_id);
452 }
453
454 va_end(values);
455
456 if (out_has_compilation_failed != NULL)
457 {
458 *out_has_compilation_failed = (compilation_status == GL_FALSE);
459 }
460
461 if (compilation_status != GL_TRUE)
462 {
463 return false;
464 }
465
466 /* Linking the program */
467
468 glw::GLint link_status = GL_FALSE;
469 gl.linkProgram(po_id);
470 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() failed!");
471
472 gl.getProgramiv(po_id, GL_LINK_STATUS, &link_status);
473 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() failed!");
474
475 if (link_status != GL_TRUE)
476 {
477 /* Dump link log */
478 std::string link_log = getLinkingInfoLog(po_id);
479 m_testCtx.getLog() << tcu::TestLog::Message << "Link failure:\n\n"
480 << link_log << "\n\n"
481 << tcu::TestLog::EndMessage;
482
483 /* Dump shader source */
484 for (std::vector<glw::GLuint>::iterator it = vec_sh_id.begin(); it != vec_sh_id.end(); ++it)
485 {
486 glw::GLint shader_type = 0;
487 gl.getShaderiv(*it, GL_SHADER_TYPE, &shader_type);
488 std::string shader_type_str = getShaderTypeName(shader_type);
489 std::string shader_source = getShaderSource(*it);
490 m_testCtx.getLog() << tcu::TestLog::Message << shader_type_str << " source:\n\n"
491 << shader_source << "\n\n"
492 << tcu::TestLog::EndMessage;
493 }
494
495 return false;
496 }
497
498 return true;
499 }
500
501 /** Builds an OpenGL ES program by configuring contents of 1 shader object,
502 * compiling it, attaching to specified program object, and finally
503 * by linking the program object.
504 *
505 * Implementation assumes all aforementioned objects have already been
506 * generated.
507 *
508 * @param po_id ID of program object
509 * @param sh1_shader_id ID of first shader to configure.
510 * @param n_sh1_body_parts Number of elements of @param sh1_body_parts array.
511 * @param sh1_body_parts Pointer to array of strings to make up first shader's body.
512 * Can be NULL.
513 *
514 * @return GTFtrue if successful, false otherwise.
515 */
buildProgram(glw::GLuint po_id,glw::GLuint sh1_shader_id,unsigned int n_sh1_body_parts,const char * const * sh1_body_parts,bool * out_has_compilation_failed)516 bool TestCaseBase::buildProgram(glw::GLuint po_id, glw::GLuint sh1_shader_id, unsigned int n_sh1_body_parts,
517 const char* const* sh1_body_parts, bool* out_has_compilation_failed)
518 {
519 return buildProgramVA(po_id, out_has_compilation_failed, 1, sh1_shader_id, n_sh1_body_parts, sh1_body_parts);
520 }
521
522 /** Builds an OpenGL ES program by configuring contents of 2 shader objects,
523 * compiling them, attaching to specified program object, and finally
524 * by linking the program object.
525 *
526 * Implementation assumes all aforementioned objects have already been
527 * generated.
528 *
529 * @param po_id ID of program object
530 * @param sh1_shader_id ID of first shader to configure.
531 * @param n_sh1_body_parts Number of elements of @param sh1_body_parts array.
532 * @param sh1_body_parts Pointer to array of strings to make up first shader's body.
533 * Can be NULL.
534 * @param sh2_shader_id ID of second shader to configure.
535 * @param n_sh2_body_parts Number of elements of @param sh2_body_parts array.
536 * @param sh2_body_parts Pointer to array of strings to make up second shader's body.
537 * Can be NULL.
538 *
539 * @return GTFtrue if successful, false otherwise.
540 */
buildProgram(glw::GLuint po_id,glw::GLuint sh1_shader_id,unsigned int n_sh1_body_parts,const char * const * sh1_body_parts,glw::GLuint sh2_shader_id,unsigned int n_sh2_body_parts,const char * const * sh2_body_parts,bool * out_has_compilation_failed)541 bool TestCaseBase::buildProgram(glw::GLuint po_id, glw::GLuint sh1_shader_id, unsigned int n_sh1_body_parts,
542 const char* const* sh1_body_parts, glw::GLuint sh2_shader_id,
543 unsigned int n_sh2_body_parts, const char* const* sh2_body_parts,
544 bool* out_has_compilation_failed)
545 {
546 return buildProgramVA(po_id, out_has_compilation_failed, 2, sh1_shader_id, n_sh1_body_parts, sh1_body_parts,
547 sh2_shader_id, n_sh2_body_parts, sh2_body_parts);
548 }
549
550 /** Builds an OpenGL ES program by configuring contents of 3 shader objects,
551 * compiling them, attaching to specified program object, and finally
552 * by linking the program object.
553 *
554 * Implementation assumes all aforementioned objects have already been
555 * generated.
556 *
557 * @param po_id ID of program object
558 * @param sh1_shader_id ID of first shader to configure.
559 * @param n_sh1_body_parts Number of elements of @param sh1_body_parts array.
560 * @param sh1_body_parts Pointer to array of strings to make up first shader's body.
561 * Can be NULL.
562 * @param sh2_shader_id ID of second shader to configure.
563 * @param n_sh2_body_parts Number of elements of @param sh2_body_parts array.
564 * @param sh2_body_parts Pointer to array of strings to make up second shader's body.
565 * Can be NULL.
566 * @param sh3_shader_id ID of third shader to configure.
567 * @param n_sh3_body_parts Number of elements of @param sh3_body_parts array.
568 * @param sh3_body_parts Pointer to array of strings to make up third shader's body.
569 * Can be NULL.
570 * @param has_compilation_failed Deref will be set to true if shader compilation failed,
571 * false if shader compilation was successful. Can be NULL.
572 *
573 * @return GTFtrue if successful, false otherwise.
574 */
buildProgram(glw::GLuint po_id,glw::GLuint sh1_shader_id,unsigned int n_sh1_body_parts,const char * const * sh1_body_parts,glw::GLuint sh2_shader_id,unsigned int n_sh2_body_parts,const char * const * sh2_body_parts,glw::GLuint sh3_shader_id,unsigned int n_sh3_body_parts,const char * const * sh3_body_parts,bool * out_has_compilation_failed)575 bool TestCaseBase::buildProgram(glw::GLuint po_id, glw::GLuint sh1_shader_id, unsigned int n_sh1_body_parts,
576 const char* const* sh1_body_parts, glw::GLuint sh2_shader_id,
577 unsigned int n_sh2_body_parts, const char* const* sh2_body_parts,
578 glw::GLuint sh3_shader_id, unsigned int n_sh3_body_parts,
579 const char* const* sh3_body_parts, bool* out_has_compilation_failed)
580 {
581 return buildProgramVA(po_id, out_has_compilation_failed, 3, sh1_shader_id, n_sh1_body_parts, sh1_body_parts,
582 sh2_shader_id, n_sh2_body_parts, sh2_body_parts, sh3_shader_id, n_sh3_body_parts,
583 sh3_body_parts);
584 }
585
586 /** Builds an OpenGL ES program by configuring contents of 4 shader objects,
587 * compiling them, attaching to specified program object, and finally
588 * by linking the program object.
589 *
590 * Implementation assumes all aforementioned objects have already been
591 * generated.
592 *
593 * @param po_id ID of program object
594 * @param sh1_shader_id ID of first shader to configure.
595 * @param n_sh1_body_parts Number of elements of @param sh1_body_parts array.
596 * @param sh1_body_parts Pointer to array of strings to make up first shader's body.
597 * Can be NULL.
598 * @param sh2_shader_id ID of second shader to configure.
599 * @param n_sh2_body_parts Number of elements of @param sh2_body_parts array.
600 * @param sh2_body_parts Pointer to array of strings to make up second shader's body.
601 * Can be NULL.
602 * @param sh3_shader_id ID of third shader to configure.
603 * @param n_sh3_body_parts Number of elements of @param sh3_body_parts array.
604 * @param sh3_body_parts Pointer to array of strings to make up third shader's body.
605 * Can be NULL.
606 * @param sh4_shader_id ID of fourth shader to configure.
607 * @param n_sh4_body_parts Number of elements of @param sh4_body_parts array.
608 * @param sh4_body_parts Pointer to array of strings to make up fourth shader's body.
609 * Can be NULL.
610 *
611 * @return GTFtrue if successful, false otherwise.
612 */
buildProgram(glw::GLuint po_id,glw::GLuint sh1_shader_id,unsigned int n_sh1_body_parts,const char * const * sh1_body_parts,glw::GLuint sh2_shader_id,unsigned int n_sh2_body_parts,const char * const * sh2_body_parts,glw::GLuint sh3_shader_id,unsigned int n_sh3_body_parts,const char * const * sh3_body_parts,glw::GLuint sh4_shader_id,unsigned int n_sh4_body_parts,const char * const * sh4_body_parts,bool * out_has_compilation_failed)613 bool TestCaseBase::buildProgram(glw::GLuint po_id, glw::GLuint sh1_shader_id, unsigned int n_sh1_body_parts,
614 const char* const* sh1_body_parts, glw::GLuint sh2_shader_id,
615 unsigned int n_sh2_body_parts, const char* const* sh2_body_parts,
616 glw::GLuint sh3_shader_id, unsigned int n_sh3_body_parts,
617 const char* const* sh3_body_parts, glw::GLuint sh4_shader_id,
618 unsigned int n_sh4_body_parts, const char* const* sh4_body_parts,
619 bool* out_has_compilation_failed)
620 {
621 return buildProgramVA(po_id, out_has_compilation_failed, 4, sh1_shader_id, n_sh1_body_parts, sh1_body_parts,
622 sh2_shader_id, n_sh2_body_parts, sh2_body_parts, sh3_shader_id, n_sh3_body_parts,
623 sh3_body_parts, sh4_shader_id, n_sh4_body_parts, sh4_body_parts);
624 }
625
626 /** Builds an OpenGL ES program by configuring contents of 5 shader objects,
627 * compiling them, attaching to specified program object, and finally
628 * by linking the program object.
629 *
630 * Implementation assumes all aforementioned objects have already been
631 * generated.
632 *
633 * @param po_id ID of program object
634 * @param sh1_shader_id ID of first shader to configure.
635 * @param n_sh1_body_parts Number of elements of @param sh1_body_parts array.
636 * @param sh1_body_parts Pointer to array of strings to make up first shader's body.
637 * Can be NULL.
638 * @param sh2_shader_id ID of second shader to configure.
639 * @param n_sh2_body_parts Number of elements of @param sh2_body_parts array.
640 * @param sh2_body_parts Pointer to array of strings to make up second shader's body.
641 * Can be NULL.
642 * @param sh3_shader_id ID of third shader to configure.
643 * @param n_sh3_body_parts Number of elements of @param sh3_body_parts array.
644 * @param sh3_body_parts Pointer to array of strings to make up third shader's body.
645 * Can be NULL.
646 * @param sh4_shader_id ID of fourth shader to configure.
647 * @param n_sh4_body_parts Number of elements of @param sh4_body_parts array.
648 * @param sh4_body_parts Pointer to array of strings to make up fourth shader's body.
649 * Can be NULL.
650 * @param sh5_shader_id ID of fifth shader to configure.
651 * @param n_sh5_body_parts Number of elements of @param sh5_body_parts array.
652 * @param sh5_body_parts Pointer to array of strings to make up fifth shader's body.
653 * Can be NULL.
654 *
655 * @return GTFtrue if successful, false otherwise.
656 */
buildProgram(glw::GLuint po_id,glw::GLuint sh1_shader_id,unsigned int n_sh1_body_parts,const char * const * sh1_body_parts,glw::GLuint sh2_shader_id,unsigned int n_sh2_body_parts,const char * const * sh2_body_parts,glw::GLuint sh3_shader_id,unsigned int n_sh3_body_parts,const char * const * sh3_body_parts,glw::GLuint sh4_shader_id,unsigned int n_sh4_body_parts,const char * const * sh4_body_parts,glw::GLuint sh5_shader_id,unsigned int n_sh5_body_parts,const char * const * sh5_body_parts,bool * out_has_compilation_failed)657 bool TestCaseBase::buildProgram(glw::GLuint po_id, glw::GLuint sh1_shader_id, unsigned int n_sh1_body_parts,
658 const char* const* sh1_body_parts, glw::GLuint sh2_shader_id,
659 unsigned int n_sh2_body_parts, const char* const* sh2_body_parts,
660 glw::GLuint sh3_shader_id, unsigned int n_sh3_body_parts,
661 const char* const* sh3_body_parts, glw::GLuint sh4_shader_id,
662 unsigned int n_sh4_body_parts, const char* const* sh4_body_parts,
663 glw::GLuint sh5_shader_id, unsigned int n_sh5_body_parts,
664 const char* const* sh5_body_parts, bool* out_has_compilation_failed)
665 {
666 return buildProgramVA(po_id, out_has_compilation_failed, 5, sh1_shader_id, n_sh1_body_parts, sh1_body_parts,
667 sh2_shader_id, n_sh2_body_parts, sh2_body_parts, sh3_shader_id, n_sh3_body_parts,
668 sh3_body_parts, sh4_shader_id, n_sh4_body_parts, sh4_body_parts, sh5_shader_id,
669 n_sh5_body_parts, sh5_body_parts);
670 }
671
672 /** Compare pixel's color with specified value.
673 * Assumptions:
674 * - size of each channel is 1 byte
675 * - channel order is R G B A
676 * - lines are stored one after another, without any additional data
677 *
678 * @param buffer Image data
679 * @param x X coordinate of pixel
680 * @param y Y coordinate of pixel
681 * @param width Image width
682 * @param height Image height
683 * @param pixel_size Size of single pixel in bytes, eg. for RGBA8 it should be set to 4
684 * @param expected_red Expected value of red channel, default is 0
685 * @param expected_green Expected value of green channel, default is 0
686 * @param expected_blue Expected value of blue channel, default is 0
687 * @param expected_alpha Expected value of alpha channel, default is 0
688 *
689 * @retrun true When pixel color matches expected values
690 * false When:
691 * - buffer is null_ptr
692 * - offset of pixel exceeds size of image
693 * - pixel_size is not in range <1 ; 4>
694 * - pixel color does not match expected values
695 **/
comparePixel(const unsigned char * buffer,unsigned int x,unsigned int y,unsigned int width,unsigned int height,unsigned int pixel_size,unsigned char expected_red,unsigned char expected_green,unsigned char expected_blue,unsigned char expected_alpha) const696 bool TestCaseBase::comparePixel(const unsigned char* buffer, unsigned int x, unsigned int y, unsigned int width,
697 unsigned int height, unsigned int pixel_size, unsigned char expected_red,
698 unsigned char expected_green, unsigned char expected_blue,
699 unsigned char expected_alpha) const
700 {
701 const unsigned int line_size = width * pixel_size;
702 const unsigned int image_size = height * line_size;
703 const unsigned int texel_offset = y * line_size + x * pixel_size;
704
705 bool result = true;
706
707 /* Sanity checks */
708 if (0 == buffer)
709 {
710 return false;
711 }
712
713 if (image_size < texel_offset)
714 {
715 return false;
716 }
717
718 switch (pixel_size)
719 {
720 /* Fall through by design */
721 case 4:
722 {
723 result &= (expected_alpha == buffer[texel_offset + 3]);
724 }
725 /* Fallthrough */
726
727 case 3:
728 {
729 result &= (expected_blue == buffer[texel_offset + 2]);
730 }
731 /* Fallthrough */
732
733 case 2:
734 {
735 result &= (expected_green == buffer[texel_offset + 1]);
736 }
737 /* Fallthrough */
738
739 case 1:
740 {
741 result &= (expected_red == buffer[texel_offset + 0]);
742
743 break;
744 }
745
746 default:
747 {
748 return false;
749 }
750 } /* switch (pixel_size) */
751
752 return result;
753 }
754
755 /** Checks whether a combination of fragment/geometry/vertex shader objects compiles and links into a program
756 *
757 * @param n_fs_body_parts Number of elements of @param fs_body_parts array.
758 * @param fs_body_parts Pointer to array of strings to make up fragment shader's body.
759 * Must not be NULL.
760 *
761 * @param n_gs_body_parts Number of elements of @param gs_body_parts array.
762 * @param gs_body_parts Pointer to array of strings to make up geometry shader's body.
763 * Can be NULL.
764 *
765 * @param n_vs_body_parts Number of elements of @param vs_body_parts array.
766 * @param vs_body_parts Pointer to array of strings to make up vertex shader's body.
767 * Must not be NULL.
768 *
769 * @return true if program creation was successful, false otherwise.
770 **/
doesProgramBuild(unsigned int n_fs_body_parts,const char * const * fs_body_parts,unsigned int n_gs_body_parts,const char * const * gs_body_parts,unsigned int n_vs_body_parts,const char * const * vs_body_parts)771 bool TestCaseBase::doesProgramBuild(unsigned int n_fs_body_parts, const char* const* fs_body_parts,
772 unsigned int n_gs_body_parts, const char* const* gs_body_parts,
773 unsigned int n_vs_body_parts, const char* const* vs_body_parts)
774 {
775 /* General variables */
776 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
777 bool result = false;
778
779 /* Shaders */
780 glw::GLuint vertex_shader_id = 0;
781 glw::GLuint geometry_shader_id = 0;
782 glw::GLuint fragment_shader_id = 0;
783
784 /* Program */
785 glw::GLuint program_object_id = 0;
786
787 /* Create shaders */
788 vertex_shader_id = gl.createShader(GL_VERTEX_SHADER);
789 geometry_shader_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
790 fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER);
791
792 /* Create program */
793 program_object_id = gl.createProgram();
794
795 /* Check createProgram call for errors */
796 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
797
798 /* Compile and link the program */
799 result = buildProgram(program_object_id, fragment_shader_id, n_fs_body_parts, fs_body_parts, geometry_shader_id,
800 n_gs_body_parts, gs_body_parts, vertex_shader_id, n_vs_body_parts, vs_body_parts);
801
802 if (program_object_id != 0)
803 gl.deleteProgram(program_object_id);
804 if (fragment_shader_id != 0)
805 gl.deleteShader(fragment_shader_id);
806 if (geometry_shader_id != 0)
807 gl.deleteShader(geometry_shader_id);
808 if (vertex_shader_id != 0)
809 gl.deleteShader(vertex_shader_id);
810
811 return result;
812 }
813
814 /** Retrieves source for a shader object with GLES id @param shader_id.
815 *
816 * @param shader_id GLES id of a shader object to retrieve source for.
817 *
818 * @return String instance containing the shader source.
819 **/
getShaderSource(glw::GLuint shader_id)820 std::string TestCaseBase::getShaderSource(glw::GLuint shader_id)
821 {
822 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
823
824 glw::GLint length = 0;
825
826 gl.getShaderiv(shader_id, GL_SHADER_SOURCE_LENGTH, &length);
827
828 std::vector<char> result_vec(length + 1);
829
830 gl.getShaderSource(shader_id, length + 1, NULL, &result_vec[0]);
831
832 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not retrieve shader source!");
833
834 return std::string(&result_vec[0]);
835 }
836
837 /** Retrieves compilation info log for a shader object with GLES id
838 * @param shader_id.
839 *
840 * @param shader_id GLES id of a shader object to retrieve compilation
841 * info log for.
842 *
843 * @return String instance containing the log.
844 **/
getCompilationInfoLog(glw::GLuint shader_id)845 std::string TestCaseBase::getCompilationInfoLog(glw::GLuint shader_id)
846 {
847 return getInfoLog(LT_SHADER_OBJECT, shader_id);
848 }
849
850 /** Retrieves linking info log for a program object with GLES id
851 * @param po_id.
852 *
853 * @param po_id GLES id of a program object to retrieve linking
854 * info log for.
855 *
856 * @return String instance containing the log.
857 **/
getLinkingInfoLog(glw::GLuint po_id)858 std::string TestCaseBase::getLinkingInfoLog(glw::GLuint po_id)
859 {
860 return getInfoLog(LT_PROGRAM_OBJECT, po_id);
861 }
862
863 /** Retrieves linking info log for a pipeline object with GLES id
864 * @param ppo_id.
865 *
866 * @param ppo_id GLES id of a pipeline object to retrieve validation
867 * info log for.
868 *
869 * @return String instance containing the log.
870 **/
getPipelineInfoLog(glw::GLuint ppo_id)871 std::string TestCaseBase::getPipelineInfoLog(glw::GLuint ppo_id)
872 {
873 return getInfoLog(LT_PIPELINE_OBJECT, ppo_id);
874 }
875
876 /** Retrieves compilation OR linking info log for a shader/program object with GLES id
877 * @param id.
878 *
879 * @param is_compilation_info_log true if @param id is a GLES id of a shader object;
880 * false if it represents a program object.
881 * @param id GLES id of a shader OR a program object to
882 * retrieve info log for.
883 *
884 * @return String instance containing the log..
885 **/
getInfoLog(LOG_TYPE log_type,glw::GLuint id)886 std::string TestCaseBase::getInfoLog(LOG_TYPE log_type, glw::GLuint id)
887 {
888 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
889
890 glw::GLint n_characters = 0;
891 /* Retrieve amount of characters needed to store the info log (terminator-inclusive) */
892 switch (log_type)
893 {
894 case LT_SHADER_OBJECT:
895 gl.getShaderiv(id, GL_INFO_LOG_LENGTH, &n_characters);
896 break;
897 case LT_PROGRAM_OBJECT:
898 gl.getProgramiv(id, GL_INFO_LOG_LENGTH, &n_characters);
899 break;
900 case LT_PIPELINE_OBJECT:
901 gl.getProgramPipelineiv(id, GL_INFO_LOG_LENGTH, &n_characters);
902 break;
903 default:
904 TCU_FAIL("Invalid parameter");
905 }
906
907 /* Check if everything is fine so far */
908 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not query info log length!");
909
910 /* Allocate buffer */
911 std::vector<char> result_vec(n_characters + 1);
912
913 /* Retrieve the info log */
914 switch (log_type)
915 {
916 case LT_SHADER_OBJECT:
917 gl.getShaderInfoLog(id, n_characters + 1, 0, &result_vec[0]);
918 break;
919 case LT_PROGRAM_OBJECT:
920 gl.getProgramInfoLog(id, n_characters + 1, 0, &result_vec[0]);
921 break;
922 case LT_PIPELINE_OBJECT:
923 gl.getProgramPipelineInfoLog(id, n_characters + 1, 0, &result_vec[0]);
924 break;
925 }
926
927 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not retrieve info log!");
928
929 return std::string(&result_vec[0]);
930 }
931
932 /** Setup frame buffer:
933 * 1 allocate texture storage for specified format and dimensions,
934 * 2 bind framebuffer and attach texture to GL_COLOR_ATTACHMENT0
935 * 3 setup viewport to specified dimensions
936 *
937 * @param framebuffer_object_id FBO handle
938 * @param color_texture_id Texture handle
939 * @param texture_format Requested texture format, eg. GL_RGBA8
940 * @param texture_width Requested texture width
941 * @param texture_height Requested texture height
942 *
943 * @return true All operations succeded
944 * false In case of any error
945 **/
setupFramebufferWithTextureAsAttachment(glw::GLuint framebuffer_object_id,glw::GLuint color_texture_id,glw::GLenum texture_format,glw::GLuint texture_width,glw::GLuint texture_height) const946 bool TestCaseBase::setupFramebufferWithTextureAsAttachment(glw::GLuint framebuffer_object_id,
947 glw::GLuint color_texture_id, glw::GLenum texture_format,
948 glw::GLuint texture_width, glw::GLuint texture_height) const
949 {
950 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
951
952 /* Allocate texture storage */
953 gl.bindTexture(GL_TEXTURE_2D, color_texture_id);
954 gl.texStorage2D(GL_TEXTURE_2D, 1 /* levels */, texture_format, texture_width, texture_height);
955
956 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not allocate texture storage!");
957
958 /* Setup framebuffer */
959 gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer_object_id);
960 gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color_texture_id, 0 /* level */);
961
962 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not setup framebuffer!");
963
964 /* Setup viewport */
965 gl.viewport(0, 0, texture_width, texture_height);
966
967 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not setup viewport!");
968
969 /* Success */
970 return true;
971 }
972
973 /** Check Framebuffer Status.
974 * Throws a TestError exception, should the framebuffer be found incomplete.
975 *
976 * @param framebuffer - GL_DRAW_FRAMEBUFFER, GL_READ_FRAMEBUFFER or GL_FRAMEBUFFER
977 *
978 */
checkFramebufferStatus(glw::GLenum framebuffer) const979 void TestCaseBase::checkFramebufferStatus(glw::GLenum framebuffer) const
980 {
981 /* Get GL entry points */
982 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
983
984 glw::GLenum framebuffer_status = gl.checkFramebufferStatus(framebuffer);
985 GLU_EXPECT_NO_ERROR(gl.getError(), "Error getting framebuffer status!");
986
987 if (GL_FRAMEBUFFER_COMPLETE != framebuffer_status)
988 {
989 switch (framebuffer_status)
990 {
991 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
992 {
993 TCU_FAIL("Framebuffer incomplete, status: GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT");
994 }
995
996 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
997 {
998 TCU_FAIL("Framebuffer incomplete, status: GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS");
999 }
1000
1001 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
1002 {
1003 TCU_FAIL("Framebuffer incomplete, status: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT");
1004 }
1005
1006 case GL_FRAMEBUFFER_UNSUPPORTED:
1007 {
1008 TCU_FAIL("Framebuffer incomplete, status: Error: GL_FRAMEBUFFER_UNSUPPORTED");
1009 }
1010
1011 default:
1012 {
1013 TCU_FAIL("Framebuffer incomplete, status not recognized");
1014 }
1015 } /* switch (framebuffer_status) */
1016 } /* if (GL_FRAMEBUFFER_COMPLETE != framebuffer_status) */
1017 }
1018
getGLSLExtDirective(ExtensionType type,ExtensionName name,ExtensionBehavior behavior)1019 std::string TestCaseBase::getGLSLExtDirective(ExtensionType type, ExtensionName name, ExtensionBehavior behavior)
1020 {
1021 if (type == EXTENSIONTYPE_NONE && name != EXTENSIONNAME_GEOMETRY_POINT_SIZE &&
1022 name != EXTENSIONNAME_TESSELLATION_POINT_SIZE)
1023 {
1024 return "";
1025 }
1026
1027 const char* type_str = NULL;
1028 const char* name_str = NULL;
1029 const char* behavior_str = NULL;
1030
1031 if (name == EXTENSIONNAME_SHADER_IMAGE_ATOMIC)
1032 {
1033 // There is no EXT version of shader_image_atomic; use OES
1034 type = EXTENSIONTYPE_OES;
1035 }
1036
1037 if (name == EXTENSIONNAME_TESSELLATION_POINT_SIZE)
1038 {
1039 // there is no core version of tessellation_point_size, use OES or EXT
1040 if (isExtensionSupported("GL_OES_tessellation_point_size"))
1041 {
1042 type = EXTENSIONTYPE_OES;
1043 }
1044 else if (isExtensionSupported("GL_EXT_tessellation_point_size"))
1045 {
1046 type = EXTENSIONTYPE_EXT;
1047 }
1048 else
1049 {
1050 return "";
1051 }
1052 }
1053
1054 if (name == EXTENSIONNAME_GEOMETRY_POINT_SIZE)
1055 {
1056 // there is no core version of geometry_point_size, use OES or EXT
1057 if (isExtensionSupported("GL_OES_geometry_point_size"))
1058 {
1059 type = EXTENSIONTYPE_OES;
1060 }
1061 else if (isExtensionSupported("GL_EXT_geometry_point_size"))
1062 {
1063 type = EXTENSIONTYPE_EXT;
1064 }
1065 else
1066 {
1067 return "";
1068 }
1069 }
1070
1071 switch (type)
1072 {
1073 case EXTENSIONTYPE_EXT:
1074 type_str = "EXT_";
1075 break;
1076 case EXTENSIONTYPE_OES:
1077 type_str = "OES_";
1078 break;
1079 default:
1080 DE_ASSERT(0);
1081 return "#error unknown extension type\n";
1082 }
1083
1084 switch (name)
1085 {
1086 case EXTENSIONNAME_SHADER_IMAGE_ATOMIC:
1087 name_str = "shader_image_atomic";
1088 break;
1089 case EXTENSIONNAME_SHADER_IO_BLOCKS:
1090 name_str = "shader_io_blocks";
1091 break;
1092 case EXTENSIONNAME_GEOMETRY_SHADER:
1093 name_str = "geometry_shader";
1094 break;
1095 case EXTENSIONNAME_GEOMETRY_POINT_SIZE:
1096 name_str = "geometry_point_size";
1097 break;
1098 case EXTENSIONNAME_TESSELLATION_SHADER:
1099 name_str = "tessellation_shader";
1100 break;
1101 case EXTENSIONNAME_TESSELLATION_POINT_SIZE:
1102 name_str = "tessellation_point_size";
1103 break;
1104 case EXTENSIONNAME_TEXTURE_BUFFER:
1105 name_str = "texture_buffer";
1106 break;
1107 case EXTENSIONNAME_TEXTURE_CUBE_MAP_ARRAY:
1108 name_str = "texture_cube_map_array";
1109 break;
1110 case EXTENSIONNAME_GPU_SHADER5:
1111 name_str = "gpu_shader5";
1112 break;
1113 case EXTENSIONNAME_VIEWPORT_ARRAY:
1114 name_str = "viewport_array";
1115 break;
1116 default:
1117 DE_ASSERT(0);
1118 return "#error unknown extension name\n";
1119 }
1120
1121 switch (behavior)
1122 {
1123 case EXTENSIONBEHAVIOR_DISABLE:
1124 behavior_str = "disable";
1125 break;
1126 case EXTENSIONBEHAVIOR_WARN:
1127 behavior_str = "warn";
1128 break;
1129 case EXTENSIONBEHAVIOR_ENABLE:
1130 behavior_str = "enable";
1131 break;
1132 case EXTENSIONBEHAVIOR_REQUIRE:
1133 behavior_str = "require";
1134 break;
1135 default:
1136 DE_ASSERT(0);
1137 return "#error unknown extension behavior";
1138 }
1139
1140 std::stringstream str;
1141 str << "#extension GL_" << type_str << name_str << " : " << behavior_str;
1142 return str.str();
1143 }
1144
1145 } // namespace glcts
1146