• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2019 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // EGLPrintEGLinfoTest.cpp:
7 //   This test prints out the extension strings, configs and their attributes
8 //
9 
10 #include <gtest/gtest.h>
11 
12 #include "common/string_utils.h"
13 #include "test_utils/ANGLETest.h"
14 #include "test_utils/runner/TestSuite.h"
15 
16 #if defined(ANGLE_HAS_RAPIDJSON)
17 #    include "common/serializer/JsonSerializer.h"
18 #endif  // defined(ANGLE_HAS_RAPIDJSON)
19 
20 using namespace angle;
21 
22 class EGLPrintEGLinfoTest : public ANGLETest<>
23 {
24   protected:
EGLPrintEGLinfoTest()25     EGLPrintEGLinfoTest() {}
26 
testSetUp()27     void testSetUp() override
28     {
29         mDisplay = getEGLWindow()->getDisplay();
30         ASSERT_TRUE(mDisplay != EGL_NO_DISPLAY);
31     }
32 
33     EGLDisplay mDisplay = EGL_NO_DISPLAY;
34 };
35 
36 namespace
37 {
38 // Parse space separated extension string into a vector of strings
ParseExtensions(const char * extensions)39 std::vector<std::string> ParseExtensions(const char *extensions)
40 {
41     std::string extensionsStr(extensions);
42     std::vector<std::string> extensionsVec;
43     SplitStringAlongWhitespace(extensionsStr, &extensionsVec);
44     return extensionsVec;
45 }
46 
47 // Query a EGL attribute
GetAttrib(EGLDisplay display,EGLConfig config,EGLint attrib)48 EGLint GetAttrib(EGLDisplay display, EGLConfig config, EGLint attrib)
49 {
50     EGLint value = 0;
51     EXPECT_EGL_TRUE(eglGetConfigAttrib(display, config, attrib, &value));
52     return value;
53 }
54 
55 // Query a egl string
GetEGLString(EGLDisplay display,EGLint name)56 const char *GetEGLString(EGLDisplay display, EGLint name)
57 {
58     const char *value = "";
59     value             = eglQueryString(display, name);
60     EXPECT_EGL_ERROR(EGL_SUCCESS);
61     EXPECT_TRUE(value != nullptr);
62     return value;
63 }
64 
65 // Query a GL string
GetGLString(EGLint name)66 const char *GetGLString(EGLint name)
67 {
68     const char *value = "";
69     value             = reinterpret_cast<const char *>(glGetString(name));
70     EXPECT_GL_ERROR(GL_NO_ERROR);
71     EXPECT_TRUE(value != nullptr);
72     return value;
73 }
74 
75 }  // namespace
76 
77 // Print the EGL strings and extensions
TEST_P(EGLPrintEGLinfoTest,PrintEGLInfo)78 TEST_P(EGLPrintEGLinfoTest, PrintEGLInfo)
79 {
80     std::cout << "    EGL Information:" << std::endl;
81     std::cout << "\tVendor: " << GetEGLString(mDisplay, EGL_VENDOR) << std::endl;
82     std::cout << "\tVersion: " << GetEGLString(mDisplay, EGL_VERSION) << std::endl;
83     std::cout << "\tClient APIs: " << GetEGLString(mDisplay, EGL_CLIENT_APIS) << std::endl;
84 
85     std::cout << "\tEGL Client Extensions:" << std::endl;
86     for (auto extension : ParseExtensions(GetEGLString(EGL_NO_DISPLAY, EGL_EXTENSIONS)))
87     {
88         std::cout << "\t\t" << extension << std::endl;
89     }
90 
91     std::cout << "\tEGL Display Extensions:" << std::endl;
92     for (auto extension : ParseExtensions(GetEGLString(mDisplay, EGL_EXTENSIONS)))
93     {
94         std::cout << "\t\t" << extension << std::endl;
95     }
96 
97     std::cout << std::endl;
98 }
99 
100 // Print the GL strings and extensions
TEST_P(EGLPrintEGLinfoTest,PrintGLInfo)101 TEST_P(EGLPrintEGLinfoTest, PrintGLInfo)
102 {
103     std::cout << "    GLES Information:" << std::endl;
104     std::cout << "\tVendor: " << GetGLString(GL_VENDOR) << std::endl;
105     std::cout << "\tVersion: " << GetGLString(GL_VERSION) << std::endl;
106     std::cout << "\tRenderer: " << GetGLString(GL_RENDERER) << std::endl;
107     std::cout << "\tShader: " << GetGLString(GL_SHADING_LANGUAGE_VERSION) << std::endl;
108 
109     std::cout << "\tExtensions:" << std::endl;
110 
111     const std::vector<std::string> extensions = ParseExtensions(GetGLString(GL_EXTENSIONS));
112 
113     for (const std::string &extension : extensions)
114     {
115         std::cout << "\t\t" << extension << std::endl;
116     }
117 
118     std::cout << std::endl;
119 
120 #if defined(ANGLE_HAS_RAPIDJSON)
121     angle::TestSuite *testSuite = angle::TestSuite::GetInstance();
122     if (!testSuite->hasTestArtifactsDirectory())
123     {
124         return;
125     }
126     JsonSerializer json;
127     json.addCString("Vendor", GetGLString(GL_VENDOR));
128     json.addCString("Version", GetGLString(GL_VERSION));
129     json.addCString("Renderer", GetGLString(GL_RENDERER));
130     json.addCString("ShaderLanguageVersion", GetGLString(GL_SHADING_LANGUAGE_VERSION));
131     json.addVectorOfStrings("Extensions", extensions);
132 
133     constexpr size_t kBufferSize = 1000;
134     std::array<char, kBufferSize> buffer;
135     std::time_t timeNow = std::time(nullptr);
136     std::strftime(buffer.data(), buffer.size(), "%B %e, %Y", std::localtime(&timeNow));
137     json.addCString("DateRecorded", buffer.data());
138 
139     std::stringstream fnameStream;
140     fnameStream << "GLinfo_" << GetParam() << ".json";
141     std::string fname = fnameStream.str();
142 
143     const std::string artifactPath = testSuite->reserveTestArtifactPath(fname);
144 
145     {
146         std::vector<uint8_t> jsonData = json.getData();
147         SaveFileHelper saveFile(artifactPath);
148         saveFile.write(jsonData.data(), jsonData.size());
149     }
150 #endif  // defined(ANGLE_HAS_RAPIDJSON)
151 }
152 
153 #define QUERY_HELPER(enumValue, enumString, stream)                                    \
154     {                                                                                  \
155         GLint result;                                                                  \
156         glGetIntegerv(enumValue, &result);                                             \
157         ASSERT_GL_NO_ERROR();                                                          \
158         stream << enumString + std::string(",") + std::to_string(result) << std::endl; \
159     }
160 
161 #define QUERY_ARRAY_HELPER(enumValue, enumString, size, stream)               \
162     {                                                                         \
163         GLint result[size];                                                   \
164         glGetIntegerv(enumValue, result);                                     \
165         ASSERT_GL_NO_ERROR();                                                 \
166         std::stringstream results;                                            \
167         for (int i = 0; i < size; i++)                                        \
168             results << result[i] << " ";                                      \
169         stream << enumString + std::string(",") + results.str() << std::endl; \
170     }
171 
172 #define QUERY_INDEXED_HELPER(enumValue, enumString, index, stream)                     \
173     {                                                                                  \
174         GLint result;                                                                  \
175         glGetIntegeri_v(enumValue, index, &result);                                    \
176         ASSERT_GL_NO_ERROR();                                                          \
177         stream << enumString + std::string(",") + std::to_string(result) << std::endl; \
178     }
179 
180 #define QUERY_AND_LOG_CAPABILITY(enum, stream) QUERY_HELPER(enum, #enum, stream)
181 
182 #define QUERY_AND_LOG_CAPABILITY_ARRAY(enum, size, stream) \
183     QUERY_ARRAY_HELPER(enum, #enum, size, stream)
184 
185 #define QUERY_AND_LOG_CAPABILITY_INDEXED(enum, index, stream) \
186     QUERY_INDEXED_HELPER(enum, #enum "[" #index "]", index, stream)
187 
LogGles2Capabilities(std::ostream & stream)188 static void LogGles2Capabilities(std::ostream &stream)
189 {
190     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, stream);
191     QUERY_AND_LOG_CAPABILITY(GL_MAX_CUBE_MAP_TEXTURE_SIZE, stream);
192     QUERY_AND_LOG_CAPABILITY(GL_MAX_FRAGMENT_UNIFORM_VECTORS, stream);
193     QUERY_AND_LOG_CAPABILITY(GL_MAX_RENDERBUFFER_SIZE, stream);
194     QUERY_AND_LOG_CAPABILITY(GL_MAX_TEXTURE_IMAGE_UNITS, stream);
195     QUERY_AND_LOG_CAPABILITY(GL_MAX_TEXTURE_SIZE, stream);
196     QUERY_AND_LOG_CAPABILITY(GL_MAX_VARYING_VECTORS, stream);
197     QUERY_AND_LOG_CAPABILITY(GL_MAX_VERTEX_ATTRIBS, stream);
198     QUERY_AND_LOG_CAPABILITY(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, stream);
199     QUERY_AND_LOG_CAPABILITY(GL_MAX_VERTEX_UNIFORM_VECTORS, stream);
200     constexpr int kMaxViewPortDimsReturnValuesSize = 2;
201     QUERY_AND_LOG_CAPABILITY_ARRAY(GL_MAX_VIEWPORT_DIMS, kMaxViewPortDimsReturnValuesSize, stream);
202     QUERY_AND_LOG_CAPABILITY(GL_NUM_COMPRESSED_TEXTURE_FORMATS, stream);
203     QUERY_AND_LOG_CAPABILITY(GL_NUM_SHADER_BINARY_FORMATS, stream);
204 }
205 
LogGles3Capabilities(std::ostream & stream)206 static void LogGles3Capabilities(std::ostream &stream)
207 {
208     QUERY_AND_LOG_CAPABILITY(GL_MAX_3D_TEXTURE_SIZE, stream);
209     QUERY_AND_LOG_CAPABILITY(GL_MAX_ARRAY_TEXTURE_LAYERS, stream);
210     QUERY_AND_LOG_CAPABILITY(GL_MAX_COLOR_ATTACHMENTS, stream);
211     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS, stream);
212     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMBINED_UNIFORM_BLOCKS, stream);
213     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS, stream);
214     QUERY_AND_LOG_CAPABILITY(GL_MAX_DRAW_BUFFERS, stream);
215     QUERY_AND_LOG_CAPABILITY(GL_MAX_ELEMENT_INDEX, stream);
216     QUERY_AND_LOG_CAPABILITY(GL_MAX_ELEMENTS_INDICES, stream);
217     QUERY_AND_LOG_CAPABILITY(GL_MAX_ELEMENTS_VERTICES, stream);
218     QUERY_AND_LOG_CAPABILITY(GL_MAX_FRAGMENT_INPUT_COMPONENTS, stream);
219     QUERY_AND_LOG_CAPABILITY(GL_MAX_FRAGMENT_UNIFORM_BLOCKS, stream);
220     QUERY_AND_LOG_CAPABILITY(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, stream);
221     QUERY_AND_LOG_CAPABILITY(GL_MAX_PROGRAM_TEXEL_OFFSET, stream);
222     QUERY_AND_LOG_CAPABILITY(GL_MAX_SAMPLES, stream);
223     QUERY_AND_LOG_CAPABILITY(GL_MAX_SERVER_WAIT_TIMEOUT, stream);
224     QUERY_AND_LOG_CAPABILITY(GL_MAX_TEXTURE_LOD_BIAS, stream);
225     QUERY_AND_LOG_CAPABILITY(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, stream);
226     QUERY_AND_LOG_CAPABILITY(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, stream);
227     QUERY_AND_LOG_CAPABILITY(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, stream);
228     QUERY_AND_LOG_CAPABILITY(GL_MAX_UNIFORM_BLOCK_SIZE, stream);
229     QUERY_AND_LOG_CAPABILITY(GL_MAX_UNIFORM_BUFFER_BINDINGS, stream);
230     QUERY_AND_LOG_CAPABILITY(GL_MAX_VARYING_COMPONENTS, stream);
231     QUERY_AND_LOG_CAPABILITY(GL_MAX_VERTEX_OUTPUT_COMPONENTS, stream);
232     QUERY_AND_LOG_CAPABILITY(GL_MAX_VERTEX_UNIFORM_BLOCKS, stream);
233     QUERY_AND_LOG_CAPABILITY(GL_MAX_VERTEX_UNIFORM_COMPONENTS, stream);
234     QUERY_AND_LOG_CAPABILITY(GL_MIN_PROGRAM_TEXEL_OFFSET, stream);
235     QUERY_AND_LOG_CAPABILITY(GL_NUM_PROGRAM_BINARY_FORMATS, stream);
236     // GLES3 capabilities are a superset of GLES2
237     LogGles2Capabilities(stream);
238 }
239 
LogGles31Capabilities(std::ostream & stream)240 static void LogGles31Capabilities(std::ostream &stream)
241 {
242     QUERY_AND_LOG_CAPABILITY(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, stream);
243     QUERY_AND_LOG_CAPABILITY(GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE, stream);
244     QUERY_AND_LOG_CAPABILITY(GL_MAX_COLOR_TEXTURE_SAMPLES, stream);
245     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS, stream);
246     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMBINED_ATOMIC_COUNTERS, stream);
247     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS, stream);
248     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMBINED_IMAGE_UNIFORMS, stream);
249     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES, stream);
250     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, stream);
251     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS, stream);
252     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMPUTE_ATOMIC_COUNTERS, stream);
253     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMPUTE_IMAGE_UNIFORMS, stream);
254     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS, stream);
255     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMPUTE_SHARED_MEMORY_SIZE, stream);
256     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS, stream);
257     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMPUTE_UNIFORM_BLOCKS, stream);
258     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMPUTE_UNIFORM_COMPONENTS, stream);
259     QUERY_AND_LOG_CAPABILITY_INDEXED(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 0, stream);
260     QUERY_AND_LOG_CAPABILITY_INDEXED(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 1, stream);
261     QUERY_AND_LOG_CAPABILITY_INDEXED(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 2, stream);
262     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS, stream);
263     QUERY_AND_LOG_CAPABILITY_INDEXED(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0, stream);
264     QUERY_AND_LOG_CAPABILITY_INDEXED(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 1, stream);
265     QUERY_AND_LOG_CAPABILITY_INDEXED(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 2, stream);
266     QUERY_AND_LOG_CAPABILITY(GL_MAX_DEPTH_TEXTURE_SAMPLES, stream);
267     QUERY_AND_LOG_CAPABILITY(GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS, stream);
268     QUERY_AND_LOG_CAPABILITY(GL_MAX_FRAGMENT_ATOMIC_COUNTERS, stream);
269     QUERY_AND_LOG_CAPABILITY(GL_MAX_FRAGMENT_IMAGE_UNIFORMS, stream);
270     QUERY_AND_LOG_CAPABILITY(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, stream);
271     QUERY_AND_LOG_CAPABILITY(GL_MAX_FRAMEBUFFER_HEIGHT, stream);
272     QUERY_AND_LOG_CAPABILITY(GL_MAX_FRAMEBUFFER_SAMPLES, stream);
273     QUERY_AND_LOG_CAPABILITY(GL_MAX_FRAMEBUFFER_WIDTH, stream);
274     QUERY_AND_LOG_CAPABILITY(GL_MAX_IMAGE_UNITS, stream);
275     QUERY_AND_LOG_CAPABILITY(GL_MAX_INTEGER_SAMPLES, stream);
276     QUERY_AND_LOG_CAPABILITY(GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET, stream);
277     QUERY_AND_LOG_CAPABILITY(GL_MAX_SAMPLE_MASK_WORDS, stream);
278     QUERY_AND_LOG_CAPABILITY(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, stream);
279     QUERY_AND_LOG_CAPABILITY(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, stream);
280     QUERY_AND_LOG_CAPABILITY(GL_MAX_UNIFORM_LOCATIONS, stream);
281     QUERY_AND_LOG_CAPABILITY(GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS, stream);
282     QUERY_AND_LOG_CAPABILITY(GL_MAX_VERTEX_ATOMIC_COUNTERS, stream);
283     QUERY_AND_LOG_CAPABILITY(GL_MAX_VERTEX_ATTRIB_BINDINGS, stream);
284     QUERY_AND_LOG_CAPABILITY(GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET, stream);
285     QUERY_AND_LOG_CAPABILITY(GL_MAX_VERTEX_ATTRIB_STRIDE, stream);
286     QUERY_AND_LOG_CAPABILITY(GL_MAX_VERTEX_IMAGE_UNIFORMS, stream);
287     QUERY_AND_LOG_CAPABILITY(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, stream);
288     QUERY_AND_LOG_CAPABILITY(GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET, stream);
289 
290     // GLES31 capabilities are a superset of GLES3
291     LogGles3Capabilities(stream);
292 }
293 
LogGles32Capabilities(std::ostream & stream)294 static void LogGles32Capabilities(std::ostream &stream)
295 {
296     // Most of these capabilities are not implemented yet.
297     ANGLE_SKIP_TEST_IF(IsVulkan());
298 
299     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS, stream);
300     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS, stream);
301     QUERY_AND_LOG_CAPABILITY(GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS, stream);
302     QUERY_AND_LOG_CAPABILITY(GL_MAX_DEBUG_GROUP_STACK_DEPTH, stream);
303     QUERY_AND_LOG_CAPABILITY(GL_MAX_DEBUG_LOGGED_MESSAGES, stream);
304     QUERY_AND_LOG_CAPABILITY(GL_MAX_DEBUG_MESSAGE_LENGTH, stream);
305     QUERY_AND_LOG_CAPABILITY(GL_MAX_FRAGMENT_INTERPOLATION_OFFSET, stream);
306     QUERY_AND_LOG_CAPABILITY(GL_MAX_FRAMEBUFFER_LAYERS, stream);
307     QUERY_AND_LOG_CAPABILITY(GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS, stream);
308     QUERY_AND_LOG_CAPABILITY(GL_MAX_GEOMETRY_ATOMIC_COUNTERS, stream);
309     QUERY_AND_LOG_CAPABILITY(GL_MAX_GEOMETRY_IMAGE_UNIFORMS, stream);
310     QUERY_AND_LOG_CAPABILITY(GL_MAX_GEOMETRY_INPUT_COMPONENTS, stream);
311     QUERY_AND_LOG_CAPABILITY(GL_MAX_GEOMETRY_OUTPUT_COMPONENTS, stream);
312     QUERY_AND_LOG_CAPABILITY(GL_MAX_GEOMETRY_OUTPUT_VERTICES, stream);
313     QUERY_AND_LOG_CAPABILITY(GL_MAX_GEOMETRY_SHADER_INVOCATIONS, stream);
314     QUERY_AND_LOG_CAPABILITY(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, stream);
315     QUERY_AND_LOG_CAPABILITY(GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, stream);
316     QUERY_AND_LOG_CAPABILITY(GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS, stream);
317     QUERY_AND_LOG_CAPABILITY(GL_MAX_GEOMETRY_UNIFORM_BLOCKS, stream);
318     QUERY_AND_LOG_CAPABILITY(GL_MAX_GEOMETRY_UNIFORM_COMPONENTS, stream);
319     QUERY_AND_LOG_CAPABILITY(GL_MAX_LABEL_LENGTH, stream);
320     QUERY_AND_LOG_CAPABILITY(GL_MAX_PATCH_VERTICES, stream);
321     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS, stream);
322     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS, stream);
323     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS, stream);
324     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_CONTROL_INPUT_COMPONENTS, stream);
325     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS, stream);
326     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, stream);
327     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS, stream);
328     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS, stream);
329     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS, stream);
330     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS, stream);
331     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS, stream);
332     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS, stream);
333     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS, stream);
334     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS, stream);
335     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS, stream);
336     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, stream);
337     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS, stream);
338     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS, stream);
339     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS, stream);
340     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_GEN_LEVEL, stream);
341     QUERY_AND_LOG_CAPABILITY(GL_MAX_TESS_PATCH_COMPONENTS, stream);
342     QUERY_AND_LOG_CAPABILITY(GL_MAX_TEXTURE_BUFFER_SIZE, stream);
343     QUERY_AND_LOG_CAPABILITY(GL_MIN_FRAGMENT_INTERPOLATION_OFFSET, stream);
344     QUERY_AND_LOG_CAPABILITY(GL_MIN_SAMPLE_SHADING_VALUE, stream);
345 
346     // GLES32 capabilities are a superset of GLES31
347     LogGles31Capabilities(stream);
348 }
349 
350 // Prints GLES Capabilities listed at
351 // https://opengles.gpuinfo.org/listcapabilities.php
352 // in CSV format
TEST_P(EGLPrintEGLinfoTest,PrintGLESCapabilities)353 TEST_P(EGLPrintEGLinfoTest, PrintGLESCapabilities)
354 {
355     std::cout << std::endl << "Capability name, value" << std::endl << std::endl;
356 
357     std::ostream &stream = std::cout;
358 
359     switch (getClientMajorVersion())
360     {
361         case 1:
362             break;
363         case 2:
364             LogGles2Capabilities(stream);
365             break;
366         case 3:
367             switch (getClientMinorVersion())
368             {
369                 case 2:
370                     LogGles32Capabilities(stream);
371                     break;
372                 case 1:
373                     LogGles31Capabilities(stream);
374                     break;
375                 case 0:
376                     LogGles3Capabilities(stream);
377                     break;
378                 default:
379                     FAIL() << "unknown client minor version.";
380             }
381             break;
382         default:
383             FAIL() << "unknown client major version.";
384     }
385 
386     stream << std::endl;
387 }
388 
389 // Print the EGL configs with attributes
TEST_P(EGLPrintEGLinfoTest,PrintConfigInfo)390 TEST_P(EGLPrintEGLinfoTest, PrintConfigInfo)
391 {
392     // Get all the configs
393     EGLint count;
394     EXPECT_EGL_TRUE(eglGetConfigs(mDisplay, nullptr, 0, &count));
395     EXPECT_TRUE(count > 0);
396     std::vector<EGLConfig> configs(count);
397     EXPECT_EGL_TRUE(eglGetConfigs(mDisplay, configs.data(), count, &count));
398     configs.resize(count);
399     // sort configs by increaing ID
400     std::sort(configs.begin(), configs.end(), [this](EGLConfig a, EGLConfig b) -> bool {
401         return GetAttrib(mDisplay, a, EGL_CONFIG_ID) < GetAttrib(mDisplay, b, EGL_CONFIG_ID);
402     });
403 
404     std::cout << "Configs - Count: " << count << std::endl;
405 
406     // For each config, print its attributes
407     for (auto config : configs)
408     {
409         // Config ID
410         std::cout << "    Config: " << GetAttrib(mDisplay, config, EGL_CONFIG_ID) << std::endl;
411 
412         // Color
413         const char *componentType = (GetAttrib(mDisplay, config, EGL_COLOR_COMPONENT_TYPE_EXT) ==
414                                      EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT)
415                                         ? "Float "
416                                         : "Fixed ";
417         const char *colorBuffType =
418             (GetAttrib(mDisplay, config, EGL_COLOR_BUFFER_TYPE) == EGL_LUMINANCE_BUFFER)
419                 ? "LUMINANCE"
420                 : "RGB";
421         std::cout << "\tColor:" << GetAttrib(mDisplay, config, EGL_BUFFER_SIZE) << "bit "
422                   << componentType << colorBuffType
423                   << " Red:" << GetAttrib(mDisplay, config, EGL_RED_SIZE)
424                   << " Green:" << GetAttrib(mDisplay, config, EGL_GREEN_SIZE)
425                   << " Blue:" << GetAttrib(mDisplay, config, EGL_BLUE_SIZE)
426                   << " Alpha:" << GetAttrib(mDisplay, config, EGL_ALPHA_SIZE)
427                   << " Lum:" << GetAttrib(mDisplay, config, EGL_LUMINANCE_SIZE)
428                   << " AlphaMask:" << GetAttrib(mDisplay, config, EGL_ALPHA_MASK_SIZE) << std::endl;
429 
430         // Texture Binding
431         std::cout << "\tBinding RGB:" << (bool)GetAttrib(mDisplay, config, EGL_BIND_TO_TEXTURE_RGB)
432                   << " RGBA:" << (bool)GetAttrib(mDisplay, config, EGL_BIND_TO_TEXTURE_RGBA)
433                   << " MaxWidth:" << GetAttrib(mDisplay, config, EGL_MAX_PBUFFER_WIDTH)
434                   << " MaxHeight:" << GetAttrib(mDisplay, config, EGL_MAX_PBUFFER_HEIGHT)
435                   << " MaxPixels:" << GetAttrib(mDisplay, config, EGL_MAX_PBUFFER_PIXELS)
436                   << std::endl;
437 
438         // Conformant
439         EGLint caveatAttrib = GetAttrib(mDisplay, config, EGL_CONFIG_CAVEAT);
440         const char *caveat  = nullptr;
441         switch (caveatAttrib)
442         {
443             case EGL_NONE:
444                 caveat = "None.";
445                 break;
446             case EGL_SLOW_CONFIG:
447                 caveat = "Slow.";
448                 break;
449             case EGL_NON_CONFORMANT_CONFIG:
450                 caveat = "Non-Conformant.";
451                 break;
452             default:
453                 caveat = ".";
454         }
455         std::cout << "\tCaveate: " << caveat;
456 
457         EGLint conformant = GetAttrib(mDisplay, config, EGL_CONFORMANT);
458         std::cout << " Conformant: ";
459         if (conformant & EGL_OPENGL_BIT)
460             std::cout << "OpenGL ";
461         if (conformant & EGL_OPENGL_ES_BIT)
462             std::cout << "ES1 ";
463         if (conformant & EGL_OPENGL_ES2_BIT)
464             std::cout << "ES2 ";
465         if (conformant & EGL_OPENGL_ES3_BIT)
466             std::cout << "ES3";
467         std::cout << std::endl;
468 
469         // Ancilary buffers
470         std::cout << "\tAncilary "
471                   << "Depth:" << GetAttrib(mDisplay, config, EGL_DEPTH_SIZE)
472                   << " Stencil:" << GetAttrib(mDisplay, config, EGL_STENCIL_SIZE)
473                   << " SampleBuffs:" << GetAttrib(mDisplay, config, EGL_SAMPLE_BUFFERS)
474                   << " Samples:" << GetAttrib(mDisplay, config, EGL_SAMPLES) << std::endl;
475 
476         // Swap interval
477         std::cout << "\tSwap Interval"
478                   << " Min:" << GetAttrib(mDisplay, config, EGL_MIN_SWAP_INTERVAL)
479                   << " Max:" << GetAttrib(mDisplay, config, EGL_MAX_SWAP_INTERVAL) << std::endl;
480 
481         // Native
482         std::cout << "\tNative Renderable: " << GetAttrib(mDisplay, config, EGL_NATIVE_RENDERABLE)
483                   << ", VisualID: " << GetAttrib(mDisplay, config, EGL_NATIVE_VISUAL_ID)
484                   << ", VisualType: " << GetAttrib(mDisplay, config, EGL_NATIVE_VISUAL_TYPE)
485                   << std::endl;
486 
487         // Surface type
488         EGLint surfaceType = GetAttrib(mDisplay, config, EGL_SURFACE_TYPE);
489         std::cout << "\tSurface Type: ";
490         if (surfaceType & EGL_WINDOW_BIT)
491             std::cout << "WINDOW ";
492         if (surfaceType & EGL_PIXMAP_BIT)
493             std::cout << "PIXMAP ";
494         if (surfaceType & EGL_PBUFFER_BIT)
495             std::cout << "PBUFFER ";
496         if (surfaceType & EGL_MULTISAMPLE_RESOLVE_BOX_BIT)
497             std::cout << "MULTISAMPLE_RESOLVE_BOX ";
498         if (surfaceType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT)
499             std::cout << "SWAP_PRESERVE ";
500         std::cout << std::endl;
501 
502         // Renderable
503         EGLint rendType = GetAttrib(mDisplay, config, EGL_RENDERABLE_TYPE);
504         std::cout << "\tRender: ";
505         if (rendType & EGL_OPENGL_BIT)
506             std::cout << "OpenGL ";
507         if (rendType & EGL_OPENGL_ES_BIT)
508             std::cout << "ES1 ";
509         if (rendType & EGL_OPENGL_ES2_BIT)
510             std::cout << "ES2 ";
511         if (rendType & EGL_OPENGL_ES3_BIT)
512             std::cout << "ES3 ";
513         std::cout << std::endl;
514 
515         // Extensions
516         if (IsEGLDisplayExtensionEnabled(mDisplay, "EGL_ANDROID_recordable"))
517         {
518             std::cout << "\tAndroid Recordable: "
519                       << GetAttrib(mDisplay, config, EGL_RECORDABLE_ANDROID) << std::endl;
520         }
521         if (IsEGLDisplayExtensionEnabled(mDisplay, "EGL_ANDROID_framebuffer_target"))
522         {
523             std::cout << "\tAndroid framebuffer target: "
524                       << GetAttrib(mDisplay, config, EGL_FRAMEBUFFER_TARGET_ANDROID) << std::endl;
525         }
526 
527         // Separator between configs
528         std::cout << std::endl;
529     }
530 }
531 
532 ANGLE_INSTANTIATE_TEST(EGLPrintEGLinfoTest,
533                        ES1_VULKAN(),
534                        ES1_VULKAN_SWIFTSHADER(),
535                        ES2_VULKAN(),
536                        ES3_VULKAN(),
537                        ES32_VULKAN(),
538                        ES31_VULKAN_SWIFTSHADER());
539 
540 // This test suite is not instantiated on some OSes.
541 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EGLPrintEGLinfoTest);
542