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