VirtualBox

source: vbox/trunk/src/VBox/Main/src-helper-apps/OpenGLTest/OpenGLTestApp.cpp@ 90862

Last change on this file since 90862 was 90862, checked in by vboxsync, 3 years ago

IPRT,SUPDrv,VMM,++: Bumped major support driver version. Added RTLogSetR0ProgramStart and make the VMM use it when configuring the ring-0 loggers. Removed pfnFlush from the parameter list of RTLogCreateEx[V]. bugref:10086

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 14.5 KB
Line 
1/* $Id: OpenGLTestApp.cpp 90862 2021-08-25 00:37:59Z vboxsync $ */
2/** @file
3 * VBox host opengl support test application.
4 */
5
6/*
7 * Copyright (C) 2009-2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#include <iprt/assert.h>
19#include <iprt/buildconfig.h>
20#include <iprt/errcore.h>
21#include <iprt/getopt.h>
22#include <iprt/initterm.h>
23#include <iprt/ldr.h>
24#include <iprt/stream.h>
25#ifdef RT_OS_WINDOWS
26# include <iprt/win/windows.h>
27#endif
28#if !defined(RT_OS_WINDOWS) && !defined(RT_OS_OS2)
29# include <sys/resource.h>
30# include <fcntl.h>
31# include <unistd.h>
32#endif
33
34#include <string.h>
35
36#define VBOXGLTEST_WITH_LOGGING /** @todo r=andy Is this intentional? */
37
38#ifdef VBOXGLTEST_WITH_LOGGING
39# include "package-generated.h"
40
41# include <iprt/log.h>
42# include <iprt/param.h>
43# include <iprt/time.h>
44# include <iprt/system.h>
45# include <iprt/process.h>
46# include <iprt/env.h>
47
48# include <VBox/log.h>
49# include <VBox/version.h>
50#endif /* VBOXGLTEST_WITH_LOGGING */
51
52#ifdef VBOX_WITH_VIDEOHWACCEL
53# include <QGLWidget>
54# include <QApplication>
55# include <VBox/VBoxGL2D.h>
56#endif
57
58#ifndef RT_OS_WINDOWS
59# include <GL/gl.h> /* For GLubyte and friends. */
60#endif
61
62/**
63 * The OpenGL methods to look for when checking 3D presence.
64 */
65static const char * const g_apszOglMethods[] =
66{
67#ifdef RT_OS_WINDOWS
68 "wglCreateContext",
69 "wglDeleteContext",
70 "wglMakeCurrent",
71 "wglShareLists",
72#elif defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD) || defined(RT_OS_SOLARIS)
73 "glXQueryVersion",
74 "glXChooseVisual",
75 "glXCreateContext",
76 "glXMakeCurrent",
77 "glXDestroyContext",
78#endif
79 "glAlphaFunc",
80 "glBindTexture",
81 "glBlendFunc",
82 "glClear",
83 "glClearColor",
84 "glClearDepth",
85 "glClearStencil",
86 "glClipPlane",
87 "glColorMask",
88 "glColorPointer",
89 "glCullFace",
90 "glDeleteTextures",
91 "glDepthFunc",
92 "glDepthMask",
93 "glDepthRange",
94 "glDisable",
95 "glDisableClientState",
96 "glDrawArrays",
97 "glDrawElements",
98 "glEnable",
99 "glEnableClientState",
100 "glFogf",
101 "glFogfv",
102 "glFogi",
103 "glFrontFace",
104 "glGenTextures",
105 "glGetBooleanv",
106 "glGetError",
107 "glGetFloatv",
108 "glGetIntegerv",
109 "glGetString",
110 "glGetTexImage",
111 "glLightModelfv",
112 "glLightf",
113 "glLightfv",
114 "glLineWidth",
115 "glLoadIdentity",
116 "glLoadMatrixf",
117 "glMaterialfv",
118 "glMatrixMode",
119 "glMultMatrixf",
120 "glNormalPointer",
121 "glPixelStorei",
122 "glPointSize",
123 "glPolygonMode",
124 "glPolygonOffset",
125 "glPopAttrib",
126 "glPopMatrix",
127 "glPushAttrib",
128 "glPushMatrix",
129 "glScissor",
130 "glShadeModel",
131 "glStencilFunc",
132 "glStencilMask",
133 "glStencilOp",
134 "glTexCoordPointer",
135 "glTexImage2D",
136 "glTexParameterf",
137 "glTexParameterfv",
138 "glTexParameteri",
139 "glTexSubImage2D",
140 "glVertexPointer",
141 "glViewport"
142};
143
144
145/**
146 * Tries to resolve the given OpenGL symbol.
147 *
148 * @returns Pointer to the symbol or nULL on error.
149 * @param pszSymbol The symbol to resolve.
150 */
151DECLINLINE(PFNRT) vboxTestOglGetProc(const char *pszSymbol)
152{
153 int rc;
154
155#ifdef RT_OS_WINDOWS
156 static RTLDRMOD s_hOpenGL32 = NULL;
157 if (s_hOpenGL32 == NULL)
158 {
159 rc = RTLdrLoadSystem("opengl32", /* fNoUnload = */ true, &s_hOpenGL32);
160 if (RT_FAILURE(rc))
161 s_hOpenGL32 = NULL;
162 }
163
164 typedef PROC (WINAPI *PFNWGLGETPROCADDRESS)(LPCSTR);
165 static PFNWGLGETPROCADDRESS s_wglGetProcAddress = NULL;
166 if (s_wglGetProcAddress == NULL)
167 {
168 if (s_hOpenGL32 != NULL)
169 {
170 rc = RTLdrGetSymbol(s_hOpenGL32, "wglGetProcAddress", (void **)&s_wglGetProcAddress);
171 if (RT_FAILURE(rc))
172 s_wglGetProcAddress = NULL;
173 }
174 }
175
176 if (s_wglGetProcAddress)
177 {
178 /* Khronos: [on failure] "some implementations will return other values. 1, 2, and 3 are used, as well as -1". */
179 PFNRT p = (PFNRT)s_wglGetProcAddress(pszSymbol);
180 if (RT_VALID_PTR(p))
181 return p;
182
183 /* Might be an exported symbol. */
184 rc = RTLdrGetSymbol(s_hOpenGL32, pszSymbol, (void **)&p);
185 if (RT_SUCCESS(rc))
186 return p;
187 }
188#else /* The X11 gang */
189 static RTLDRMOD s_hGL = NULL;
190 if (s_hGL == NULL)
191 {
192 static const char s_szLibGL[] = "libGL.so.1";
193 rc = RTLdrLoadEx(s_szLibGL, &s_hGL, RTLDRLOAD_FLAGS_GLOBAL | RTLDRLOAD_FLAGS_NO_UNLOAD, NULL);
194 if (RT_FAILURE(rc))
195 {
196 s_hGL = NULL;
197 return NULL;
198 }
199 }
200
201 typedef PFNRT (* PFNGLXGETPROCADDRESS)(const GLubyte * procName);
202 static PFNGLXGETPROCADDRESS s_glXGetProcAddress = NULL;
203 if (s_glXGetProcAddress == NULL)
204 {
205 rc = RTLdrGetSymbol(s_hGL, "glXGetProcAddress", (void **)&s_glXGetProcAddress);
206 if (RT_FAILURE(rc))
207 {
208 s_glXGetProcAddress = NULL;
209 return NULL;
210 }
211 }
212
213 PFNRT p = s_glXGetProcAddress((const GLubyte *)pszSymbol);
214 if (RT_VALID_PTR(p))
215 return p;
216
217 /* Might be an exported symbol. */
218 rc = RTLdrGetSymbol(s_hGL, pszSymbol, (void **)&p);
219 if (RT_SUCCESS(rc))
220 return p;
221#endif
222
223 return NULL;
224}
225
226static int vboxCheck3DAccelerationSupported()
227{
228 LogRel(("Testing 3D Support:\n"));
229
230 for (uint32_t i = 0; i < RT_ELEMENTS(g_apszOglMethods); i++)
231 {
232 PFNRT pfn = vboxTestOglGetProc(g_apszOglMethods[i]);
233 if (!pfn)
234 {
235 LogRel(("Testing 3D Failed\n"));
236 return 1;
237 }
238 }
239
240 LogRel(("Testing 3D Succeeded!\n"));
241 return 0;
242}
243
244#ifdef VBOX_WITH_VIDEOHWACCEL
245static int vboxCheck2DVideoAccelerationSupported()
246{
247 LogRel(("Testing 2D Support:\n"));
248 static int dummyArgc = 1;
249 static char * dummyArgv = (char*)"GlTest";
250 QApplication app (dummyArgc, &dummyArgv);
251
252 VBoxGLTmpContext ctx;
253 const QGLContext *pContext = ctx.makeCurrent();
254 if(pContext)
255 {
256 VBoxVHWAInfo supportInfo;
257 supportInfo.init(pContext);
258 if(supportInfo.isVHWASupported())
259 {
260 LogRel(("Testing 2D Succeeded!\n"));
261 return 0;
262 }
263 }
264 else
265 {
266 LogRel(("Failed to create gl context\n"));
267 }
268 LogRel(("Testing 2D Failed\n"));
269 return 1;
270}
271#endif
272
273#ifdef VBOXGLTEST_WITH_LOGGING
274static int vboxInitLogging(const char *pszFilename, bool bGenNameSuffix)
275{
276 PRTLOGGER loggerRelease;
277 static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES;
278 RTUINT fFlags = RTLOGFLAGS_PREFIX_TIME_PROG;
279#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
280 fFlags |= RTLOGFLAGS_USECRLF;
281#endif
282 const char * pszFilenameFmt;
283 RTLOGDEST enmLogDest;
284 if(pszFilename)
285 {
286 if(bGenNameSuffix)
287 pszFilenameFmt = "%s.%ld.log";
288 else
289 pszFilenameFmt = "%s";
290 enmLogDest = RTLOGDEST_FILE;
291 }
292 else
293 {
294 pszFilenameFmt = NULL;
295 enmLogDest = RTLOGDEST_STDOUT;
296 }
297
298
299 int vrc = RTLogCreateEx(&loggerRelease, "VBOX_RELEASE_LOG", fFlags, "all", RT_ELEMENTS(s_apszGroups), s_apszGroups, UINT32_MAX,
300 0 /*cBufDescs*/, NULL /*paBufDescs*/, enmLogDest,
301 NULL /*pfnBeginEnd*/, 0 /*cHistory*/, 0 /*cbHistoryFileMax*/, 0 /*uHistoryTimeMax*/,
302 NULL /*pErrInfo*/, pszFilenameFmt, pszFilename, RTTimeMilliTS());
303 if (RT_SUCCESS(vrc))
304 {
305 /* some introductory information */
306 RTTIMESPEC timeSpec;
307 char szTmp[256];
308 RTTimeSpecToString(RTTimeNow(&timeSpec), szTmp, sizeof(szTmp));
309 RTLogRelLogger(loggerRelease, 0, ~0U,
310 "VBoxTestGL %s r%u %s (%s %s) release log\n"
311#ifdef VBOX_BLEEDING_EDGE
312 "EXPERIMENTAL build " VBOX_BLEEDING_EDGE "\n"
313#endif
314 "Log opened %s\n",
315 VBOX_VERSION_STRING, RTBldCfgRevision(), VBOX_BUILD_TARGET,
316 __DATE__, __TIME__, szTmp);
317
318 vrc = RTSystemQueryOSInfo(RTSYSOSINFO_PRODUCT, szTmp, sizeof(szTmp));
319 if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
320 RTLogRelLogger(loggerRelease, 0, ~0U, "OS Product: %s\n", szTmp);
321 vrc = RTSystemQueryOSInfo(RTSYSOSINFO_RELEASE, szTmp, sizeof(szTmp));
322 if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
323 RTLogRelLogger(loggerRelease, 0, ~0U, "OS Release: %s\n", szTmp);
324 vrc = RTSystemQueryOSInfo(RTSYSOSINFO_VERSION, szTmp, sizeof(szTmp));
325 if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
326 RTLogRelLogger(loggerRelease, 0, ~0U, "OS Version: %s\n", szTmp);
327 vrc = RTSystemQueryOSInfo(RTSYSOSINFO_SERVICE_PACK, szTmp, sizeof(szTmp));
328 if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
329 RTLogRelLogger(loggerRelease, 0, ~0U, "OS Service Pack: %s\n", szTmp);
330// RTLogRelLogger(loggerRelease, 0, ~0U, "Host RAM: %uMB RAM, available: %uMB\n",
331// uHostRamMb, uHostRamAvailMb);
332 /* the package type is interesting for Linux distributions */
333 char szExecName[RTPATH_MAX];
334 char *pszExecName = RTProcGetExecutablePath(szExecName, sizeof(szExecName));
335 RTLogRelLogger(loggerRelease, 0, ~0U,
336 "Executable: %s\n"
337 "Process ID: %u\n"
338 "Package type: %s"
339#ifdef VBOX_OSE
340 " (OSE)"
341#endif
342 "\n",
343 pszExecName ? pszExecName : "unknown",
344 RTProcSelf(),
345 VBOX_PACKAGE_STRING);
346
347 /* register this logger as the release logger */
348 RTLogRelSetDefaultInstance(loggerRelease);
349
350 return VINF_SUCCESS;
351 }
352
353 return vrc;
354}
355#endif
356
357static int vboxInitQuietMode()
358{
359#if !defined(RT_OS_WINDOWS) && !defined(RT_OS_OS2)
360 /* This small test application might crash on some hosts. Do never
361 * generate a core dump as most likely some OpenGL library is
362 * responsible. */
363 struct rlimit lim = { 0, 0 };
364 setrlimit(RLIMIT_CORE, &lim);
365
366 /* Redirect stderr to /dev/null */
367 int fd = open("/dev/null", O_WRONLY);
368 if (fd != -1)
369 dup2(fd, STDERR_FILENO);
370#endif
371 return 0;
372}
373
374int main(int argc, char **argv)
375{
376 int rc = 0;
377
378 RTR3InitExe(argc, &argv, 0);
379
380 if(argc < 2)
381 {
382 /* backwards compatibility: check 3D */
383 rc = vboxCheck3DAccelerationSupported();
384 }
385 else
386 {
387 static const RTGETOPTDEF s_aOptionDefs[] =
388 {
389 { "--test", 't', RTGETOPT_REQ_STRING },
390 { "-test", 't', RTGETOPT_REQ_STRING },
391#ifdef VBOXGLTEST_WITH_LOGGING
392 { "--log", 'l', RTGETOPT_REQ_STRING },
393#endif
394 };
395
396 RTGETOPTSTATE State;
397 rc = RTGetOptInit(&State, argc-1, argv+1, &s_aOptionDefs[0], RT_ELEMENTS(s_aOptionDefs), 0, 0);
398 AssertRCReturn(rc, 49);
399
400#ifdef VBOX_WITH_VIDEOHWACCEL
401 bool bTest2D = false;
402#endif
403 bool bTest3D = false;
404#ifdef VBOXGLTEST_WITH_LOGGING
405 bool bLog = false;
406 bool bLogSuffix = false;
407 const char * pLog = NULL;
408#endif
409
410 for (;;)
411 {
412 RTGETOPTUNION Val;
413 rc = RTGetOpt(&State, &Val);
414 if (!rc)
415 break;
416 switch (rc)
417 {
418 case 't':
419 if (!strcmp(Val.psz, "3D") || !strcmp(Val.psz, "3d"))
420 {
421 bTest3D = true;
422 rc = 0;
423 break;
424 }
425#ifdef VBOX_WITH_VIDEOHWACCEL
426 if (!strcmp(Val.psz, "2D") || !strcmp(Val.psz, "2d"))
427 {
428 bTest2D = true;
429 rc = 0;
430 break;
431 }
432#endif
433 rc = 1;
434 break;
435#ifdef VBOXGLTEST_WITH_LOGGING
436 case 'l':
437 bLog = true;
438 pLog = Val.psz;
439 rc = 0;
440 break;
441#endif
442 case 'h':
443 RTPrintf(VBOX_PRODUCT " Helper for testing 2D/3D OpenGL capabilities %u.%u.%u\n"
444 "(C) 2009-" VBOX_C_YEAR " " VBOX_VENDOR "\n"
445 "All rights reserved.\n"
446 "\n"
447 "Parameters:\n"
448#ifdef VBOX_WITH_VIDEOHWACCEL
449 " --test 2D test for 2D (video) OpenGL capabilities\n"
450#endif
451 " --test 3D test for 3D OpenGL capabilities\n"
452#ifdef VBOXGLTEST_WITH_LOGGING
453 " --log <log_file_name> log the GL test result to the given file\n"
454 "\n"
455 "Logging can alternatively be enabled by specifying the VBOXGLTEST_LOG=<log_file_name> env variable\n"
456
457#endif
458 "\n",
459 RTBldCfgVersionMajor(), RTBldCfgVersionMinor(), RTBldCfgVersionBuild());
460 break;
461
462 case 'V':
463 RTPrintf("$Revision: 90862 $\n");
464 return 0;
465
466 case VERR_GETOPT_UNKNOWN_OPTION:
467 case VINF_GETOPT_NOT_OPTION:
468 rc = 1;
469
470 default:
471 /* complain? RTGetOptPrintError(rc, &Val); */
472 break;
473 }
474
475 if (rc)
476 break;
477 }
478
479 if(!rc)
480 {
481#ifdef VBOXGLTEST_WITH_LOGGING
482 if(!bLog)
483 {
484 /* check the VBOXGLTEST_LOG env var */
485 pLog = RTEnvGet("VBOXGLTEST_LOG");
486 if(pLog)
487 bLog = true;
488 bLogSuffix = true;
489 }
490 if(bLog)
491 rc = vboxInitLogging(pLog, bLogSuffix);
492 else
493#endif
494 rc = vboxInitQuietMode();
495
496 if(!rc && bTest3D)
497 rc = vboxCheck3DAccelerationSupported();
498
499#ifdef VBOX_WITH_VIDEOHWACCEL
500 if(!rc && bTest2D)
501 rc = vboxCheck2DVideoAccelerationSupported();
502#endif
503
504 }
505 }
506
507 /*RTR3Term();*/
508 return rc;
509
510}
511
512#ifdef RT_OS_WINDOWS
513extern "C" int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
514{
515 RT_NOREF(hInstance, hPrevInstance, lpCmdLine, nShowCmd);
516 return main(__argc, __argv);
517}
518#endif
519
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette