/* * Copyright © 2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ /** @file glx-fbconfig-sanity.c * Verify that the list of fbconfigs conforms to GLX 1.4 section 3.3.3. * * This reproduces X.org bugzilla #34265, among much else. */ #include "piglit-util-gl.h" #include "piglit-glx-util.h" int piglit_width = 10; int piglit_height = 10; static PFNGLXGETFBCONFIGSPROC GetFBConfigs = NULL; static PFNGLXGETFBCONFIGATTRIBPROC GetFBConfigAttrib = NULL; static PFNGLXGETVISUALFROMFBCONFIGPROC GetVisualFromFBConfig = NULL; static void fbconfig_sanity_warn(int *result) { if (*result != PIGLIT_FAIL) *result = PIGLIT_WARN; } int main(int argc, char **argv) { Display *dpy; int i; int result = PIGLIT_PASS; GLXFBConfig *configs; int num_configs; dpy = XOpenDisplay(NULL); if (dpy == NULL) { fprintf(stderr, "couldn't open display\n"); piglit_report_result(PIGLIT_FAIL); } /* Test requires at least GLX version 1.3. Otherwise there is no * glXGetFBConfigs function. */ piglit_require_glx_version(dpy, 1, 3); piglit_require_glx_extension(dpy, "GLX_ARB_get_proc_address"); GetFBConfigs = (PFNGLXGETFBCONFIGSPROC) glXGetProcAddressARB((GLubyte *) "glXGetFBConfigs"); GetFBConfigAttrib = (PFNGLXGETFBCONFIGATTRIBPROC) glXGetProcAddressARB((GLubyte *) "glXGetFBConfigAttrib"); GetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC) glXGetProcAddressARB((GLubyte *) "glXGetVisualFromFBConfig"); configs = GetFBConfigs(dpy, DefaultScreen(dpy), &num_configs); /* Iterate over the list of fbconfigs. Check that each fbconfig that * has the GLX_WINDOW_BIT or GLX_PIXMAP_BIT set also has a non-zero * X visual. Also verify that glXGetVisualFromFBConfig returns NULL * if and only if the X visual is 0. */ for (i = 0; i < num_configs; i++) { int draw_type; int visual_id; int config_id; int sample_buffers; int render_type; int x_renderable; int caveat; int vtype; int transparency; XVisualInfo *vinfo; GetFBConfigAttrib(dpy, configs[i], GLX_FBCONFIG_ID, &config_id); GetFBConfigAttrib(dpy, configs[i], GLX_DRAWABLE_TYPE, &draw_type); GetFBConfigAttrib(dpy, configs[i], GLX_VISUAL_ID, &visual_id); GetFBConfigAttrib(dpy, configs[i], GLX_SAMPLE_BUFFERS, &sample_buffers); GetFBConfigAttrib(dpy, configs[i], GLX_RENDER_TYPE, &render_type); GetFBConfigAttrib(dpy, configs[i], GLX_X_RENDERABLE, &x_renderable); GetFBConfigAttrib(dpy, configs[i], GLX_CONFIG_CAVEAT, &caveat); GetFBConfigAttrib(dpy, configs[i], GLX_TRANSPARENT_TYPE, &transparency); GetFBConfigAttrib(dpy, configs[i], GLX_X_VISUAL_TYPE, &vtype); if (!draw_type) { fprintf(stderr, "FBConfig 0x%x supports no " "drawables\n", config_id); fbconfig_sanity_warn(&result); } if ((draw_type & GLX_WINDOW_BIT) != 0 && visual_id == 0) { fprintf(stderr, "FBconfig 0x%x has GLX_WINDOW_BIT " "set, but the Visual ID is 0!\n", config_id); result = PIGLIT_FAIL; } GetFBConfigAttrib(dpy, configs[i], GLX_TRANSPARENT_TYPE, &transparency); vinfo = GetVisualFromFBConfig(dpy, configs[i]); if ((vinfo == NULL) != (visual_id == 0)) { fprintf(stderr, "FBconfig 0x%x has vinfo = %p and " "visual ID = 0x%x. Both or neither must be " "NULL / zero.\n", config_id, vinfo, visual_id); result = PIGLIT_FAIL; } if (vinfo != NULL && vinfo->visualid != visual_id) { fprintf(stderr, "FBconfig 0x%x has " "vinfo->visualid = 0x%x and visual ID = 0x%x. " "These should match!\n", config_id, (int) vinfo->visualid, visual_id); result = PIGLIT_FAIL; } if (vinfo) { int depth; GetFBConfigAttrib(dpy, configs[i], GLX_BUFFER_SIZE, &depth); if (vinfo->class == StaticColor || vinfo->class == PseudoColor) { if (depth != vinfo->depth) { fprintf(stderr, "FBConfig 0x%x has " "depth %d but visual 0x%x has " "depth %d. These should " "match!\n", config_id, depth, (int)vinfo->visualid, vinfo->depth); result = PIGLIT_FAIL; } } if (vinfo->class == TrueColor || vinfo->class == DirectColor) { if (depth < vinfo->depth) { fprintf(stderr, "FBConfig 0x%x has " "depth %d < visual 0x%x depth " "%d. Should be >= visual " "depth!\n", config_id, depth, (int)vinfo->visualid, vinfo->depth); result = PIGLIT_FAIL; } } if (vtype == GLX_NONE) { fprintf(stderr, "FBConfig 0x%x supports " "windows but has no visual type\n", config_id); result = PIGLIT_FAIL; } else { int fail = 0; int ci_fail = 0; switch (vinfo->class) { case TrueColor: if (vtype != GLX_TRUE_COLOR) fail = 1; if (render_type & GLX_COLOR_INDEX_BIT) ci_fail = 1; break; case DirectColor: if (vtype != GLX_DIRECT_COLOR) fail = 1; if (render_type & GLX_COLOR_INDEX_BIT) ci_fail = 1; break; case PseudoColor: if (vtype != GLX_PSEUDO_COLOR) fail = 1; break; case StaticColor: if (vtype != GLX_STATIC_COLOR) fail = 1; break; case GrayScale: if (vtype != GLX_GRAY_SCALE) fail = 1; break; case StaticGray: if (vtype != GLX_STATIC_GRAY) fail = 1; break; default: fail = 2; break; } if (ci_fail) { fprintf(stderr, "FBConfig 0x%x is " "{True,Direct}Color but claims " "support for color-index\n", config_id); result = PIGLIT_FAIL; } if (fail == 2) { fprintf(stderr, "FBConfig 0x%x has " "visual with unknown class " "%d\n", config_id, vinfo->class); result = PIGLIT_FAIL; } else if (fail == 1) { fprintf(stderr, "FBConfig 0x%x claims " "visual class that does not " "match visual 0x%x\n", config_id, (int)vinfo->visualid); result = PIGLIT_FAIL; } } XFree(vinfo); } if (sample_buffers == 0) { int samples; GetFBConfigAttrib(dpy, configs[i], GLX_SAMPLES, &samples); if (samples != 0) { fprintf(stderr, "FBConfig 0x%x has " "0 sample buffers but %d " "samples, should be 0\n", config_id, samples); result = PIGLIT_FAIL; } } else if (sample_buffers == 1) { /* TODO check color/depth/stencil bits per sample */ } else { fprintf(stderr, "FBConfig 0x%x has bizarre " "GLX_SAMPLE_BUFFERS of %d, should be " "0 or 1\n", config_id, sample_buffers); result = PIGLIT_FAIL; } if (render_type == 0) { fprintf(stderr, "FBConfig 0x%x can be bound to " "neither RGBA nor color-index contexts\n", config_id); result = PIGLIT_FAIL; } else if (render_type & ~(GLX_RGBA_BIT | GLX_COLOR_INDEX_BIT)) { fprintf(stderr, "FBConfig 0x%x supports rendering " "to something other than RGBA or CI, " "piglit needs to be fixed\n", config_id); fbconfig_sanity_warn(&result); } if (x_renderable && !(draw_type & (GLX_WINDOW_BIT | GLX_PIXMAP_BIT))) { fprintf(stderr, "FBConfig 0x%x claims to be X " "renderable (0x%x), but does not support " "windows or pixmaps\n", config_id, draw_type); fbconfig_sanity_warn(&result); } else if (!x_renderable && (draw_type & (GLX_WINDOW_BIT | GLX_PIXMAP_BIT))) { fprintf(stderr, "FBConfig 0x%x claims to not be X " "renderable but claims to support windows " "and/or pixmaps\n", config_id); result = PIGLIT_FAIL; } switch (caveat) { case GLX_NONE: case GLX_SLOW_CONFIG: case GLX_NON_CONFORMANT_CONFIG: break; default: fprintf(stderr, "FBConfig 0x%x has unknown " "caveat 0x%x\n", config_id, caveat); result = PIGLIT_FAIL; break; } switch (transparency) { case GLX_NONE: break; case GLX_TRANSPARENT_RGB: if (vtype != GLX_TRUE_COLOR && vtype != GLX_DIRECT_COLOR) { fprintf(stderr, "FBConfig 0x%x is rgb " "transparent but not an rgb " "visual type\n", config_id); result = PIGLIT_FAIL; } break; case GLX_TRANSPARENT_INDEX: if (vtype == GLX_TRUE_COLOR || vtype == GLX_DIRECT_COLOR) { fprintf(stderr, "FBConfig 0x%x is ci " "transparent but not a ci " "visual type\n", config_id); result = PIGLIT_FAIL; } break; default: fprintf(stderr, "FBConfig 0x%x has unknown " "transparency type 0x%x\n", config_id, transparency); result = PIGLIT_FAIL; break; } } XCloseDisplay(dpy); piglit_report_result(result); return 0; }