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