1*54e60f84SAndroid Build Coastguard Worker /*
2*54e60f84SAndroid Build Coastguard Worker * Copyright (C) 2010 Splitted-Desktop Systems. All Rights Reserved.
3*54e60f84SAndroid Build Coastguard Worker *
4*54e60f84SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
5*54e60f84SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the
6*54e60f84SAndroid Build Coastguard Worker * "Software"), to deal in the Software without restriction, including
7*54e60f84SAndroid Build Coastguard Worker * without limitation the rights to use, copy, modify, merge, publish,
8*54e60f84SAndroid Build Coastguard Worker * distribute, sub license, and/or sell copies of the Software, and to
9*54e60f84SAndroid Build Coastguard Worker * permit persons to whom the Software is furnished to do so, subject to
10*54e60f84SAndroid Build Coastguard Worker * the following conditions:
11*54e60f84SAndroid Build Coastguard Worker *
12*54e60f84SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the
13*54e60f84SAndroid Build Coastguard Worker * next paragraph) shall be included in all copies or substantial portions
14*54e60f84SAndroid Build Coastguard Worker * of the Software.
15*54e60f84SAndroid Build Coastguard Worker *
16*54e60f84SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17*54e60f84SAndroid Build Coastguard Worker * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18*54e60f84SAndroid Build Coastguard Worker * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19*54e60f84SAndroid Build Coastguard Worker * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20*54e60f84SAndroid Build Coastguard Worker * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21*54e60f84SAndroid Build Coastguard Worker * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22*54e60f84SAndroid Build Coastguard Worker * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23*54e60f84SAndroid Build Coastguard Worker */
24*54e60f84SAndroid Build Coastguard Worker
25*54e60f84SAndroid Build Coastguard Worker #include "sysdeps.h"
26*54e60f84SAndroid Build Coastguard Worker
27*54e60f84SAndroid Build Coastguard Worker #ifdef HAVE_FGLRX
28*54e60f84SAndroid Build Coastguard Worker
29*54e60f84SAndroid Build Coastguard Worker #include <stdio.h>
30*54e60f84SAndroid Build Coastguard Worker #include <stdlib.h>
31*54e60f84SAndroid Build Coastguard Worker #include <string.h>
32*54e60f84SAndroid Build Coastguard Worker #include <dlfcn.h>
33*54e60f84SAndroid Build Coastguard Worker #include <X11/Xlib.h>
34*54e60f84SAndroid Build Coastguard Worker #include "va_fglrx.h"
35*54e60f84SAndroid Build Coastguard Worker
36*54e60f84SAndroid Build Coastguard Worker #define ADL_OK 0
37*54e60f84SAndroid Build Coastguard Worker #define ADL_MAX_PATH 256
38*54e60f84SAndroid Build Coastguard Worker
39*54e60f84SAndroid Build Coastguard Worker /*
40*54e60f84SAndroid Build Coastguard Worker * Based on public AMD Display Library (ADL) SDK:
41*54e60f84SAndroid Build Coastguard Worker * <http://developer.amd.com/gpu/adlsdk/Pages/default.aspx>
42*54e60f84SAndroid Build Coastguard Worker */
43*54e60f84SAndroid Build Coastguard Worker typedef struct AdapterInfo {
44*54e60f84SAndroid Build Coastguard Worker int iSize;
45*54e60f84SAndroid Build Coastguard Worker int iAdapterIndex;
46*54e60f84SAndroid Build Coastguard Worker char strUDID[ADL_MAX_PATH];
47*54e60f84SAndroid Build Coastguard Worker int iBusNumber;
48*54e60f84SAndroid Build Coastguard Worker int iDeviceNumber;
49*54e60f84SAndroid Build Coastguard Worker int iFunctionNumber;
50*54e60f84SAndroid Build Coastguard Worker int iVendorID;
51*54e60f84SAndroid Build Coastguard Worker char strAdapterName[ADL_MAX_PATH];
52*54e60f84SAndroid Build Coastguard Worker char strDisplayName[ADL_MAX_PATH];
53*54e60f84SAndroid Build Coastguard Worker int iPresent;
54*54e60f84SAndroid Build Coastguard Worker int iXScreenNum;
55*54e60f84SAndroid Build Coastguard Worker int iDrvIndex;
56*54e60f84SAndroid Build Coastguard Worker char strXScreenConfigName[ADL_MAX_PATH];
57*54e60f84SAndroid Build Coastguard Worker } AdapterInfo, *LPAdapterInfo;
58*54e60f84SAndroid Build Coastguard Worker
59*54e60f84SAndroid Build Coastguard Worker typedef struct XScreenInfo {
60*54e60f84SAndroid Build Coastguard Worker int iXScreenNum;
61*54e60f84SAndroid Build Coastguard Worker char strXScreenConfigName[ADL_MAX_PATH];
62*54e60f84SAndroid Build Coastguard Worker } XScreenInfo, *LPXScreenInfo;
63*54e60f84SAndroid Build Coastguard Worker
64*54e60f84SAndroid Build Coastguard Worker typedef void *(*ADL_MAIN_MALLOC_CALLBACK)(int);
65*54e60f84SAndroid Build Coastguard Worker typedef int (*ADL_MAIN_CONTROL_CREATE)(ADL_MAIN_MALLOC_CALLBACK, int);
66*54e60f84SAndroid Build Coastguard Worker typedef int (*ADL_MAIN_CONTROL_DESTROY)(void);
67*54e60f84SAndroid Build Coastguard Worker typedef int (*ADL_ADAPTER_NUMBEROFADAPTERS_GET)(int *);
68*54e60f84SAndroid Build Coastguard Worker typedef int (*ADL_ADAPTER_ADAPTERINFO_GET)(LPAdapterInfo, int);
69*54e60f84SAndroid Build Coastguard Worker typedef int (*ADL_ADAPTER_XSCREENINFO_GET)(LPXScreenInfo, int);
70*54e60f84SAndroid Build Coastguard Worker
ADL_Main_Memory_Alloc(int iSize)71*54e60f84SAndroid Build Coastguard Worker static void *ADL_Main_Memory_Alloc(int iSize)
72*54e60f84SAndroid Build Coastguard Worker {
73*54e60f84SAndroid Build Coastguard Worker return malloc(iSize);
74*54e60f84SAndroid Build Coastguard Worker }
75*54e60f84SAndroid Build Coastguard Worker
ADL_Main_Memory_Free(void * arg)76*54e60f84SAndroid Build Coastguard Worker static void ADL_Main_Memory_Free(void *arg)
77*54e60f84SAndroid Build Coastguard Worker {
78*54e60f84SAndroid Build Coastguard Worker void ** const lpBuffer = arg;
79*54e60f84SAndroid Build Coastguard Worker
80*54e60f84SAndroid Build Coastguard Worker if (lpBuffer && *lpBuffer) {
81*54e60f84SAndroid Build Coastguard Worker free(*lpBuffer);
82*54e60f84SAndroid Build Coastguard Worker *lpBuffer = NULL;
83*54e60f84SAndroid Build Coastguard Worker }
84*54e60f84SAndroid Build Coastguard Worker }
85*54e60f84SAndroid Build Coastguard Worker
get_display_name_length(const char * name)86*54e60f84SAndroid Build Coastguard Worker static int get_display_name_length(const char *name)
87*54e60f84SAndroid Build Coastguard Worker {
88*54e60f84SAndroid Build Coastguard Worker const char *m;
89*54e60f84SAndroid Build Coastguard Worker
90*54e60f84SAndroid Build Coastguard Worker if (!name)
91*54e60f84SAndroid Build Coastguard Worker return 0;
92*54e60f84SAndroid Build Coastguard Worker
93*54e60f84SAndroid Build Coastguard Worker /* Strip out screen number */
94*54e60f84SAndroid Build Coastguard Worker m = strchr(name, ':');
95*54e60f84SAndroid Build Coastguard Worker if (m) {
96*54e60f84SAndroid Build Coastguard Worker m = strchr(m, '.');
97*54e60f84SAndroid Build Coastguard Worker if (m)
98*54e60f84SAndroid Build Coastguard Worker return m - name;
99*54e60f84SAndroid Build Coastguard Worker }
100*54e60f84SAndroid Build Coastguard Worker return strlen(name);
101*54e60f84SAndroid Build Coastguard Worker }
102*54e60f84SAndroid Build Coastguard Worker
match_display_name(Display * x11_dpy,const char * display_name)103*54e60f84SAndroid Build Coastguard Worker static int match_display_name(Display *x11_dpy, const char *display_name)
104*54e60f84SAndroid Build Coastguard Worker {
105*54e60f84SAndroid Build Coastguard Worker Display *test_dpy;
106*54e60f84SAndroid Build Coastguard Worker char *test_dpy_name, *x11_dpy_name;
107*54e60f84SAndroid Build Coastguard Worker int test_dpy_namelen, x11_dpy_namelen;
108*54e60f84SAndroid Build Coastguard Worker int m;
109*54e60f84SAndroid Build Coastguard Worker
110*54e60f84SAndroid Build Coastguard Worker test_dpy = XOpenDisplay(display_name);
111*54e60f84SAndroid Build Coastguard Worker if (!test_dpy)
112*54e60f84SAndroid Build Coastguard Worker return 0;
113*54e60f84SAndroid Build Coastguard Worker
114*54e60f84SAndroid Build Coastguard Worker test_dpy_name = XDisplayString(test_dpy);
115*54e60f84SAndroid Build Coastguard Worker test_dpy_namelen = get_display_name_length(test_dpy_name);
116*54e60f84SAndroid Build Coastguard Worker x11_dpy_name = XDisplayString(x11_dpy);
117*54e60f84SAndroid Build Coastguard Worker x11_dpy_namelen = get_display_name_length(x11_dpy_name);
118*54e60f84SAndroid Build Coastguard Worker
119*54e60f84SAndroid Build Coastguard Worker m = (test_dpy_namelen == x11_dpy_namelen &&
120*54e60f84SAndroid Build Coastguard Worker (test_dpy_namelen == 0 ||
121*54e60f84SAndroid Build Coastguard Worker (test_dpy_namelen > 0 &&
122*54e60f84SAndroid Build Coastguard Worker strncmp(test_dpy_name, x11_dpy_name, test_dpy_namelen) == 0)));
123*54e60f84SAndroid Build Coastguard Worker
124*54e60f84SAndroid Build Coastguard Worker XCloseDisplay(test_dpy);
125*54e60f84SAndroid Build Coastguard Worker return m;
126*54e60f84SAndroid Build Coastguard Worker }
127*54e60f84SAndroid Build Coastguard Worker
VA_FGLRXGetClientDriverName(Display * dpy,int screen,char ** clientDriverName)128*54e60f84SAndroid Build Coastguard Worker static Bool VA_FGLRXGetClientDriverName(Display *dpy, int screen, char **clientDriverName)
129*54e60f84SAndroid Build Coastguard Worker {
130*54e60f84SAndroid Build Coastguard Worker ADL_MAIN_CONTROL_CREATE ADL_Main_Control_Create;
131*54e60f84SAndroid Build Coastguard Worker ADL_MAIN_CONTROL_DESTROY ADL_Main_Control_Destroy;
132*54e60f84SAndroid Build Coastguard Worker ADL_ADAPTER_NUMBEROFADAPTERS_GET ADL_Adapter_NumberOfAdapters_Get;
133*54e60f84SAndroid Build Coastguard Worker ADL_ADAPTER_ADAPTERINFO_GET ADL_Adapter_AdapterInfo_Get;
134*54e60f84SAndroid Build Coastguard Worker ADL_ADAPTER_XSCREENINFO_GET ADL_Adapter_XScreenInfo_Get;
135*54e60f84SAndroid Build Coastguard Worker
136*54e60f84SAndroid Build Coastguard Worker LPAdapterInfo lpAdapterInfo = NULL;
137*54e60f84SAndroid Build Coastguard Worker LPXScreenInfo lpXScreenInfo = NULL;
138*54e60f84SAndroid Build Coastguard Worker void *libadl_handle = NULL;
139*54e60f84SAndroid Build Coastguard Worker Bool success = False;
140*54e60f84SAndroid Build Coastguard Worker int is_adl_initialized = 0;
141*54e60f84SAndroid Build Coastguard Worker int i, num_adapters, lpAdapterInfo_size, lpXScreenInfo_size;
142*54e60f84SAndroid Build Coastguard Worker
143*54e60f84SAndroid Build Coastguard Worker libadl_handle = dlopen("libatiadlxx.so", RTLD_LAZY | RTLD_GLOBAL);
144*54e60f84SAndroid Build Coastguard Worker if (!libadl_handle)
145*54e60f84SAndroid Build Coastguard Worker goto end;
146*54e60f84SAndroid Build Coastguard Worker
147*54e60f84SAndroid Build Coastguard Worker dlerror();
148*54e60f84SAndroid Build Coastguard Worker ADL_Main_Control_Create = (ADL_MAIN_CONTROL_CREATE)
149*54e60f84SAndroid Build Coastguard Worker dlsym(libadl_handle, "ADL_Main_Control_Create");
150*54e60f84SAndroid Build Coastguard Worker if (dlerror())
151*54e60f84SAndroid Build Coastguard Worker goto end;
152*54e60f84SAndroid Build Coastguard Worker
153*54e60f84SAndroid Build Coastguard Worker ADL_Main_Control_Destroy = (ADL_MAIN_CONTROL_DESTROY)
154*54e60f84SAndroid Build Coastguard Worker dlsym(libadl_handle, "ADL_Main_Control_Destroy");
155*54e60f84SAndroid Build Coastguard Worker if (dlerror())
156*54e60f84SAndroid Build Coastguard Worker goto end;
157*54e60f84SAndroid Build Coastguard Worker
158*54e60f84SAndroid Build Coastguard Worker ADL_Adapter_NumberOfAdapters_Get = (ADL_ADAPTER_NUMBEROFADAPTERS_GET)
159*54e60f84SAndroid Build Coastguard Worker dlsym(libadl_handle, "ADL_Adapter_NumberOfAdapters_Get");
160*54e60f84SAndroid Build Coastguard Worker if (dlerror())
161*54e60f84SAndroid Build Coastguard Worker goto end;
162*54e60f84SAndroid Build Coastguard Worker
163*54e60f84SAndroid Build Coastguard Worker ADL_Adapter_AdapterInfo_Get = (ADL_ADAPTER_ADAPTERINFO_GET)
164*54e60f84SAndroid Build Coastguard Worker dlsym(libadl_handle, "ADL_Adapter_AdapterInfo_Get");
165*54e60f84SAndroid Build Coastguard Worker if (dlerror())
166*54e60f84SAndroid Build Coastguard Worker goto end;
167*54e60f84SAndroid Build Coastguard Worker
168*54e60f84SAndroid Build Coastguard Worker ADL_Adapter_XScreenInfo_Get = (ADL_ADAPTER_XSCREENINFO_GET)
169*54e60f84SAndroid Build Coastguard Worker dlsym(libadl_handle, "ADL_Adapter_XScreenInfo_Get");
170*54e60f84SAndroid Build Coastguard Worker if (dlerror())
171*54e60f84SAndroid Build Coastguard Worker goto end;
172*54e60f84SAndroid Build Coastguard Worker
173*54e60f84SAndroid Build Coastguard Worker if (ADL_Main_Control_Create(ADL_Main_Memory_Alloc, 1) != ADL_OK)
174*54e60f84SAndroid Build Coastguard Worker goto end;
175*54e60f84SAndroid Build Coastguard Worker is_adl_initialized = 1;
176*54e60f84SAndroid Build Coastguard Worker
177*54e60f84SAndroid Build Coastguard Worker if (ADL_Adapter_NumberOfAdapters_Get(&num_adapters) != ADL_OK)
178*54e60f84SAndroid Build Coastguard Worker goto end;
179*54e60f84SAndroid Build Coastguard Worker if (num_adapters <= 0)
180*54e60f84SAndroid Build Coastguard Worker goto end;
181*54e60f84SAndroid Build Coastguard Worker
182*54e60f84SAndroid Build Coastguard Worker lpAdapterInfo_size = num_adapters * sizeof(*lpAdapterInfo);
183*54e60f84SAndroid Build Coastguard Worker lpAdapterInfo = ADL_Main_Memory_Alloc(lpAdapterInfo_size);
184*54e60f84SAndroid Build Coastguard Worker if (!lpAdapterInfo)
185*54e60f84SAndroid Build Coastguard Worker goto end;
186*54e60f84SAndroid Build Coastguard Worker memset(lpAdapterInfo, 0, lpAdapterInfo_size);
187*54e60f84SAndroid Build Coastguard Worker
188*54e60f84SAndroid Build Coastguard Worker for (i = 0; i < num_adapters; i++)
189*54e60f84SAndroid Build Coastguard Worker lpAdapterInfo[i].iSize = sizeof(lpAdapterInfo[i]);
190*54e60f84SAndroid Build Coastguard Worker
191*54e60f84SAndroid Build Coastguard Worker lpXScreenInfo_size = num_adapters * sizeof(*lpXScreenInfo);
192*54e60f84SAndroid Build Coastguard Worker lpXScreenInfo = ADL_Main_Memory_Alloc(lpXScreenInfo_size);
193*54e60f84SAndroid Build Coastguard Worker if (!lpXScreenInfo)
194*54e60f84SAndroid Build Coastguard Worker goto end;
195*54e60f84SAndroid Build Coastguard Worker memset(lpXScreenInfo, 0, lpXScreenInfo_size);
196*54e60f84SAndroid Build Coastguard Worker
197*54e60f84SAndroid Build Coastguard Worker if (ADL_Adapter_AdapterInfo_Get(lpAdapterInfo, lpAdapterInfo_size) != ADL_OK)
198*54e60f84SAndroid Build Coastguard Worker goto end;
199*54e60f84SAndroid Build Coastguard Worker
200*54e60f84SAndroid Build Coastguard Worker if (ADL_Adapter_XScreenInfo_Get(lpXScreenInfo, lpXScreenInfo_size) != ADL_OK)
201*54e60f84SAndroid Build Coastguard Worker goto end;
202*54e60f84SAndroid Build Coastguard Worker
203*54e60f84SAndroid Build Coastguard Worker for (i = 0; i < num_adapters; i++) {
204*54e60f84SAndroid Build Coastguard Worker LPXScreenInfo const lpCurrXScreenInfo = &lpXScreenInfo[i];
205*54e60f84SAndroid Build Coastguard Worker LPAdapterInfo const lpCurrAdapterInfo = &lpAdapterInfo[i];
206*54e60f84SAndroid Build Coastguard Worker if (!lpCurrAdapterInfo->iPresent)
207*54e60f84SAndroid Build Coastguard Worker continue;
208*54e60f84SAndroid Build Coastguard Worker #if 0
209*54e60f84SAndroid Build Coastguard Worker printf("Adapter %d:\n", i);
210*54e60f84SAndroid Build Coastguard Worker printf(" iAdapterIndex: %d\n", lpCurrAdapterInfo->iAdapterIndex);
211*54e60f84SAndroid Build Coastguard Worker printf(" strUDID: '%s'\n", lpCurrAdapterInfo->strUDID);
212*54e60f84SAndroid Build Coastguard Worker printf(" iBusNumber: %d\n", lpCurrAdapterInfo->iBusNumber);
213*54e60f84SAndroid Build Coastguard Worker printf(" iDeviceNumber: %d\n", lpCurrAdapterInfo->iDeviceNumber);
214*54e60f84SAndroid Build Coastguard Worker printf(" iFunctionNumber: %d\n", lpCurrAdapterInfo->iFunctionNumber);
215*54e60f84SAndroid Build Coastguard Worker printf(" iVendorID: 0x%04x\n", lpCurrAdapterInfo->iVendorID);
216*54e60f84SAndroid Build Coastguard Worker printf(" strAdapterName: '%s'\n", lpCurrAdapterInfo->strAdapterName);
217*54e60f84SAndroid Build Coastguard Worker printf(" strDisplayName: '%s'\n", lpCurrAdapterInfo->strDisplayName);
218*54e60f84SAndroid Build Coastguard Worker printf(" iPresent: %d\n", lpCurrAdapterInfo->iPresent);
219*54e60f84SAndroid Build Coastguard Worker printf(" iXScreenNum: %d\n", lpCurrXScreenInfo->iXScreenNum);
220*54e60f84SAndroid Build Coastguard Worker #endif
221*54e60f84SAndroid Build Coastguard Worker if (screen == lpCurrXScreenInfo->iXScreenNum &&
222*54e60f84SAndroid Build Coastguard Worker match_display_name(dpy, lpCurrAdapterInfo->strDisplayName)) {
223*54e60f84SAndroid Build Coastguard Worker *clientDriverName = strdup("fglrx");
224*54e60f84SAndroid Build Coastguard Worker success = !!(*clientDriverName);
225*54e60f84SAndroid Build Coastguard Worker break;
226*54e60f84SAndroid Build Coastguard Worker }
227*54e60f84SAndroid Build Coastguard Worker }
228*54e60f84SAndroid Build Coastguard Worker
229*54e60f84SAndroid Build Coastguard Worker end:
230*54e60f84SAndroid Build Coastguard Worker if (lpXScreenInfo)
231*54e60f84SAndroid Build Coastguard Worker ADL_Main_Memory_Free(&lpXScreenInfo);
232*54e60f84SAndroid Build Coastguard Worker if (lpAdapterInfo)
233*54e60f84SAndroid Build Coastguard Worker ADL_Main_Memory_Free(&lpAdapterInfo);
234*54e60f84SAndroid Build Coastguard Worker if (is_adl_initialized)
235*54e60f84SAndroid Build Coastguard Worker ADL_Main_Control_Destroy();
236*54e60f84SAndroid Build Coastguard Worker if (libadl_handle)
237*54e60f84SAndroid Build Coastguard Worker dlclose(libadl_handle);
238*54e60f84SAndroid Build Coastguard Worker return success;
239*54e60f84SAndroid Build Coastguard Worker }
240*54e60f84SAndroid Build Coastguard Worker
va_FGLRX_GetDriverNames(VADisplayContextP pDisplayContext,char ** drivers,unsigned * num_drivers)241*54e60f84SAndroid Build Coastguard Worker VAStatus va_FGLRX_GetDriverNames(
242*54e60f84SAndroid Build Coastguard Worker VADisplayContextP pDisplayContext,
243*54e60f84SAndroid Build Coastguard Worker char **drivers,
244*54e60f84SAndroid Build Coastguard Worker unsigned *num_drivers
245*54e60f84SAndroid Build Coastguard Worker )
246*54e60f84SAndroid Build Coastguard Worker {
247*54e60f84SAndroid Build Coastguard Worker VADriverContextP ctx = pDisplayContext->pDriverContext;
248*54e60f84SAndroid Build Coastguard Worker if (!VA_FGLRXGetClientDriverName(ctx->native_dpy, ctx->x11_screen,
249*54e60f84SAndroid Build Coastguard Worker drivers))
250*54e60f84SAndroid Build Coastguard Worker return VA_STATUS_ERROR_UNKNOWN;
251*54e60f84SAndroid Build Coastguard Worker
252*54e60f84SAndroid Build Coastguard Worker *num_drivers = 1;
253*54e60f84SAndroid Build Coastguard Worker return VA_STATUS_SUCCESS;
254*54e60f84SAndroid Build Coastguard Worker }
255*54e60f84SAndroid Build Coastguard Worker
256*54e60f84SAndroid Build Coastguard Worker #endif
257