/************************************************************************** * * Copyright 2008 Tungsten Graphics, Inc., Bismarck, ND., USA * All Rights Reserved. * * 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, sub license, 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 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 NON-INFRINGEMENT. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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. * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. * * **************************************************************************/ /** * @file * Get a hardware accelerated Gallium screen/context from the OpenGL driver. */ #include "pipe/p_compiler.h" #ifdef PIPE_OS_WINDOWS #include #include #else #include #include #include #include #endif #include "st_winsys.h" typedef struct pipe_screen * (GLAPIENTRY *PFNGETGALLIUMSCREENMESAPROC) (void); typedef struct pipe_context * (GLAPIENTRY* PFNCREATEGALLIUMCONTEXTMESAPROC) (void); static PFNGETGALLIUMSCREENMESAPROC pfnGetGalliumScreenMESA = NULL; static PFNCREATEGALLIUMCONTEXTMESAPROC pfnCreateGalliumContextMESA = NULL; #ifdef PIPE_OS_WINDOWS static INLINE boolean st_hardpipe_load(void) { WNDCLASS wc; HWND hwnd; HGLRC hglrc; HDC hdc; PIXELFORMATDESCRIPTOR pfd; int iPixelFormat; if(pfnGetGalliumScreenMESA && pfnCreateGalliumContextMESA) return TRUE; memset(&wc, 0, sizeof wc); wc.lpfnWndProc = DefWindowProc; wc.lpszClassName = "gallium"; wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; RegisterClass(&wc); hwnd = CreateWindow(wc.lpszClassName, "gallium", 0, 0, 0, 0, 0, NULL, 0, wc.hInstance, NULL); if (!hwnd) return FALSE; hdc = GetDC(hwnd); if (!hdc) return FALSE; pfd.cColorBits = 3; pfd.cRedBits = 1; pfd.cGreenBits = 1; pfd.cBlueBits = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; pfd.iLayerType = PFD_MAIN_PLANE; pfd.iPixelType = PFD_TYPE_RGBA; pfd.nSize = sizeof(pfd); pfd.nVersion = 1; iPixelFormat = ChoosePixelFormat(hdc, &pfd); if (!iPixelFormat) { pfd.dwFlags |= PFD_DOUBLEBUFFER; iPixelFormat = ChoosePixelFormat(hdc, &pfd); } if (!iPixelFormat) return FALSE; SetPixelFormat(hdc, iPixelFormat, &pfd); hglrc = wglCreateContext(hdc); if (!hglrc) return FALSE; if (!wglMakeCurrent(hdc, hglrc)) return FALSE; pfnGetGalliumScreenMESA = (PFNGETGALLIUMSCREENMESAPROC)wglGetProcAddress("wglGetGalliumScreenMESA"); if(!pfnGetGalliumScreenMESA) return FALSE; pfnCreateGalliumContextMESA = (PFNCREATEGALLIUMCONTEXTMESAPROC)wglGetProcAddress("wglCreateGalliumContextMESA"); if(!pfnCreateGalliumContextMESA) return FALSE; DestroyWindow(hwnd); return TRUE; } #else static INLINE boolean st_hardpipe_load(void) { Display *dpy; int scrnum; Window root; int attribSingle[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, None }; int attribDouble[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, None }; XVisualInfo *visinfo; GLXContext ctx = NULL; XSetWindowAttributes attr; unsigned long mask; int width = 100, height = 100; Window win; dpy = XOpenDisplay(NULL); if (!dpy) return FALSE; scrnum = 0; root = RootWindow(dpy, scrnum); visinfo = glXChooseVisual(dpy, scrnum, attribSingle); if (!visinfo) visinfo = glXChooseVisual(dpy, scrnum, attribDouble); if (!visinfo) return FALSE; ctx = glXCreateContext( dpy, visinfo, NULL, True ); if (!ctx) return FALSE; attr.background_pixel = 0; attr.border_pixel = 0; attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone); attr.event_mask = StructureNotifyMask | ExposureMask; mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; win = XCreateWindow(dpy, root, 0, 0, width, height, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr); if (!glXMakeCurrent(dpy, win, ctx)) return FALSE; pfnGetGalliumScreenMESA = (PFNGETGALLIUMSCREENMESAPROC)glXGetProcAddressARB((const GLubyte *)"glXGetGalliumScreenMESA"); if(!pfnGetGalliumScreenMESA) return FALSE; pfnCreateGalliumContextMESA = (PFNCREATEGALLIUMCONTEXTMESAPROC)glXGetProcAddressARB((const GLubyte *)"glXCreateGalliumContextMESA"); if(!pfnCreateGalliumContextMESA) return FALSE; glXDestroyContext(dpy, ctx); XFree(visinfo); XDestroyWindow(dpy, win); XCloseDisplay(dpy); return TRUE; } #endif struct pipe_screen * st_hardware_screen_create(void) { if(st_hardpipe_load()) return pfnGetGalliumScreenMESA(); else return st_software_screen_create(NULL); }