179
int main (int argc, char* argv[]) {
180
int indirect = 0, print = 0, compiz = 0;
182
unsigned int flags = 0;
183
char* display_name = NULL;
189
char *vendor, *renderer, *version;
190
int result, major, minor;
192
if (getenv ("UNITY_FORCE_START")) {
193
fprintf (stdout, "Warning: UNITY_FORCE_START enabled, no check for unity or compiz support.\n");
198
// Basic command-line parsing.
199
for (int i = 1; i < argc; i++) {
200
if (((strncmp (argv[i], "-d", 2) == 0) ||
201
(strncmp (argv[i], "--display", 9) == 0)) &&
203
display_name = argv[i + 1];
205
} else if ((strncmp (argv[i], "-i", 2) == 0) ||
206
(strncmp (argv[i], "--indirect", 10) == 0)) {
208
} else if ((strncmp (argv[i], "-p", 2) == 0) ||
209
(strncmp (argv[i], "--print", 7) == 0)) {
211
} else if ((strncmp (argv[i], "-c", 2) == 0) ||
212
(strncmp (argv[i], "--compiz", 8) == 0)) {
214
} else if ((strncmp (argv[i], "-h", 2) == 0) ||
215
(strncmp (argv[i], "--help", 6) == 0)) {
219
fprintf (stderr, "Error: unknown command-line option `%s'\n\n", argv[i]);
225
// Open a X11 connection and get the root window.
226
display = XOpenDisplay (display_name);
227
if (display == NULL) {
228
error = "unable to open display";
232
screen = DefaultScreen (display);
233
root = XRootWindow (display, screen);
198
static int check_root_visual (Display *display,
202
XVisualInfo **vinfos,
203
TestResults *results)
235
205
// Retrieve root window visual.
236
206
XWindowAttributes attr;
237
207
XVisualInfo vinfo_template;
239
209
if (XGetWindowAttributes (display, root, &attr) == 0) {
240
error = "unable to get root window attributes";
210
results->error = strdup ("unable to get root window attributes");
244
214
vinfo_template.visualid = XVisualIDFromVisual (attr.visual);
245
vinfos = XGetVisualInfo (display, VisualIDMask, &vinfo_template, &nr_vinfos);
215
*vinfos = XGetVisualInfo (display, VisualIDMask, &vinfo_template, &nr_vinfos);
246
216
if (nr_vinfos == 0) {
247
error = "unable to get visual informations for default visual";
217
results->error = strdup ("unable to get visual informations for default visual");
225
static int check_xcomposite (Display *display,
229
XVisualInfo **vinfos,
230
TestResults *results)
232
// Check for XComposite
233
int composite_major, composite_minor;
234
unsigned int composite_tmp;
236
if (!XQueryExtension (display, COMPOSITE_NAME, &composite_tmp, &composite_tmp, &composite_tmp))
238
results->error = strdup ("no composite extension");
243
XCompositeQueryVersion (display, &composite_major, &composite_minor);
245
if (composite_major == 0 && composite_minor < 2)
247
results->error = strdup ("old composite extension");
255
static int check_damage_extension (Display *display,
259
XVisualInfo **vinfos,
260
TestResults *results)
264
if (!XDamageQueryExtension (display, &damage_tmp, &damage_tmp))
266
results->error = strdup ("no damage extension");
274
static int check_fixes_extension (Display *display,
278
XVisualInfo **vinfos,
279
TestResults *results)
283
if (!XFixesQueryExtension (display, &fixes_tmp, &fixes_tmp))
285
results->error = strdup ("no fixes extension");
293
static int check_glx_config (Display *display,
297
XVisualInfo **vinfos,
298
TestResults *results)
252
300
// Check root window visual capabilities.
254
glXGetConfig (display, vinfos, GLX_USE_GL, &value);
256
error = "OpenGL rendering is not supported by the root visual";
260
glXGetConfig (display, vinfos, GLX_DOUBLEBUFFER, &value);
262
error = "color buffers of the root visual are not double-buffered";
302
glXGetConfig (display, *vinfos, GLX_USE_GL, &value);
304
results->error = strdup ("OpenGL rendering is not supported by the root visual");
312
static int check_colorbuffers (Display *display,
316
XVisualInfo **vinfos,
317
TestResults *results)
320
glXGetConfig (display,*vinfos, GLX_DOUBLEBUFFER, &value);
322
results->error = strdup ("color buffers of the root visual are not double-buffered");
330
static int check_context (Display *display,
334
XVisualInfo **vinfos,
335
TestResults *results)
267
337
// Create and map the OpenGL context to the root window and get the strings.
268
context = glXCreateContext (display, vinfos, NULL, !indirect);
269
if (context == NULL) {
270
error = "unable to create the OpenGL context";
274
glXMakeCurrent (display, root, context);
275
vendor = (char*) glGetString (GL_VENDOR);
276
renderer = (char*) glGetString (GL_RENDERER);
277
version = (char*) glGetString (GL_VERSION);
279
// Fill flags with the supported GLX extensions.
280
const char* glx_extensions = glXQueryExtensionsString (display, screen);
281
const struct { const char* name; const unsigned int flag; } glx_extension[] = {
282
{ "GLX_SGIX_fbconfig", FLAG_GLX_SGIX_FBCONFIG },
283
{ "GLX_EXT_texture_from_pixmap", FLAG_GLX_EXT_TEXTURE_FROM_PIXMAP },
286
for (int i = 0; glx_extension[i].name != NULL; i++)
287
if (is_extension_supported (glx_extensions, glx_extension[i].name) == 1)
288
flags |= glx_extension[i].flag;
289
if (flags & FLAG_GLX_SGIX_FBCONFIG) {
290
if (glXGetProcAddressARB ("glXQueryDrawable") == NULL ||
291
glXGetProcAddressARB ("glXGetFBConfigs") == NULL ||
292
glXGetProcAddressARB ("glXGetFBConfigAttrib") == NULL ||
293
glXGetProcAddressARB ("glXCreatePixmap") == NULL ||
294
glXGetProcAddressARB ("glXDestroyPixmap") == NULL) {
295
flags &= ~FLAG_GLX_SGIX_FBCONFIG;
298
if (flags & FLAG_GLX_EXT_TEXTURE_FROM_PIXMAP) {
299
if (glXGetProcAddressARB ("glXBindTexImageEXT") == NULL ||
300
glXGetProcAddressARB ("glXReleaseTexImageEXT") == NULL) {
301
flags &= ~FLAG_GLX_EXT_TEXTURE_FROM_PIXMAP;
338
*context = glXCreateContext (display, *vinfos, NULL, !results->indirect);
339
if (*context == NULL) {
340
results->error = strdup ("unable to create the OpenGL context");
344
glXMakeCurrent (display, root, *context);
345
results->vendor = (char*) glGetString (GL_VENDOR);
346
results->renderer = (char*) glGetString (GL_RENDERER);
347
results->version = (char*) glGetString (GL_VERSION);
352
static int check_extensions (Display *display,
356
XVisualInfo **vinfos,
357
TestResults *results)
305
359
// Fill flags with the supported OpenGL extensions.
306
360
const char* gl_extensions = glGetString (GL_EXTENSIONS);
307
361
if (gl_extensions == NULL) {
308
error = "invalid OpenGL extensions string";
362
results->error = strdup ("invalid OpenGL extensions string");
312
366
const struct { const char* name; const unsigned int flag; } gl_extension[] = {
313
367
{ "GL_ARB_texture_non_power_of_two", FLAG_GL_ARB_NON_POWER_OF_TWO },
324
378
for (int i = 0; gl_extension[i].name != NULL; i++)
325
379
if (is_extension_supported (gl_extensions, gl_extension[i].name) == 1)
326
flags |= gl_extension[i].flag;
380
results->flags |= gl_extension[i].flag;
382
// Fill results->flags with the supported GLX extensions.
383
const char* glx_extensions = glXQueryExtensionsString (display, screen);
384
const struct { const char* name; const unsigned int flag; } glx_extension[] = {
385
{ "GLX_SGIX_fbconfig", FLAG_GLX_SGIX_FBCONFIG },
386
{ "GLX_EXT_texture_from_pixmap", FLAG_GLX_EXT_TEXTURE_FROM_PIXMAP },
389
for (int i = 0; glx_extension[i].name != NULL; i++)
390
if (is_extension_supported (glx_extensions, glx_extension[i].name) == 1)
391
results->flags |= glx_extension[i].flag;
392
if (results->flags & FLAG_GLX_SGIX_FBCONFIG) {
393
if (glXGetProcAddressARB ("glXQueryDrawable") == NULL ||
394
glXGetProcAddressARB ("glXGetFBConfigs") == NULL ||
395
glXGetProcAddressARB ("glXGetFBConfigAttrib") == NULL ||
396
glXGetProcAddressARB ("glXCreatePixmap") == NULL ||
397
glXGetProcAddressARB ("glXDestroyPixmap") == NULL) {
398
results->flags &= ~FLAG_GLX_SGIX_FBCONFIG;
401
if (results->flags & FLAG_GLX_EXT_TEXTURE_FROM_PIXMAP) {
402
if (glXGetProcAddressARB ("glXBindTexImageEXT") == NULL ||
403
glXGetProcAddressARB ("glXReleaseTexImageEXT") == NULL) {
404
results->flags &= ~FLAG_GLX_EXT_TEXTURE_FROM_PIXMAP;
411
static int check_blacklist (Display *display,
415
XVisualInfo **vinfos,
416
TestResults *results)
328
418
// Check for software rendering.
329
if (renderer != NULL &&
330
(strncmp (renderer, "Software Rasterizer", 19) == 0 ||
331
strncmp (renderer, "Mesa X11", 8) == 0)) {
332
flags |= FLAG_SOFTWARE_RENDERING;
419
if (results->renderer != NULL &&
420
(strncmp (results->renderer, "Software Rasterizer", 19) == 0 ||
421
strncmp (results->renderer, "Mesa X11", 8) == 0)) {
422
results->flags |= FLAG_SOFTWARE_RENDERING;
335
425
// jaytaoko: Balcklist the Geforce FX cards
336
if (renderer != NULL) {
337
char* str = strstr (renderer, "GeForce FX");
426
if (results->renderer != NULL) {
427
char* str = strstr (results->renderer, "GeForce FX");
338
428
if (str != NULL) {
339
flags |= FLAG_BLACKLISTED;
429
results->flags |= FLAG_BLACKLISTED;
356
446
for (int i = 0; i < gpu_blacklist_size; i++) {
357
447
if (dev->vendor_id == gpu_blacklist[i].vendor &&
358
448
dev->device_id == gpu_blacklist[i].device) {
359
flags |= FLAG_BLACKLISTED;
449
results->flags |= FLAG_BLACKLISTED;
364
454
pci_cleanup (access);
367
// Unity compatibility checks.
368
get_opengl_version (version, &major, &minor);
369
if ((major >= 2 || (major == 1 && minor >= 4)) &&
370
(flags & FLAG_GLX_SGIX_FBCONFIG) &&
371
(flags & FLAG_GLX_EXT_TEXTURE_FROM_PIXMAP) &&
372
(flags & MASK_GL_NON_POWER_OF_TWO) &&
373
(flags & FLAG_GL_ARB_VERTEX_PROGRAM) &&
374
(flags & FLAG_GL_ARB_FRAGMENT_PROGRAM) &&
375
(flags & FLAG_GL_ARB_VERTEX_BUFFER_OBJECT) &&
376
(flags & MASK_GL_FRAMEBUFFER_OBJECT) &&
377
(~flags & FLAG_SOFTWARE_RENDERING) &&
378
(~flags & FLAG_BLACKLISTED)) {
384
// Compiz compatibility checks.
385
if ((flags & FLAG_GLX_SGIX_FBCONFIG) &&
386
(flags & FLAG_GLX_EXT_TEXTURE_FROM_PIXMAP) &&
387
(flags & MASK_GL_NON_POWER_OF_TWO) &&
388
(~flags & FLAG_SOFTWARE_RENDERING) &&
389
(~flags & FLAG_BLACKLISTED)) {
459
int (*tests[]) (Display *display,
463
XVisualInfo **vinfos,
464
TestResults *results) = {
467
check_damage_extension,
468
check_fixes_extension,
476
const unsigned int c_num_tests = 9;
478
int main (int argc, char* argv[]) {
479
char *display_name = NULL;
481
unsigned int print = 0;
483
XVisualInfo *vinfos = NULL;
484
Display *display = NULL;
485
GLXContext context = NULL;
488
results.indirect = 0;
491
results.error = NULL;
494
if (getenv ("UNITY_FORCE_START")) {
495
fprintf (stdout, "Warning: UNITY_FORCE_START enabled, no check for unity or compiz support.\n");
499
// Basic command-line parsing.
500
for (int i = 1; i < argc; i++) {
501
if (((strncmp (argv[i], "-d", 2) == 0) ||
502
(strncmp (argv[i], "--display", 9) == 0)) &&
504
display_name = argv[i + 1];
506
} else if ((strncmp (argv[i], "-i", 2) == 0) ||
507
(strncmp (argv[i], "--indirect", 10) == 0)) {
508
results.indirect = 1;
509
} else if ((strncmp (argv[i], "-p", 2) == 0) ||
510
(strncmp (argv[i], "--print", 7) == 0)) {
512
} else if ((strncmp (argv[i], "-c", 2) == 0) ||
513
(strncmp (argv[i], "--compiz", 8) == 0)) {
515
} else if ((strncmp (argv[i], "-h", 2) == 0) ||
516
(strncmp (argv[i], "--help", 6) == 0)) {
520
fprintf (stderr, "Error: unknown command-line option `%s'\n\n", argv[i]);
526
// Open a X11 connection and get the root window.
527
display = XOpenDisplay (display_name);
528
if (display == NULL) {
529
results.error = strdup ("unable to open display");
534
screen = DefaultScreen (display);
535
root = XRootWindow (display, screen);
537
// Do the tests, if one of them fails break out of the loop
539
for (unsigned int i = 0; i < c_num_tests; i++)
540
if (!(*tests[i]) (display, screen, root, &context, &vinfos, &results))
543
if (results.compiz == 0) {
544
// Unity compatibility checks.
545
get_opengl_version (results.version, &results.major, &results.minor);
546
if ((results.major >= 2 || (results.major == 1 && results.minor >= 4)) &&
547
(results.flags & FLAG_GLX_SGIX_FBCONFIG) &&
548
(results.flags & FLAG_GLX_EXT_TEXTURE_FROM_PIXMAP) &&
549
(results.flags & MASK_GL_NON_POWER_OF_TWO) &&
550
(results.flags & FLAG_GL_ARB_VERTEX_PROGRAM) &&
551
(results.flags & FLAG_GL_ARB_FRAGMENT_PROGRAM) &&
552
(results.flags & FLAG_GL_ARB_VERTEX_BUFFER_OBJECT) &&
553
(results.flags & MASK_GL_FRAMEBUFFER_OBJECT) &&
554
(~results.flags & FLAG_SOFTWARE_RENDERING) &&
555
(~results.flags & FLAG_BLACKLISTED)) {
561
// Compiz compatibility checks.
562
if ((results.flags & FLAG_GLX_SGIX_FBCONFIG) &&
563
(results.flags & FLAG_GLX_EXT_TEXTURE_FROM_PIXMAP) &&
564
(results.flags & MASK_GL_NON_POWER_OF_TWO) &&
565
(~results.flags & FLAG_SOFTWARE_RENDERING) &&
566
(~results.flags & FLAG_BLACKLISTED)) {
398
574
if (print == 1) {
399
print_report (vendor, renderer, version, major, minor, flags, compiz,
575
print_report (results.vendor, results.renderer,
576
results.version, results.major,
577
results.minor, results.flags,
578
results.compiz, results.result, results.error);
403
581
if (vinfos != NULL)