blob: 7dea42714392d51ad374623a7c2ecf1f31f79669 [file] [log] [blame]
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001/*
2 * XGL
3 *
4 * Copyright (C) 2014 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
Chia-I Wu701f3f62014-09-02 08:32:09 +080023 *
24 * Authors:
25 * Chia-I Wu <olv@lunarg.com>
26 * Courtney Goeltzenleuchter <courtney@lunarg.com>
Chia-I Wu5f72d0f2014-08-01 11:21:23 +080027 */
Jon Ashburn6b4d70c2014-10-22 18:13:16 -060028#define _GNU_SOURCE
Chia-I Wu5f72d0f2014-08-01 11:21:23 +080029#include <stdio.h>
30#include <stdlib.h>
31#include <stdarg.h>
32#include <stdbool.h>
33#include <string.h>
34
Chia-I Wu13a61a52014-08-04 11:18:20 +080035#include <sys/types.h>
36#include <dirent.h>
Courtney Goeltzenleuchter4af9bd12014-08-01 14:18:11 -060037#include <unistd.h>
Chia-I Wu5f72d0f2014-08-01 11:21:23 +080038#include <dlfcn.h>
39#include <pthread.h>
Jon Ashburnd38bfb12014-10-14 19:15:22 -060040#include <assert.h>
Chia-I Wu19300602014-08-04 08:03:57 +080041#include "loader.h"
Chia-I Wu5f72d0f2014-08-01 11:21:23 +080042
Jon Ashburndf7d5842014-10-16 15:48:50 -060043typedef XGL_VOID (* SetDispatchType)(XGL_LAYER_DISPATCH_TABLE * disp, XGL_BOOL debug);
Chia-I Wu5f72d0f2014-08-01 11:21:23 +080044
Jon Ashburn6b4d70c2014-10-22 18:13:16 -060045struct loader_layers {
46 void *lib_handle;
47 char lib_name[1024];
48};
49
Chia-I Wu5f72d0f2014-08-01 11:21:23 +080050struct loader_icd {
51 void *handle;
52
Jon Ashburn876b1ac2014-10-17 15:09:07 -060053 XGL_LAYER_DISPATCH_TABLE *loader_dispatch;
Jon Ashburn6b4d70c2014-10-22 18:13:16 -060054 XGL_UINT layer_count[XGL_MAX_PHYSICAL_GPUS];
55 struct loader_layers layer_libs[XGL_MAX_PHYSICAL_GPUS][MAX_LAYER_LIBRARIES];
Jon Ashburnd09bd102014-10-22 21:15:26 -060056 XGL_BASE_LAYER_OBJECT *wrappedGpus[XGL_MAX_PHYSICAL_GPUS];
Jon Ashburn876b1ac2014-10-17 15:09:07 -060057 XGL_UINT gpu_count;
Jon Ashburn6b4d70c2014-10-22 18:13:16 -060058 XGL_BASE_LAYER_OBJECT *gpus;
Jon Ashburndf7d5842014-10-16 15:48:50 -060059
Jon Ashburnd38bfb12014-10-14 19:15:22 -060060 GetProcAddrType GetProcAddr;
61 InitAndEnumerateGpusType InitAndEnumerateGpus;
62 DbgRegisterMsgCallbackType DbgRegisterMsgCallback;
63 DbgUnregisterMsgCallbackType DbgUnregisterMsgCallback;
64 DbgSetGlobalOptionType DbgSetGlobalOption;
Jon Ashburndf7d5842014-10-16 15:48:50 -060065 SetDispatchType SetDispatch;
Chia-I Wu5f72d0f2014-08-01 11:21:23 +080066
67 struct loader_icd *next;
68};
69
Jon Ashburnd38bfb12014-10-14 19:15:22 -060070
Chia-I Wu5f72d0f2014-08-01 11:21:23 +080071struct loader_msg_callback {
72 XGL_DBG_MSG_CALLBACK_FUNCTION func;
73 XGL_VOID *data;
74
75 struct loader_msg_callback *next;
76};
77
Jon Ashburnd38bfb12014-10-14 19:15:22 -060078
Chia-I Wu5f72d0f2014-08-01 11:21:23 +080079static struct {
80 bool scanned;
81 struct loader_icd *icds;
Jon Ashburn6b4d70c2014-10-22 18:13:16 -060082 bool layer_scanned;
Jon Ashburnd38bfb12014-10-14 19:15:22 -060083 char layer_dirs[4096];
Jon Ashburn6b4d70c2014-10-22 18:13:16 -060084 unsigned int scanned_layer_count;
85 char *scanned_layer_names[MAX_LAYER_LIBRARIES];
Chia-I Wu5f72d0f2014-08-01 11:21:23 +080086 struct loader_msg_callback *msg_callbacks;
87
88 bool debug_echo_enable;
89 bool break_on_error;
90 bool break_on_warning;
91} loader;
92
93static XGL_RESULT loader_msg_callback_add(XGL_DBG_MSG_CALLBACK_FUNCTION func,
94 XGL_VOID *data)
95{
96 struct loader_msg_callback *cb;
97
98 cb = malloc(sizeof(*cb));
99 if (!cb)
100 return XGL_ERROR_OUT_OF_MEMORY;
101
102 cb->func = func;
103 cb->data = data;
104
105 cb->next = loader.msg_callbacks;
106 loader.msg_callbacks = cb;
107
108 return XGL_SUCCESS;
109}
110
111static XGL_RESULT loader_msg_callback_remove(XGL_DBG_MSG_CALLBACK_FUNCTION func)
112{
113 struct loader_msg_callback *cb = loader.msg_callbacks;
114
115 /*
116 * Find the first match (last registered).
117 *
118 * XXX What if the same callback function is registered more than once?
119 */
120 while (cb) {
121 if (cb->func == func) {
122 break;
123 }
124
125 cb = cb->next;
126 }
127
128 if (!cb)
129 return XGL_ERROR_INVALID_POINTER;
130
131 free(cb);
132
133 return XGL_SUCCESS;
134}
135
136static void loader_msg_callback_clear(void)
137{
138 struct loader_msg_callback *cb = loader.msg_callbacks;
139
140 while (cb) {
141 struct loader_msg_callback *next = cb->next;
142 free(cb);
143 cb = next;
144 }
145
146 loader.msg_callbacks = NULL;
147}
148
149static void loader_log(XGL_DBG_MSG_TYPE msg_type, XGL_INT msg_code,
150 const char *format, ...)
151{
152 const struct loader_msg_callback *cb = loader.msg_callbacks;
153 char msg[256];
154 va_list ap;
155 int ret;
156
157 va_start(ap, format);
158 ret = vsnprintf(msg, sizeof(msg), format, ap);
159 if (ret >= sizeof(msg) || ret < 0) {
160 msg[sizeof(msg) - 1] = '\0';
161 }
162 va_end(ap);
163
164 if (loader.debug_echo_enable || !cb) {
165 fputs(msg, stderr);
166 fputc('\n', stderr);
167 }
168
169 while (cb) {
170 cb->func(msg_type, XGL_VALIDATION_LEVEL_0, XGL_NULL_HANDLE, 0,
171 msg_code, (const XGL_CHAR *) msg, cb->data);
172 cb = cb->next;
173 }
174
175 switch (msg_type) {
176 case XGL_DBG_MSG_ERROR:
177 if (loader.break_on_error) {
178 exit(1);
179 }
180 /* fall through */
181 case XGL_DBG_MSG_WARNING:
182 if (loader.break_on_warning) {
183 exit(1);
184 }
185 break;
186 default:
187 break;
188 }
189}
190
191static void
192loader_icd_destroy(struct loader_icd *icd)
193{
194 dlclose(icd->handle);
195 free(icd);
196}
197
198static struct loader_icd *
199loader_icd_create(const char *filename)
200{
201 struct loader_icd *icd;
202
203 icd = malloc(sizeof(*icd));
204 if (!icd)
205 return NULL;
206
Courtney Goeltzenleuchter55001bb2014-10-28 10:29:27 -0600207 memset(icd, 0, sizeof(*icd));
208
Chia-I Wu5f72d0f2014-08-01 11:21:23 +0800209 icd->handle = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
210 if (!icd->handle) {
211 loader_log(XGL_DBG_MSG_WARNING, 0, dlerror());
212 free(icd);
213 return NULL;
214 }
215
216#define LOOKUP(icd, func) do { \
Jon Ashburnd38bfb12014-10-14 19:15:22 -0600217 icd->func = (func## Type) dlsym(icd->handle, "xgl" #func); \
Chia-I Wu5f72d0f2014-08-01 11:21:23 +0800218 if (!icd->func) { \
219 loader_log(XGL_DBG_MSG_WARNING, 0, dlerror()); \
220 loader_icd_destroy(icd); \
221 return NULL; \
222 } \
223} while (0)
Jon Ashburnd38bfb12014-10-14 19:15:22 -0600224 LOOKUP(icd, GetProcAddr);
Chia-I Wu5f72d0f2014-08-01 11:21:23 +0800225 LOOKUP(icd, InitAndEnumerateGpus);
226 LOOKUP(icd, DbgRegisterMsgCallback);
227 LOOKUP(icd, DbgUnregisterMsgCallback);
228 LOOKUP(icd, DbgSetGlobalOption);
Jon Ashburndf7d5842014-10-16 15:48:50 -0600229 LOOKUP(icd, SetDispatch);
Chia-I Wu5f72d0f2014-08-01 11:21:23 +0800230#undef LOOKUP
231
232 return icd;
233}
234
235static XGL_RESULT loader_icd_register_msg_callbacks(const struct loader_icd *icd)
236{
237 const struct loader_msg_callback *cb = loader.msg_callbacks;
238 XGL_RESULT res;
239
240 while (cb) {
241 res = icd->DbgRegisterMsgCallback(cb->func, cb->data);
242 if (res != XGL_SUCCESS) {
243 break;
244 }
245
246 cb = cb->next;
247 }
248
249 /* roll back on errors */
250 if (cb) {
251 const struct loader_msg_callback *tmp = loader.msg_callbacks;
252
253 while (tmp != cb) {
254 icd->DbgUnregisterMsgCallback(cb->func);
255 tmp = tmp->next;
256 }
257
258 return res;
259 }
260
261 return XGL_SUCCESS;
262}
263
264static XGL_RESULT loader_icd_set_global_options(const struct loader_icd *icd)
265{
266#define SETB(icd, opt, val) do { \
267 if (val) { \
268 const XGL_RESULT res = \
269 icd->DbgSetGlobalOption(opt, sizeof(val), &val); \
270 if (res != XGL_SUCCESS) \
271 return res; \
272 } \
273} while (0)
274 SETB(icd, XGL_DBG_OPTION_DEBUG_ECHO_ENABLE, loader.debug_echo_enable);
275 SETB(icd, XGL_DBG_OPTION_BREAK_ON_ERROR, loader.break_on_error);
276 SETB(icd, XGL_DBG_OPTION_BREAK_ON_WARNING, loader.break_on_warning);
277#undef SETB
278
279return XGL_SUCCESS;
280}
281
Chia-I Wu13a61a52014-08-04 11:18:20 +0800282static struct loader_icd *loader_icd_add(const char *filename)
283{
284 struct loader_icd *icd;
285
286 icd = loader_icd_create(filename);
287 if (!icd)
288 return NULL;
289
290 if (loader_icd_set_global_options(icd) != XGL_SUCCESS ||
291 loader_icd_register_msg_callbacks(icd) != XGL_SUCCESS) {
292 loader_log(XGL_DBG_MSG_WARNING, 0,
293 "%s ignored: failed to migrate settings", filename);
294 loader_icd_destroy(icd);
295 }
296
297 /* prepend to the list */
298 icd->next = loader.icds;
299 loader.icds = icd;
300
301 return icd;
302}
303
Courtney Goeltzenleuchter4af9bd12014-08-01 14:18:11 -0600304#ifndef DEFAULT_XGL_DRIVERS_PATH
305// TODO: Is this a good default location?
306// Need to search for both 32bit and 64bit ICDs
307#define DEFAULT_XGL_DRIVERS_PATH "/usr/lib/i386-linux-gnu/xgl:/usr/lib/x86_64-linux-gnu/xgl"
308#endif
309
310/**
311 * Try to \c loader_icd_scan XGL driver(s).
312 *
313 * This function scans the default system path or path
314 * specified by the \c LIBXGL_DRIVERS_PATH environment variable in
315 * order to find loadable XGL ICDs with the name of libXGL_*.
316 *
317 * \returns
318 * void; but side effect is to set loader_icd_scanned to true
319 */
320static void loader_icd_scan(void)
Chia-I Wu5f72d0f2014-08-01 11:21:23 +0800321{
Courtney Goeltzenleuchter4af9bd12014-08-01 14:18:11 -0600322 const char *libPaths, *p, *next;
323 DIR *sysdir;
324 struct dirent *dent;
325 char icd_library[1024];
Jon Ashburn5cda59c2014-10-03 16:31:35 -0600326 char path[1024];
Courtney Goeltzenleuchter4af9bd12014-08-01 14:18:11 -0600327 int len;
Chia-I Wu5f72d0f2014-08-01 11:21:23 +0800328
Courtney Goeltzenleuchter4af9bd12014-08-01 14:18:11 -0600329 libPaths = NULL;
330 if (geteuid() == getuid()) {
331 /* don't allow setuid apps to use LIBXGL_DRIVERS_PATH */
332 libPaths = getenv("LIBXGL_DRIVERS_PATH");
333 }
334 if (libPaths == NULL)
335 libPaths = DEFAULT_XGL_DRIVERS_PATH;
Chia-I Wu5f72d0f2014-08-01 11:21:23 +0800336
Courtney Goeltzenleuchter4af9bd12014-08-01 14:18:11 -0600337 for (p = libPaths; *p; p = next) {
338 next = strchr(p, ':');
339 if (next == NULL) {
340 len = strlen(p);
341 next = p + len;
342 }
343 else {
344 len = next - p;
Jon Ashburn5cda59c2014-10-03 16:31:35 -0600345 sprintf(path, "%.*s", (len > sizeof(path) - 1) ? (int) sizeof(path) - 1 : len, p);
346 p = path;
Courtney Goeltzenleuchter4af9bd12014-08-01 14:18:11 -0600347 next++;
348 }
Chia-I Wu5f72d0f2014-08-01 11:21:23 +0800349
Courtney Goeltzenleuchter4af9bd12014-08-01 14:18:11 -0600350 sysdir = opendir(p);
351 if (sysdir) {
352 dent = readdir(sysdir);
353 while (dent) {
354 /* look for ICDs starting with "libXGL_" */
355 if (!strncmp(dent->d_name, "libXGL_", 7)) {
Courtney Goeltzenleuchter4af9bd12014-08-01 14:18:11 -0600356 snprintf(icd_library, 1024, "%s/%s",p,dent->d_name);
Chia-I Wu13a61a52014-08-04 11:18:20 +0800357 loader_icd_add(icd_library);
Courtney Goeltzenleuchter4af9bd12014-08-01 14:18:11 -0600358 }
359
360 dent = readdir(sysdir);
361 }
362 closedir(sysdir);
363 }
Chia-I Wu5f72d0f2014-08-01 11:21:23 +0800364 }
365
366 /* we have nothing to log anymore */
367 loader_msg_callback_clear();
368
369 loader.scanned = true;
370}
371
Jon Ashburnd38bfb12014-10-14 19:15:22 -0600372#ifndef DEFAULT_XGL_LAYERS_PATH
373// TODO: Is this a good default locations
374#define DEFAULT_XGL_LAYERS_PATH ".:/usr/lib/i386-linux-gnu/xgl:/usr/lib/x86_64-linux-gnu/xgl"
375#endif
376
Jon Ashburn6b4d70c2014-10-22 18:13:16 -0600377static void layer_lib_scan(const char * libInPaths, const bool useDefaultDirs)
Jon Ashburnd38bfb12014-10-14 19:15:22 -0600378{
379 const char *p, *next;
380 char *libPaths = &loader.layer_dirs[0];
381 DIR *curdir;
382 struct dirent *dent;
Jon Ashburn6b4d70c2014-10-22 18:13:16 -0600383 int len, i;
384 char temp_str[1024];
Jon Ashburnd38bfb12014-10-14 19:15:22 -0600385
386 if (libInPaths){
387 strncpy(libPaths, libInPaths, sizeof(loader.layer_dirs));
388 }
389 else {
390 *libPaths = '\0';
391 }
392
393 /* cleanup any previously scanned libraries */
Jon Ashburn6b4d70c2014-10-22 18:13:16 -0600394 for (i = 0; i < loader.scanned_layer_count; i++) {
395 if (loader.scanned_layer_names[i] != NULL)
396 free(loader.scanned_layer_names[i]);
397 loader.scanned_layer_names[i] = NULL;
Jon Ashburnd38bfb12014-10-14 19:15:22 -0600398 }
Jon Ashburn6b4d70c2014-10-22 18:13:16 -0600399 loader.scanned_layer_count = 0;
Jon Ashburnd38bfb12014-10-14 19:15:22 -0600400
401 if (useDefaultDirs)
402 strncat(libPaths, DEFAULT_XGL_LAYERS_PATH, sizeof(loader.layer_dirs) - sizeof(DEFAULT_XGL_LAYERS_PATH));
403
404 for (p = libPaths; *p; p = next) {
405 next = strchr(p, ':');
406 if (next == NULL) {
407 len = strlen(p);
408 next = p + len;
409 }
410 else {
411 len = next - p;
412 *(char *) next = '\0';
413 next++;
414 }
415
416 curdir = opendir(p);
417 if (curdir) {
418 dent = readdir(curdir);
419 while (dent) {
Jon Ashburnd38bfb12014-10-14 19:15:22 -0600420 /* look for wrappers starting with "libXGLlayer" */
421 if (!strncmp(dent->d_name, "libXGLLayer", strlen("libXGLLayer"))) {
Jon Ashburn6b4d70c2014-10-22 18:13:16 -0600422 void * handle;
423 snprintf(temp_str, sizeof(temp_str), "%s/%s",p,dent->d_name);
424 if ((handle = dlopen((const char *) temp_str, RTLD_LAZY)) == NULL)
Jon Ashburnd38bfb12014-10-14 19:15:22 -0600425 continue;
Jon Ashburn6b4d70c2014-10-22 18:13:16 -0600426 if (loader.scanned_layer_count == MAX_LAYER_LIBRARIES) {
427 loader_log(XGL_DBG_MSG_ERROR, 0, "%s ignored: max layer libraries exceed", temp_str);
428 break;
429 }
430 if ((loader.scanned_layer_names[loader.scanned_layer_count] = malloc(strlen(temp_str) + 1)) == NULL) {
431 loader_log(XGL_DBG_MSG_ERROR, 0, "%s ignored: out of memory", temp_str);
432 break;
433 }
434 strcpy(loader.scanned_layer_names[loader.scanned_layer_count], temp_str);
435 loader.scanned_layer_count++;
436 dlclose(handle);
Jon Ashburnd38bfb12014-10-14 19:15:22 -0600437 }
438
439 dent = readdir(curdir);
440 }
441 closedir(curdir);
442 }
443 }
444
Jon Ashburn6b4d70c2014-10-22 18:13:16 -0600445 loader.layer_scanned = true;
Jon Ashburnd38bfb12014-10-14 19:15:22 -0600446}
447
Jon Ashburn876b1ac2014-10-17 15:09:07 -0600448static void loader_init_dispatch_table(XGL_LAYER_DISPATCH_TABLE *tab, GetProcAddrType fpGPA, XGL_PHYSICAL_GPU gpu)
Jon Ashburnd38bfb12014-10-14 19:15:22 -0600449{
450 tab->GetProcAddr = fpGPA;
451 tab->InitAndEnumerateGpus = fpGPA(gpu, (const XGL_CHAR *) "xglInitAndEnumerateGpus");
452 tab->GetGpuInfo = fpGPA(gpu, (const XGL_CHAR *) "xglGetGpuInfo");
453 tab->CreateDevice = fpGPA(gpu, (const XGL_CHAR *) "xglCreateDevice");
454 tab->DestroyDevice = fpGPA(gpu, (const XGL_CHAR *) "xglDestroyDevice");
455 tab->GetExtensionSupport = fpGPA(gpu, (const XGL_CHAR *) "xglGetExtensionSupport");
Jon Ashburnf7bcf9b2014-10-15 15:30:23 -0600456 tab->EnumerateLayers = fpGPA(gpu, (const XGL_CHAR *) "xglEnumerateLayers");
457 if (tab->EnumerateLayers == NULL)
458 tab->EnumerateLayers = xglEnumerateLayers;
Jon Ashburnd38bfb12014-10-14 19:15:22 -0600459 tab->GetDeviceQueue = fpGPA(gpu, (const XGL_CHAR *) "xglGetDeviceQueue");
460 tab->QueueSubmit = fpGPA(gpu, (const XGL_CHAR *) "xglQueueSubmit");
461 tab->QueueSetGlobalMemReferences = fpGPA(gpu, (const XGL_CHAR *) "xglQueueSetGlobalMemReferences");
462 tab->QueueWaitIdle = fpGPA(gpu, (const XGL_CHAR *) "xglQueueWaitIdle");
463 tab->DeviceWaitIdle = fpGPA(gpu, (const XGL_CHAR *) "xglDeviceWaitIdle");
464 tab->GetMemoryHeapCount = fpGPA(gpu, (const XGL_CHAR *) "xglGetMemoryHeapCount");
465 tab->GetMemoryHeapInfo = fpGPA(gpu, (const XGL_CHAR *) "xglGetMemoryHeapInfo");
466 tab->AllocMemory = fpGPA(gpu, (const XGL_CHAR *) "xglAllocMemory");
467 tab->FreeMemory = fpGPA(gpu, (const XGL_CHAR *) "xglFreeMemory");
468 tab->SetMemoryPriority = fpGPA(gpu, (const XGL_CHAR *) "xglSetMemoryPriority");
469 tab->MapMemory = fpGPA(gpu, (const XGL_CHAR *) "xglMapMemory");
470 tab->UnmapMemory = fpGPA(gpu, (const XGL_CHAR *) "xglUnmapMemory");
471 tab->PinSystemMemory = fpGPA(gpu, (const XGL_CHAR *) "xglPinSystemMemory");
472 tab->RemapVirtualMemoryPages = fpGPA(gpu, (const XGL_CHAR *) "xglRemapVirtualMemoryPages");
473 tab->GetMultiGpuCompatibility = fpGPA(gpu, (const XGL_CHAR *) "xglGetMultiGpuCompatibility");
474 tab->OpenSharedMemory = fpGPA(gpu, (const XGL_CHAR *) "xglOpenSharedMemory");
475 tab->OpenSharedQueueSemaphore = fpGPA(gpu, (const XGL_CHAR *) "xglOpenSharedQueueSemaphore");
476 tab->OpenPeerMemory = fpGPA(gpu, (const XGL_CHAR *) "xglOpenPeerMemory");
477 tab->OpenPeerImage = fpGPA(gpu, (const XGL_CHAR *) "xglOpenPeerImage");
478 tab->DestroyObject = fpGPA(gpu, (const XGL_CHAR *) "xglDestroyObject");
479 tab->GetObjectInfo = fpGPA(gpu, (const XGL_CHAR *) "xglGetObjectInfo");
480 tab->BindObjectMemory = fpGPA(gpu, (const XGL_CHAR *) "xglBindObjectMemory");
481 tab->CreateFence = fpGPA(gpu, (const XGL_CHAR *) "xglCreateFence");
482 tab->GetFenceStatus = fpGPA(gpu, (const XGL_CHAR *) "xglGetFenceStatus");
483 tab->WaitForFences = fpGPA(gpu, (const XGL_CHAR *) "xglWaitForFences");
484 tab->CreateQueueSemaphore = fpGPA(gpu, (const XGL_CHAR *) "xglCreateQueueSemaphore");
485 tab->SignalQueueSemaphore = fpGPA(gpu, (const XGL_CHAR *) "xglSignalQueueSemaphore");
486 tab->WaitQueueSemaphore = fpGPA(gpu, (const XGL_CHAR *) "xglWaitQueueSemaphore");
487 tab->CreateEvent = fpGPA(gpu, (const XGL_CHAR *) "xglCreateEvent");
488 tab->GetEventStatus = fpGPA(gpu, (const XGL_CHAR *) "xglGetEventStatus");
489 tab->SetEvent = fpGPA(gpu, (const XGL_CHAR *) "xglSetEvent");
490 tab->ResetEvent = fpGPA(gpu, (const XGL_CHAR *) "xglResetEvent");
491 tab->CreateQueryPool = fpGPA(gpu, (const XGL_CHAR *) "xglCreateQueryPool");
492 tab->GetQueryPoolResults = fpGPA(gpu, (const XGL_CHAR *) "xglGetQueryPoolResults");
493 tab->GetFormatInfo = fpGPA(gpu, (const XGL_CHAR *) "xglGetFormatInfo");
494 tab->CreateImage = fpGPA(gpu, (const XGL_CHAR *) "xglCreateImage");
495 tab->GetImageSubresourceInfo = fpGPA(gpu, (const XGL_CHAR *) "xglGetImageSubresourceInfo");
496 tab->CreateImageView = fpGPA(gpu, (const XGL_CHAR *) "xglCreateImageView");
497 tab->CreateColorAttachmentView = fpGPA(gpu, (const XGL_CHAR *) "xglCreateColorAttachmentView");
498 tab->CreateDepthStencilView = fpGPA(gpu, (const XGL_CHAR *) "xglCreateDepthStencilView");
499 tab->CreateShader = fpGPA(gpu, (const XGL_CHAR *) "xglCreateShader");
500 tab->CreateGraphicsPipeline = fpGPA(gpu, (const XGL_CHAR *) "xglCreateGraphicsPipeline");
501 tab->CreateComputePipeline = fpGPA(gpu, (const XGL_CHAR *) "xglCreateComputePipeline");
502 tab->StorePipeline = fpGPA(gpu, (const XGL_CHAR *) "xglStorePipeline");
503 tab->LoadPipeline = fpGPA(gpu, (const XGL_CHAR *) "xglLoadPipeline");
504 tab->CreatePipelineDelta = fpGPA(gpu, (const XGL_CHAR *) "xglCreatePipelineDelta");
505 tab->CreateSampler = fpGPA(gpu, (const XGL_CHAR *) "xglCreateSampler");
506 tab->CreateDescriptorSet = fpGPA(gpu, (const XGL_CHAR *) "xglCreateDescriptorSet");
507 tab->BeginDescriptorSetUpdate = fpGPA(gpu, (const XGL_CHAR *) "xglBeginDescriptorSetUpdate");
508 tab->EndDescriptorSetUpdate = fpGPA(gpu, (const XGL_CHAR *) "xglEndDescriptorSetUpdate");
509 tab->AttachSamplerDescriptors = fpGPA(gpu, (const XGL_CHAR *) "xglAttachSamplerDescriptors");
510 tab->AttachImageViewDescriptors = fpGPA(gpu, (const XGL_CHAR *) "xglAttachImageViewDescriptors");
511 tab->AttachMemoryViewDescriptors = fpGPA(gpu, (const XGL_CHAR *) "xglAttachMemoryViewDescriptors");
512 tab->AttachNestedDescriptors = fpGPA(gpu, (const XGL_CHAR *) "xglAttachNestedDescriptors");
513 tab->ClearDescriptorSetSlots = fpGPA(gpu, (const XGL_CHAR *) "xglClearDescriptorSetSlots");
514 tab->CreateViewportState = fpGPA(gpu, (const XGL_CHAR *) "xglCreateViewportState");
515 tab->CreateRasterState = fpGPA(gpu, (const XGL_CHAR *) "xglCreateRasterState");
516 tab->CreateMsaaState = fpGPA(gpu, (const XGL_CHAR *) "xglCreateMsaaState");
517 tab->CreateColorBlendState = fpGPA(gpu, (const XGL_CHAR *) "xglCreateColorBlendState");
518 tab->CreateDepthStencilState = fpGPA(gpu, (const XGL_CHAR *) "xglCreateDepthStencilState");
519 tab->CreateCommandBuffer = fpGPA(gpu, (const XGL_CHAR *) "xglCreateCommandBuffer");
520 tab->BeginCommandBuffer = fpGPA(gpu, (const XGL_CHAR *) "xglBeginCommandBuffer");
521 tab->EndCommandBuffer = fpGPA(gpu, (const XGL_CHAR *) "xglEndCommandBuffer");
522 tab->ResetCommandBuffer = fpGPA(gpu, (const XGL_CHAR *) "xglResetCommandBuffer");
523 tab->CmdBindPipeline = fpGPA(gpu, (const XGL_CHAR *) "xglCmdBindPipeline");
524 tab->CmdBindPipelineDelta = fpGPA(gpu, (const XGL_CHAR *) "xglCmdBindPipelineDelta");
525 tab->CmdBindStateObject = fpGPA(gpu, (const XGL_CHAR *) "xglCmdBindStateObject");
526 tab->CmdBindDescriptorSet = fpGPA(gpu, (const XGL_CHAR *) "xglCmdBindDescriptorSet");
527 tab->CmdBindDynamicMemoryView = fpGPA(gpu, (const XGL_CHAR *) "xglCmdBindDynamicMemoryView");
528 tab->CmdBindIndexData = fpGPA(gpu, (const XGL_CHAR *) "xglCmdBindIndexData");
529 tab->CmdBindAttachments = fpGPA(gpu, (const XGL_CHAR *) "xglCmdBindAttachments");
530 tab->CmdPrepareMemoryRegions = fpGPA(gpu, (const XGL_CHAR *) "xglCmdPrepareMemoryRegions");
531 tab->CmdPrepareImages = fpGPA(gpu, (const XGL_CHAR *) "xglCmdPrepareImages");
532 tab->CmdDraw = fpGPA(gpu, (const XGL_CHAR *) "xglCmdDraw");
533 tab->CmdDrawIndexed = fpGPA(gpu, (const XGL_CHAR *) "xglCmdDrawIndexed");
534 tab->CmdDrawIndirect = fpGPA(gpu, (const XGL_CHAR *) "xglCmdDrawIndirect");
535 tab->CmdDrawIndexedIndirect = fpGPA(gpu, (const XGL_CHAR *) "xglCmdDrawIndexedIndirect");
536 tab->CmdDispatch = fpGPA(gpu, (const XGL_CHAR *) "xglCmdDispatch");
537 tab->CmdDispatchIndirect = fpGPA(gpu, (const XGL_CHAR *) "xglCmdDispatchIndirect");
538 tab->CmdCopyMemory = fpGPA(gpu, (const XGL_CHAR *) "xglCmdCopyMemory");
539 tab->CmdCopyImage = fpGPA(gpu, (const XGL_CHAR *) "xglCmdCopyImage");
540 tab->CmdCopyMemoryToImage = fpGPA(gpu, (const XGL_CHAR *) "xglCmdCopyMemoryToImage");
541 tab->CmdCopyImageToMemory = fpGPA(gpu, (const XGL_CHAR *) "xglCmdCopyImageToMemory");
542 tab->CmdCloneImageData = fpGPA(gpu, (const XGL_CHAR *) "xglCmdCloneImageData");
543 tab->CmdUpdateMemory = fpGPA(gpu, (const XGL_CHAR *) "xglCmdUpdateMemory");
544 tab->CmdFillMemory = fpGPA(gpu, (const XGL_CHAR *) "xglCmdFillMemory");
545 tab->CmdClearColorImage = fpGPA(gpu, (const XGL_CHAR *) "xglCmdClearColorImage");
546 tab->CmdClearColorImageRaw = fpGPA(gpu, (const XGL_CHAR *) "xglCmdClearColorImageRaw");
547 tab->CmdClearDepthStencil = fpGPA(gpu, (const XGL_CHAR *) "xglCmdClearDepthStencil");
548 tab->CmdResolveImage = fpGPA(gpu, (const XGL_CHAR *) "xglCmdResolveImage");
549 tab->CmdSetEvent = fpGPA(gpu, (const XGL_CHAR *) "xglCmdSetEvent");
550 tab->CmdResetEvent = fpGPA(gpu, (const XGL_CHAR *) "xglCmdResetEvent");
551 tab->CmdMemoryAtomic = fpGPA(gpu, (const XGL_CHAR *) "xglCmdMemoryAtomic");
552 tab->CmdBeginQuery = fpGPA(gpu, (const XGL_CHAR *) "xglCmdBeginQuery");
553 tab->CmdEndQuery = fpGPA(gpu, (const XGL_CHAR *) "xglCmdEndQuery");
554 tab->CmdResetQueryPool = fpGPA(gpu, (const XGL_CHAR *) "xglCmdResetQueryPool");
555 tab->CmdWriteTimestamp = fpGPA(gpu, (const XGL_CHAR *) "xglCmdWriteTimestamp");
556 tab->CmdInitAtomicCounters = fpGPA(gpu, (const XGL_CHAR *) "xglCmdInitAtomicCounters");
557 tab->CmdLoadAtomicCounters = fpGPA(gpu, (const XGL_CHAR *) "xglCmdLoadAtomicCounters");
558 tab->CmdSaveAtomicCounters = fpGPA(gpu, (const XGL_CHAR *) "xglCmdSaveAtomicCounters");
559 tab->DbgSetValidationLevel = fpGPA(gpu, (const XGL_CHAR *) "xglDbgSetValidationLevel");
560 tab->DbgRegisterMsgCallback = fpGPA(gpu, (const XGL_CHAR *) "xglDbgRegisterMsgCallback");
561 tab->DbgUnregisterMsgCallback = fpGPA(gpu, (const XGL_CHAR *) "xglDbgUnregisterMsgCallback");
562 tab->DbgSetMessageFilter = fpGPA(gpu, (const XGL_CHAR *) "xglDbgSetMessageFilter");
563 tab->DbgSetObjectTag = fpGPA(gpu, (const XGL_CHAR *) "xglDbgSetObjectTag");
564 tab->DbgSetGlobalOption = fpGPA(gpu, (const XGL_CHAR *) "xglDbgSetGlobalOption");
565 tab->DbgSetDeviceOption = fpGPA(gpu, (const XGL_CHAR *) "xglDbgSetDeviceOption");
566 tab->CmdDbgMarkerBegin = fpGPA(gpu, (const XGL_CHAR *) "xglCmdDbgMarkerBegin");
567 tab->CmdDbgMarkerEnd = fpGPA(gpu, (const XGL_CHAR *) "xglCmdDbgMarkerEnd");
568 tab->WsiX11AssociateConnection = fpGPA(gpu, (const XGL_CHAR *) "xglWsiX11AssociateConnection");
569 tab->WsiX11GetMSC = fpGPA(gpu, (const XGL_CHAR *) "xglWsiX11GetMSC");
570 tab->WsiX11CreatePresentableImage = fpGPA(gpu, (const XGL_CHAR *) "xglWsiX11CreatePresentableImage");
571 tab->WsiX11QueuePresent = fpGPA(gpu, (const XGL_CHAR *) "xglWsiX11QueuePresent");
572}
573
Jon Ashburn876b1ac2014-10-17 15:09:07 -0600574static struct loader_icd * loader_get_icd(const XGL_BASE_LAYER_OBJECT *gpu, XGL_UINT *gpu_index)
575{
576 for (struct loader_icd * icd = loader.icds; icd; icd = icd->next) {
577 for (XGL_UINT i = 0; i < icd->gpu_count; i++)
Jon Ashburn6b4d70c2014-10-22 18:13:16 -0600578 if ((icd->gpus + i) == gpu || (icd->gpus +i)->baseObject == gpu->baseObject) {
Jon Ashburn876b1ac2014-10-17 15:09:07 -0600579 *gpu_index = i;
580 return icd;
581 }
582 }
583 return NULL;
584}
585
Jon Ashburn6b4d70c2014-10-22 18:13:16 -0600586static bool loader_layers_activated(const struct loader_icd *icd, const XGL_UINT gpu_index)
Jon Ashburn876b1ac2014-10-17 15:09:07 -0600587{
Jon Ashburn6b4d70c2014-10-22 18:13:16 -0600588 if (icd->layer_count[gpu_index])
589 return true;
590 else
591 return false;
Jon Ashburn876b1ac2014-10-17 15:09:07 -0600592}
593
Jon Ashburn6b4d70c2014-10-22 18:13:16 -0600594static void loader_init_layer_libs(struct loader_icd *icd, XGL_UINT gpu_index, XGL_CHAR ** ppLayerNames, XGL_UINT count)
Jon Ashburnd38bfb12014-10-14 19:15:22 -0600595{
Jon Ashburn6b4d70c2014-10-22 18:13:16 -0600596 if (!icd)
597 return;
Jon Ashburndf7d5842014-10-16 15:48:50 -0600598
Jon Ashburn6b4d70c2014-10-22 18:13:16 -0600599 struct loader_layers *obj;
600 bool foundLib;
601 for (XGL_UINT i = 0; i < count; i++) {
602 foundLib = false;
603 for (XGL_UINT j = 0; j < icd->layer_count[gpu_index]; j++) {
604 if (icd->layer_libs[gpu_index][j].lib_handle && !strcmp(icd->layer_libs[gpu_index][j].lib_name, (char *) ppLayerNames[i])) {
605 foundLib = true;
606 break;
607 }
608 }
609 if (!foundLib) {
610 obj = &(icd->layer_libs[gpu_index][i]);
611 strncpy(obj->lib_name, (char *) ppLayerNames[i], sizeof(obj->lib_name) - 1);
612 obj->lib_name[sizeof(obj->lib_name) - 1] = '\0';
613 if ((obj->lib_handle = dlopen(obj->lib_name, RTLD_LAZY | RTLD_DEEPBIND)) == NULL) {
614 loader_log(XGL_DBG_MSG_ERROR, 0, "Failed to open layer library %s got error %d", obj->lib_name, dlerror());
Jon Ashburnd38bfb12014-10-14 19:15:22 -0600615 continue;
616 } else {
Jon Ashburn6b4d70c2014-10-22 18:13:16 -0600617 loader_log(XGL_DBG_MSG_UNKNOWN, 0, "Inserting layer lib %s", obj->lib_name);
Jon Ashburnd38bfb12014-10-14 19:15:22 -0600618 }
Jon Ashburnd09bd102014-10-22 21:15:26 -0600619 free(ppLayerNames[i]);
Jon Ashburn6b4d70c2014-10-22 18:13:16 -0600620 icd->layer_count[gpu_index]++;
Jon Ashburnd38bfb12014-10-14 19:15:22 -0600621 }
Jon Ashburnd38bfb12014-10-14 19:15:22 -0600622 }
Jon Ashburnd38bfb12014-10-14 19:15:22 -0600623}
624
Jon Ashburn6b4d70c2014-10-22 18:13:16 -0600625static XGL_UINT loader_get_layer_env(XGL_CHAR * *ppLayerNames)
Jon Ashburnd38bfb12014-10-14 19:15:22 -0600626{
Jon Ashburn6b4d70c2014-10-22 18:13:16 -0600627 const char *layerEnv;
628 XGL_UINT len, count = 0;
Jon Ashburnd09bd102014-10-22 21:15:26 -0600629 char *p, *pOrig, *next, *name;
Jon Ashburnd38bfb12014-10-14 19:15:22 -0600630
Jon Ashburn6b4d70c2014-10-22 18:13:16 -0600631 layerEnv = getenv("LIBXGL_LAYER_LIBS");
632 p = malloc(strlen(layerEnv) + 1);
633 if (!p)
634 return 0;
635 strcpy(p, layerEnv);
Jon Ashburnd09bd102014-10-22 21:15:26 -0600636 pOrig = p;
Jon Ashburnd38bfb12014-10-14 19:15:22 -0600637
Jon Ashburn6b4d70c2014-10-22 18:13:16 -0600638 while (p && *p && count < MAX_LAYER_LIBRARIES) {
639 bool foundScanned = false;
640 unsigned int j;
Jon Ashburnd38bfb12014-10-14 19:15:22 -0600641 next = strchr(p, ':');
642 if (next == NULL) {
643 len = strlen(p);
644 next = p + len;
645 }
646 else {
647 len = next - p;
648 *(char *) next = '\0';
649 next++;
650 }
Jon Ashburn6b4d70c2014-10-22 18:13:16 -0600651 name = basename(p);
652 for (j = 0; j < loader.scanned_layer_count; j++) {
653 if (!strcmp(basename(loader.scanned_layer_names[j]), name)) {
654 foundScanned = true;
655 break;
656 }
657 }
658 if (!foundScanned) {
659 p = next;
660 continue;
661 }
Jon Ashburnd38bfb12014-10-14 19:15:22 -0600662
Jon Ashburn6b4d70c2014-10-22 18:13:16 -0600663 //copy to convert any dir path differences between scanned and base names
664 len = strlen(loader.scanned_layer_names[j]);
665 ppLayerNames[count] = malloc(len + 1);
Jon Ashburnd09bd102014-10-22 21:15:26 -0600666 if (!ppLayerNames[count]) {
667 free(pOrig);
Jon Ashburn6b4d70c2014-10-22 18:13:16 -0600668 return count;
Jon Ashburnd09bd102014-10-22 21:15:26 -0600669 }
Jon Ashburn6b4d70c2014-10-22 18:13:16 -0600670 strncpy((char *) ppLayerNames[count], loader.scanned_layer_names[j], len);
671 ppLayerNames[count][len] = '\0';
672 count++;
Jon Ashburnd38bfb12014-10-14 19:15:22 -0600673 p = next;
674
Jon Ashburn6b4d70c2014-10-22 18:13:16 -0600675 };
Jon Ashburnd38bfb12014-10-14 19:15:22 -0600676
Jon Ashburnd09bd102014-10-22 21:15:26 -0600677 free(pOrig);
Jon Ashburn6b4d70c2014-10-22 18:13:16 -0600678 return count;
Jon Ashburnd38bfb12014-10-14 19:15:22 -0600679}
680
Jon Ashburn6b4d70c2014-10-22 18:13:16 -0600681static XGL_UINT loader_get_layer_libs(const XGL_DEVICE_CREATE_INFO* pCreateInfo, XGL_CHAR *** ppLayerNames)
682{
683 static XGL_CHAR *layerNames[MAX_LAYER_LIBRARIES];
684
685 *ppLayerNames = &layerNames[0];
686 if (!pCreateInfo) {
687 return loader_get_layer_env(layerNames);
688 }
689
690 XGL_LAYER_CREATE_INFO *pCi = (XGL_LAYER_CREATE_INFO *) pCreateInfo->pNext;
691
692 while (pCi) {
693 if (pCi->sType == XGL_STRUCTURE_TYPE_LAYER_CREATE_INFO) {
694 const char *name;
695 XGL_UINT len;
696 unsigned int j;
697 for (XGL_UINT i = 0; i < pCi->layerCount; i++) {
698 bool foundScanned = false;
699 name = (const char *) *(pCi->ppActiveLayerNames + i);
700 for (j = 0; j < loader.scanned_layer_count; j++) {
701 if (!strcmp(basename(loader.scanned_layer_names[j]), basename(name))) {
702 foundScanned = true;
703 break;
704 }
705 }
706 if (!foundScanned)
707 return loader_get_layer_env(layerNames);
708 //copy to convert any dir path differences between scanned and base names
709 len = strlen(loader.scanned_layer_names[j]);
710 layerNames[i] = malloc(len + 1);
711 if (!layerNames[i])
712 return i;
713 strncpy((char *) layerNames[i], loader.scanned_layer_names[j], len);
714 layerNames[i][len] = '\0';
715 }
716 return pCi->layerCount;
717 }
718 pCi = pCi->pNext;
719 }
720 return loader_get_layer_env(layerNames);
721}
722
723static void loader_deactivate_layer()
724{
725 struct loader_icd *icd;
726 struct loader_layers *libs;
727
728 for (icd = loader.icds; icd; icd = icd->next) {
Jon Ashburn6b4d70c2014-10-22 18:13:16 -0600729 if (icd->gpus)
730 free(icd->gpus);
731 icd->gpus = NULL;
732 if (icd->loader_dispatch)
733 free(icd->loader_dispatch);
734 icd->loader_dispatch = NULL;
735 icd->SetDispatch(NULL, true);
736 for (XGL_UINT j = 0; j < icd->gpu_count; j++) {
737 if (icd->layer_count[j] > 0) {
738 for (XGL_UINT i = 0; i < icd->layer_count[j]; i++) {
739 libs = &(icd->layer_libs[j][i]);
740 if (libs->lib_handle)
741 dlclose(libs->lib_handle);
742 libs->lib_handle = NULL;
743 }
Jon Ashburnd09bd102014-10-22 21:15:26 -0600744 if (icd->wrappedGpus[j])
745 free(icd->wrappedGpus[j]);
Jon Ashburn6b4d70c2014-10-22 18:13:16 -0600746 }
747 icd->layer_count[j] = 0;
748 }
749 icd->gpu_count = 0;
750 }
751}
752
753extern XGL_UINT ActivateLayers(XGL_PHYSICAL_GPU *gpu, const XGL_DEVICE_CREATE_INFO* pCreateInfo)
754{
755 XGL_UINT gpu_index;
756 XGL_UINT count;
757 XGL_CHAR ** ppLayerNames;
758 struct loader_icd *icd = loader_get_icd((const XGL_BASE_LAYER_OBJECT *) *gpu, &gpu_index);
759
760 if (!icd)
761 return 0;
762 assert(gpu_index < XGL_MAX_PHYSICAL_GPUS);
763
764 /* activate any layer libraries */
765 if (!loader_layers_activated(icd, gpu_index)) {
766 XGL_BASE_LAYER_OBJECT *gpuObj = (XGL_BASE_LAYER_OBJECT *) *gpu;
767 XGL_BASE_LAYER_OBJECT *nextGpuObj;
768 GetProcAddrType nextGPA = xglGetProcAddr;
769
770 count = loader_get_layer_libs(pCreateInfo, &ppLayerNames);
771 if (!count)
772 return 0;
773 loader_init_layer_libs(icd, gpu_index, ppLayerNames, count);
774
Jon Ashburnd09bd102014-10-22 21:15:26 -0600775 icd->wrappedGpus[gpu_index] = malloc(sizeof(XGL_BASE_LAYER_OBJECT) * icd->layer_count[gpu_index]);
776 if (! icd->wrappedGpus[gpu_index])
777 loader_log(XGL_DBG_MSG_ERROR, 0, "Failed to malloc Gpu objects for layer");
Jon Ashburn6b4d70c2014-10-22 18:13:16 -0600778 for (XGL_INT i = icd->layer_count[gpu_index] - 1; i >= 0; i--) {
Jon Ashburnd09bd102014-10-22 21:15:26 -0600779 nextGpuObj = (icd->wrappedGpus[gpu_index] + i);
Jon Ashburn6b4d70c2014-10-22 18:13:16 -0600780 nextGpuObj->pGPA = nextGPA;
781 nextGpuObj->baseObject = gpuObj->baseObject;
782 nextGpuObj->nextObject = gpuObj;
783 gpuObj = nextGpuObj;
784
785 nextGPA = dlsym(icd->layer_libs[gpu_index][i].lib_handle, "xglGetProcAddr");
786 if (!nextGPA) {
787 loader_log(XGL_DBG_MSG_ERROR, 0, "Failed to find xglGetProcAddr in layer %s", icd->layer_libs[gpu_index][i].lib_name);
788 continue;
789 }
790
791 if (i == 0)
792 loader_init_dispatch_table(icd->loader_dispatch + gpu_index, nextGPA, gpuObj);
793
794 }
795 *gpu = ((XGL_PHYSICAL_GPU *) gpuObj);
796 }
797 else {
798 //make sure requested Layers matches currently activated Layers
799 count = loader_get_layer_libs(pCreateInfo, &ppLayerNames);
800 for (XGL_UINT i = 0; i < count; i++) {
801 if (strcmp(icd->layer_libs[gpu_index][i].lib_name, (char *) *(ppLayerNames + i))) {
802 loader_log(XGL_DBG_MSG_ERROR, 0, "Layers activated != Layers requested");
803 break;
804 }
805 }
806 if (count != icd->layer_count[gpu_index]) {
807 loader_log(XGL_DBG_MSG_ERROR, 0, "Number of Layers activated!= number requested");
808 }
809 }
810 return icd->layer_count[gpu_index];
811}
Jon Ashburnd38bfb12014-10-14 19:15:22 -0600812
Jon Ashburne50fae52014-10-17 15:31:22 -0600813LOADER_EXPORT XGL_VOID * XGLAPI xglGetProcAddr(XGL_PHYSICAL_GPU gpu, const XGL_CHAR * pName) {
Jon Ashburnd38bfb12014-10-14 19:15:22 -0600814
815 if (gpu == NULL)
816 return NULL;
Jon Ashburn891537f2014-10-22 12:42:13 -0600817 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
818 XGL_LAYER_DISPATCH_TABLE * disp_table = * (XGL_LAYER_DISPATCH_TABLE **) gpuw->nextObject;
Jon Ashburnd38bfb12014-10-14 19:15:22 -0600819
Jon Ashburnd38bfb12014-10-14 19:15:22 -0600820 if (disp_table == NULL)
821 return NULL;
822
823 if (!strncmp("xglGetProcAddr", (const char *) pName, sizeof("xglGetProcAddr")))
824 return xglGetProcAddr;
825 else if (!strncmp("xglInitAndEnumerateGpus", (const char *) pName, sizeof("xglInitAndEnumerateGpus")))
826 return disp_table->InitAndEnumerateGpus;
827 else if (!strncmp("xglGetGpuInfo", (const char *) pName, sizeof ("xglGetGpuInfo")))
828 return disp_table->GetGpuInfo;
829 else if (!strncmp("xglCreateDevice", (const char *) pName, sizeof ("xglCreateDevice")))
830 return disp_table->CreateDevice;
831 else if (!strncmp("xglDestroyDevice", (const char *) pName, sizeof ("xglDestroyDevice")))
832 return disp_table->DestroyDevice;
833 else if (!strncmp("xglGetExtensionSupport", (const char *) pName, sizeof ("xglGetExtensionSupport")))
834 return disp_table->GetExtensionSupport;
Jon Ashburnf7bcf9b2014-10-15 15:30:23 -0600835 else if (!strncmp("xglEnumerateLayers", (const char *) pName, sizeof ("xglEnumerateLayers")))
836 return disp_table->EnumerateLayers;
Jon Ashburnd38bfb12014-10-14 19:15:22 -0600837 else if (!strncmp("xglGetDeviceQueue", (const char *) pName, sizeof ("xglGetDeviceQueue")))
838 return disp_table->GetDeviceQueue;
839 else if (!strncmp("xglQueueSubmit", (const char *) pName, sizeof ("xglQueueSubmit")))
840 return disp_table->QueueSubmit;
841 else if (!strncmp("xglQueueSetGlobalMemReferences", (const char *) pName, sizeof ("xglQueueSetGlobalMemReferences")))
842 return disp_table->QueueSetGlobalMemReferences;
843 else if (!strncmp("xglQueueWaitIdle", (const char *) pName, sizeof ("xglQueueWaitIdle")))
844 return disp_table->QueueWaitIdle;
845 else if (!strncmp("xglDeviceWaitIdle", (const char *) pName, sizeof ("xglDeviceWaitIdle")))
846 return disp_table->DeviceWaitIdle;
847 else if (!strncmp("xglGetMemoryHeapCount", (const char *) pName, sizeof ("xglGetMemoryHeapCount")))
848 return disp_table->GetMemoryHeapCount;
849 else if (!strncmp("xglGetMemoryHeapInfo", (const char *) pName, sizeof ("xglGetMemoryHeapInfo")))
850 return disp_table->GetMemoryHeapInfo;
851 else if (!strncmp("xglAllocMemory", (const char *) pName, sizeof ("xglAllocMemory")))
852 return disp_table->AllocMemory;
853 else if (!strncmp("xglFreeMemory", (const char *) pName, sizeof ("xglFreeMemory")))
854 return disp_table->FreeMemory;
855 else if (!strncmp("xglSetMemoryPriority", (const char *) pName, sizeof ("xglSetMemoryPriority")))
856 return disp_table->SetMemoryPriority;
857 else if (!strncmp("xglMapMemory", (const char *) pName, sizeof ("xglMapMemory")))
858 return disp_table->MapMemory;
859 else if (!strncmp("xglUnmapMemory", (const char *) pName, sizeof ("xglUnmapMemory")))
860 return disp_table->UnmapMemory;
861 else if (!strncmp("xglPinSystemMemory", (const char *) pName, sizeof ("xglPinSystemMemory")))
862 return disp_table->PinSystemMemory;
863 else if (!strncmp("xglRemapVirtualMemoryPages", (const char *) pName, sizeof ("xglRemapVirtualMemoryPages")))
864 return disp_table->RemapVirtualMemoryPages;
865 else if (!strncmp("xglGetMultiGpuCompatibility", (const char *) pName, sizeof ("xglGetMultiGpuCompatibility")))
866 return disp_table->GetMultiGpuCompatibility;
867 else if (!strncmp("xglOpenSharedMemory", (const char *) pName, sizeof ("xglOpenSharedMemory")))
868 return disp_table->OpenSharedMemory;
869 else if (!strncmp("xglOpenSharedQueueSemaphore", (const char *) pName, sizeof ("xglOpenSharedQueueSemaphore")))
870 return disp_table->OpenSharedQueueSemaphore;
871 else if (!strncmp("xglOpenPeerMemory", (const char *) pName, sizeof ("xglOpenPeerMemory")))
872 return disp_table->OpenPeerMemory;
873 else if (!strncmp("xglOpenPeerImage", (const char *) pName, sizeof ("xglOpenPeerImage")))
874 return disp_table->OpenPeerImage;
875 else if (!strncmp("xglDestroyObject", (const char *) pName, sizeof ("xglDestroyObject")))
876 return disp_table->DestroyObject;
877 else if (!strncmp("xglGetObjectInfo", (const char *) pName, sizeof ("xglGetObjectInfo")))
878 return disp_table->GetObjectInfo;
879 else if (!strncmp("xglBindObjectMemory", (const char *) pName, sizeof ("xglBindObjectMemory")))
880 return disp_table->BindObjectMemory;
881 else if (!strncmp("xglCreateFence", (const char *) pName, sizeof ("xgllCreateFence")))
882 return disp_table->CreateFence;
883 else if (!strncmp("xglGetFenceStatus", (const char *) pName, sizeof ("xglGetFenceStatus")))
884 return disp_table->GetFenceStatus;
885 else if (!strncmp("xglWaitForFences", (const char *) pName, sizeof ("xglWaitForFences")))
886 return disp_table->WaitForFences;
887 else if (!strncmp("xglCreateQueueSemaphore", (const char *) pName, sizeof ("xgllCreateQueueSemaphore")))
888 return disp_table->CreateQueueSemaphore;
889 else if (!strncmp("xglSignalQueueSemaphore", (const char *) pName, sizeof ("xglSignalQueueSemaphore")))
890 return disp_table->SignalQueueSemaphore;
891 else if (!strncmp("xglWaitQueueSemaphore", (const char *) pName, sizeof ("xglWaitQueueSemaphore")))
892 return disp_table->WaitQueueSemaphore;
893 else if (!strncmp("xglCreateEvent", (const char *) pName, sizeof ("xgllCreateEvent")))
894 return disp_table->CreateEvent;
895 else if (!strncmp("xglGetEventStatus", (const char *) pName, sizeof ("xglGetEventStatus")))
896 return disp_table->GetEventStatus;
897 else if (!strncmp("xglSetEvent", (const char *) pName, sizeof ("xglSetEvent")))
898 return disp_table->SetEvent;
899 else if (!strncmp("xglResetEvent", (const char *) pName, sizeof ("xgllResetEvent")))
900 return disp_table->ResetEvent;
901 else if (!strncmp("xglCreateQueryPool", (const char *) pName, sizeof ("xglCreateQueryPool")))
902 return disp_table->CreateQueryPool;
903 else if (!strncmp("xglGetQueryPoolResults", (const char *) pName, sizeof ("xglGetQueryPoolResults")))
904 return disp_table->GetQueryPoolResults;
905 else if (!strncmp("xglGetFormatInfo", (const char *) pName, sizeof ("xglGetFormatInfo")))
906 return disp_table->GetFormatInfo;
907 else if (!strncmp("xglCreateImage", (const char *) pName, sizeof ("xglCreateImage")))
908 return disp_table->CreateImage;
909 else if (!strncmp("xglGetImageSubresourceInfo", (const char *) pName, sizeof ("xglGetImageSubresourceInfo")))
910 return disp_table->GetImageSubresourceInfo;
911 else if (!strncmp("xglCreateImageView", (const char *) pName, sizeof ("xglCreateImageView")))
912 return disp_table->CreateImageView;
913 else if (!strncmp("xglCreateColorAttachmentView", (const char *) pName, sizeof ("xglCreateColorAttachmentView")))
914 return disp_table->CreateColorAttachmentView;
915 else if (!strncmp("xglCreateDepthStencilView", (const char *) pName, sizeof ("xglCreateDepthStencilView")))
916 return disp_table->CreateDepthStencilView;
917 else if (!strncmp("xglCreateShader", (const char *) pName, sizeof ("xglCreateShader")))
918 return disp_table->CreateShader;
919 else if (!strncmp("xglCreateGraphicsPipeline", (const char *) pName, sizeof ("xglCreateGraphicsPipeline")))
920 return disp_table->CreateGraphicsPipeline;
921 else if (!strncmp("xglCreateComputePipeline", (const char *) pName, sizeof ("xglCreateComputePipeline")))
922 return disp_table->CreateComputePipeline;
923 else if (!strncmp("xglStorePipeline", (const char *) pName, sizeof ("xglStorePipeline")))
924 return disp_table->StorePipeline;
925 else if (!strncmp("xglLoadPipeline", (const char *) pName, sizeof ("xglLoadPipeline")))
926 return disp_table->LoadPipeline;
927 else if (!strncmp("xglCreatePipelineDelta", (const char *) pName, sizeof ("xglCreatePipelineDelta")))
928 return disp_table->CreatePipelineDelta;
929 else if (!strncmp("xglCreateSampler", (const char *) pName, sizeof ("xglCreateSampler")))
930 return disp_table->CreateSampler;
931 else if (!strncmp("xglCreateDescriptorSet", (const char *) pName, sizeof ("xglCreateDescriptorSet")))
932 return disp_table->CreateDescriptorSet;
933 else if (!strncmp("xglBeginDescriptorSetUpdate", (const char *) pName, sizeof ("xglBeginDescriptorSetUpdate")))
934 return disp_table->BeginDescriptorSetUpdate;
935 else if (!strncmp("xglEndDescriptorSetUpdate", (const char *) pName, sizeof ("xglEndDescriptorSetUpdate")))
936 return disp_table->EndDescriptorSetUpdate;
937 else if (!strncmp("xglAttachSamplerDescriptors", (const char *) pName, sizeof ("xglAttachSamplerDescriptors")))
938 return disp_table->AttachSamplerDescriptors;
939 else if (!strncmp("xglAttachImageViewDescriptors", (const char *) pName, sizeof ("xglAttachImageViewDescriptors")))
940 return disp_table->AttachImageViewDescriptors;
941 else if (!strncmp("xglAttachMemoryViewDescriptors", (const char *) pName, sizeof ("xglAttachMemoryViewDescriptors")))
942 return disp_table->AttachMemoryViewDescriptors;
943 else if (!strncmp("xglAttachNestedDescriptors", (const char *) pName, sizeof ("xglAttachNestedDescriptors")))
944 return disp_table->AttachNestedDescriptors;
945 else if (!strncmp("xglClearDescriptorSetSlots", (const char *) pName, sizeof ("xglClearDescriptorSetSlots")))
946 return disp_table->ClearDescriptorSetSlots;
947 else if (!strncmp("xglCreateViewportState", (const char *) pName, sizeof ("xglCreateViewportState")))
948 return disp_table->CreateViewportState;
949 else if (!strncmp("xglCreateRasterState", (const char *) pName, sizeof ("xglCreateRasterState")))
950 return disp_table->CreateRasterState;
951 else if (!strncmp("xglCreateMsaaState", (const char *) pName, sizeof ("xglCreateMsaaState")))
952 return disp_table->CreateMsaaState;
953 else if (!strncmp("xglCreateColorBlendState", (const char *) pName, sizeof ("xglCreateColorBlendState")))
954 return disp_table->CreateColorBlendState;
955 else if (!strncmp("xglCreateDepthStencilState", (const char *) pName, sizeof ("xglCreateDepthStencilState")))
956 return disp_table->CreateDepthStencilState;
957 else if (!strncmp("xglCreateCommandBuffer", (const char *) pName, sizeof ("xglCreateCommandBuffer")))
958 return disp_table->CreateCommandBuffer;
959 else if (!strncmp("xglBeginCommandBuffer", (const char *) pName, sizeof ("xglBeginCommandBuffer")))
960 return disp_table->BeginCommandBuffer;
961 else if (!strncmp("xglEndCommandBuffer", (const char *) pName, sizeof ("xglEndCommandBuffer")))
962 return disp_table->EndCommandBuffer;
963 else if (!strncmp("xglResetCommandBuffer", (const char *) pName, sizeof ("xglResetCommandBuffer")))
964 return disp_table->ResetCommandBuffer;
965 else if (!strncmp("xglCmdBindPipeline", (const char *) pName, sizeof ("xglCmdBindPipeline")))
966 return disp_table->CmdBindPipeline;
967 else if (!strncmp("xglCmdBindPipelineDelta", (const char *) pName, sizeof ("xglCmdBindPipelineDelta")))
968 return disp_table->CmdBindPipelineDelta;
969 else if (!strncmp("xglCmdBindStateObject", (const char *) pName, sizeof ("xglCmdBindStateObject")))
970 return disp_table->CmdBindStateObject;
971 else if (!strncmp("xglCmdBindDescriptorSet", (const char *) pName, sizeof ("xglCmdBindDescriptorSet")))
972 return disp_table->CmdBindDescriptorSet;
973 else if (!strncmp("xglCmdBindDynamicMemoryView", (const char *) pName, sizeof ("xglCmdBindDynamicMemoryView")))
974 return disp_table->CmdBindDynamicMemoryView;
975 else if (!strncmp("xglCmdBindIndexData", (const char *) pName, sizeof ("xglCmdBindIndexData")))
976 return disp_table->CmdBindIndexData;
977 else if (!strncmp("xglCmdBindAttachments", (const char *) pName, sizeof ("xglCmdBindAttachments")))
978 return disp_table->CmdBindAttachments;
979 else if (!strncmp("xglCmdPrepareMemoryRegions", (const char *) pName, sizeof ("xglCmdPrepareMemoryRegions")))
980 return disp_table->CmdPrepareMemoryRegions;
981 else if (!strncmp("xglCmdPrepareImages", (const char *) pName, sizeof ("xglCmdPrepareImages")))
982 return disp_table->CmdPrepareImages;
983 else if (!strncmp("xglCmdDraw", (const char *) pName, sizeof ("xglCmdDraw")))
984 return disp_table->CmdDraw;
985 else if (!strncmp("xglCmdDrawIndexed", (const char *) pName, sizeof ("xglCmdDrawIndexed")))
986 return disp_table->CmdDrawIndexed;
987 else if (!strncmp("xglCmdDrawIndirect", (const char *) pName, sizeof ("xglCmdDrawIndirect")))
988 return disp_table->CmdDrawIndirect;
989 else if (!strncmp("xglCmdDrawIndexedIndirect", (const char *) pName, sizeof ("xglCmdDrawIndexedIndirect")))
990 return disp_table->CmdDrawIndexedIndirect;
991 else if (!strncmp("xglCmdDispatch", (const char *) pName, sizeof ("xglCmdDispatch")))
992 return disp_table->CmdDispatch;
993 else if (!strncmp("xglCmdDispatchIndirect", (const char *) pName, sizeof ("xglCmdDispatchIndirect")))
994 return disp_table->CmdDispatchIndirect;
995 else if (!strncmp("xglCmdCopyMemory", (const char *) pName, sizeof ("xglCmdCopyMemory")))
996 return disp_table->CmdCopyMemory;
997 else if (!strncmp("xglCmdCopyImage", (const char *) pName, sizeof ("xglCmdCopyImage")))
998 return disp_table->CmdCopyImage;
999 else if (!strncmp("xglCmdCopyMemoryToImage", (const char *) pName, sizeof ("xglCmdCopyMemoryToImage")))
1000 return disp_table->CmdCopyMemoryToImage;
1001 else if (!strncmp("xglCmdCopyImageToMemory", (const char *) pName, sizeof ("xglCmdCopyImageToMemory")))
1002 return disp_table->CmdCopyImageToMemory;
1003 else if (!strncmp("xglCmdCloneImageData", (const char *) pName, sizeof ("xglCmdCloneImageData")))
1004 return disp_table->CmdCloneImageData;
1005 else if (!strncmp("xglCmdUpdateMemory", (const char *) pName, sizeof ("xglCmdUpdateMemory")))
1006 return disp_table->CmdUpdateMemory;
1007 else if (!strncmp("xglCmdFillMemory", (const char *) pName, sizeof ("xglCmdFillMemory")))
1008 return disp_table->CmdFillMemory;
1009 else if (!strncmp("xglCmdClearColorImage", (const char *) pName, sizeof ("xglCmdClearColorImage")))
1010 return disp_table->CmdClearColorImage;
1011 else if (!strncmp("xglCmdClearColorImageRaw", (const char *) pName, sizeof ("xglCmdClearColorImageRaw")))
1012 return disp_table->CmdClearColorImageRaw;
1013 else if (!strncmp("xglCmdClearDepthStencil", (const char *) pName, sizeof ("xglCmdClearDepthStencil")))
1014 return disp_table->CmdClearDepthStencil;
1015 else if (!strncmp("xglCmdResolveImage", (const char *) pName, sizeof ("xglCmdResolveImage")))
1016 return disp_table->CmdResolveImage;
1017 else if (!strncmp("xglCmdSetEvent", (const char *) pName, sizeof ("xglCmdSetEvent")))
1018 return disp_table->CmdSetEvent;
1019 else if (!strncmp("xglCmdResetEvent", (const char *) pName, sizeof ("xglCmdResetEvent")))
1020 return disp_table->CmdResetEvent;
1021 else if (!strncmp("xglCmdMemoryAtomic", (const char *) pName, sizeof ("xglCmdMemoryAtomic")))
1022 return disp_table->CmdMemoryAtomic;
1023 else if (!strncmp("xglCmdBeginQuery", (const char *) pName, sizeof ("xglCmdBeginQuery")))
1024 return disp_table->CmdBeginQuery;
1025 else if (!strncmp("xglCmdEndQuery", (const char *) pName, sizeof ("xglCmdEndQuery")))
1026 return disp_table->CmdEndQuery;
1027 else if (!strncmp("xglCmdResetQueryPool", (const char *) pName, sizeof ("xglCmdResetQueryPool")))
1028 return disp_table->CmdResetQueryPool;
1029 else if (!strncmp("xglCmdWriteTimestamp", (const char *) pName, sizeof ("xglCmdWriteTimestamp")))
1030 return disp_table->CmdWriteTimestamp;
1031 else if (!strncmp("xglCmdInitAtomicCounters", (const char *) pName, sizeof ("xglCmdInitAtomicCounters")))
1032 return disp_table->CmdInitAtomicCounters;
1033 else if (!strncmp("xglCmdLoadAtomicCounters", (const char *) pName, sizeof ("xglCmdLoadAtomicCounters")))
1034 return disp_table->CmdLoadAtomicCounters;
1035 else if (!strncmp("xglCmdSaveAtomicCounters", (const char *) pName, sizeof ("xglCmdSaveAtomicCounters")))
1036 return disp_table->CmdSaveAtomicCounters;
1037 else if (!strncmp("xglDbgSetValidationLevel", (const char *) pName, sizeof ("xglDbgSetValidationLevel")))
1038 return disp_table->DbgSetValidationLevel;
1039 else if (!strncmp("xglDbgRegisterMsgCallback", (const char *) pName, sizeof ("xglDbgRegisterMsgCallback")))
1040 return disp_table->DbgRegisterMsgCallback;
1041 else if (!strncmp("xglDbgUnregisterMsgCallback", (const char *) pName, sizeof ("xglDbgUnregisterMsgCallback")))
1042 return disp_table->DbgUnregisterMsgCallback;
1043 else if (!strncmp("xglDbgSetMessageFilter", (const char *) pName, sizeof ("xglDbgSetMessageFilter")))
1044 return disp_table->DbgSetMessageFilter;
1045 else if (!strncmp("xglDbgSetObjectTag", (const char *) pName, sizeof ("xglDbgSetObjectTag")))
1046 return disp_table->DbgSetObjectTag;
1047 else if (!strncmp("xglDbgSetGlobalOption", (const char *) pName, sizeof ("xglDbgSetGlobalOption")))
1048 return disp_table->DbgSetGlobalOption;
1049 else if (!strncmp("xglDbgSetDeviceOption", (const char *) pName, sizeof ("xglDbgSetDeviceOption")))
1050 return disp_table->DbgSetDeviceOption;
1051 else if (!strncmp("xglCmdDbgMarkerBegin", (const char *) pName, sizeof ("xglCmdDbgMarkerBegin")))
1052 return disp_table->CmdDbgMarkerBegin;
1053 else if (!strncmp("xglCmdDbgMarkerEnd", (const char *) pName, sizeof ("xglCmdDbgMarkerEnd")))
1054 return disp_table->CmdDbgMarkerEnd;
1055 else if (!strncmp("xglWsiX11AssociateConnection", (const char *) pName, sizeof("xglWsiX11AssociateConnection")))
1056 return disp_table->WsiX11AssociateConnection;
1057 else if (!strncmp("xglWsiX11GetMSC", (const char *) pName, sizeof("xglWsiX11GetMSC")))
1058 return disp_table->WsiX11GetMSC;
1059 else if (!strncmp("xglWsiX11CreatePresentableImage", (const char *) pName, sizeof("xglWsiX11CreatePresentableImage")))
1060 return disp_table->WsiX11CreatePresentableImage;
1061 else if (!strncmp("xglWsiX11QueuePresent", (const char *) pName, sizeof("xglWsiX11QueuePresent")))
1062 return disp_table->WsiX11QueuePresent;
1063 else {
1064 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
1065 if (gpuw->pGPA == NULL)
1066 return NULL;
1067 return gpuw->pGPA(gpuw->nextObject, pName);
1068 }
1069}
1070
Chia-I Wu19300602014-08-04 08:03:57 +08001071LOADER_EXPORT XGL_RESULT XGLAPI xglInitAndEnumerateGpus(const XGL_APPLICATION_INFO* pAppInfo, const XGL_ALLOC_CALLBACKS* pAllocCb, XGL_UINT maxGpus, XGL_UINT* pGpuCount, XGL_PHYSICAL_GPU* pGpus)
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001072{
1073 static pthread_once_t once = PTHREAD_ONCE_INIT;
Jon Ashburndf7d5842014-10-16 15:48:50 -06001074 struct loader_icd *icd;
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001075 XGL_UINT count = 0;
1076 XGL_RESULT res;
1077
Jon Ashburndf7d5842014-10-16 15:48:50 -06001078 // cleanup any prior layer initializations
Jon Ashburn876b1ac2014-10-17 15:09:07 -06001079 loader_deactivate_layer();
Jon Ashburndf7d5842014-10-16 15:48:50 -06001080
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001081 pthread_once(&once, loader_icd_scan);
1082
1083 if (!loader.icds)
1084 return XGL_ERROR_UNAVAILABLE;
1085
1086 icd = loader.icds;
1087 while (icd) {
1088 XGL_PHYSICAL_GPU gpus[XGL_MAX_PHYSICAL_GPUS];
Jon Ashburnd38bfb12014-10-14 19:15:22 -06001089 XGL_BASE_LAYER_OBJECT * wrappedGpus;
1090 GetProcAddrType getProcAddr = icd->GetProcAddr;
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001091 XGL_UINT n, max = maxGpus - count;
1092
1093 if (max > XGL_MAX_PHYSICAL_GPUS) {
1094 max = XGL_MAX_PHYSICAL_GPUS;
1095 }
1096
1097 res = icd->InitAndEnumerateGpus(pAppInfo, pAllocCb, max, &n, gpus);
Chia-I Wu7f44d352014-08-06 12:17:04 +08001098 if (res == XGL_SUCCESS && n) {
Jon Ashburnd38bfb12014-10-14 19:15:22 -06001099 wrappedGpus = (XGL_BASE_LAYER_OBJECT*) malloc(n * sizeof(XGL_BASE_LAYER_OBJECT));
Jon Ashburn6b4d70c2014-10-22 18:13:16 -06001100 icd->gpus = wrappedGpus;
Jon Ashburn876b1ac2014-10-17 15:09:07 -06001101 icd->gpu_count = n;
Jon Ashburndf7d5842014-10-16 15:48:50 -06001102 icd->loader_dispatch = (XGL_LAYER_DISPATCH_TABLE *) malloc(n * sizeof(XGL_LAYER_DISPATCH_TABLE));
Jon Ashburnd38bfb12014-10-14 19:15:22 -06001103 for (int i = 0; i < n; i++) {
1104 (wrappedGpus + i)->baseObject = gpus[i];
Jon Ashburndf7d5842014-10-16 15:48:50 -06001105 (wrappedGpus + i)->pGPA = getProcAddr;
Jon Ashburnd38bfb12014-10-14 19:15:22 -06001106 (wrappedGpus + i)->nextObject = gpus[i];
1107 memcpy(pGpus + count, &wrappedGpus, sizeof(*pGpus));
Jon Ashburn891537f2014-10-22 12:42:13 -06001108 loader_init_dispatch_table(icd->loader_dispatch + i, getProcAddr, gpus[i]);
Jon Ashburnd38bfb12014-10-14 19:15:22 -06001109 const XGL_LAYER_DISPATCH_TABLE * *disp = (const XGL_LAYER_DISPATCH_TABLE * *) gpus[i];
Jon Ashburndf7d5842014-10-16 15:48:50 -06001110 *disp = icd->loader_dispatch + i;
1111 icd->SetDispatch(icd->loader_dispatch + i, true);
Jon Ashburnd38bfb12014-10-14 19:15:22 -06001112 }
1113
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001114 count += n;
1115
1116 if (count >= maxGpus) {
1117 break;
1118 }
1119 }
1120
1121 icd = icd->next;
1122 }
1123
Jon Ashburnd38bfb12014-10-14 19:15:22 -06001124 /* get layer libraries */
Jon Ashburn6b4d70c2014-10-22 18:13:16 -06001125 if (!loader.layer_scanned)
1126 layer_lib_scan(NULL, true);
Jon Ashburnd38bfb12014-10-14 19:15:22 -06001127
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001128 *pGpuCount = count;
1129
1130 return (count > 0) ? XGL_SUCCESS : res;
1131}
1132
Jon Ashburnf7bcf9b2014-10-15 15:30:23 -06001133LOADER_EXPORT XGL_RESULT XGLAPI xglEnumerateLayers(XGL_PHYSICAL_GPU gpu, XGL_SIZE maxLayerCount, XGL_SIZE maxStringSize, XGL_CHAR* const* pOutLayers, XGL_SIZE* pOutLayerCount)
1134{
Jon Ashburn6b4d70c2014-10-22 18:13:16 -06001135 XGL_SIZE count = loader.scanned_layer_count;
Jon Ashburnf7bcf9b2014-10-15 15:30:23 -06001136 // TODO handle layers per GPU, multiple icds
1137
1138 if (pOutLayerCount == NULL)
1139 return XGL_ERROR_INVALID_POINTER;
1140
Jon Ashburn6b4d70c2014-10-22 18:13:16 -06001141 if (maxLayerCount < loader.scanned_layer_count)
Jon Ashburnf7bcf9b2014-10-15 15:30:23 -06001142 count = maxLayerCount;
1143 *pOutLayerCount = count;
1144
1145 if (pOutLayers == NULL)
1146 return XGL_SUCCESS;
1147 for (XGL_SIZE i = 0; i < count; i++) {
Jon Ashburn6b4d70c2014-10-22 18:13:16 -06001148 strncpy((char *) (pOutLayers[i]), loader.scanned_layer_names[i], maxStringSize);
Jon Ashburnf7bcf9b2014-10-15 15:30:23 -06001149 if (maxStringSize > 0)
1150 pOutLayers[i][maxStringSize - 1] = '\0';
1151 }
1152 return XGL_SUCCESS;
1153}
1154
Chia-I Wu19300602014-08-04 08:03:57 +08001155LOADER_EXPORT XGL_RESULT XGLAPI xglDbgRegisterMsgCallback(XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback, XGL_VOID* pUserData)
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001156{
1157 const struct loader_icd *icd = loader.icds;
1158 XGL_RESULT res;
1159
1160 if (!loader.scanned) {
1161 return loader_msg_callback_add(pfnMsgCallback, pUserData);
1162 }
1163
1164 while (icd) {
1165 res = icd->DbgRegisterMsgCallback(pfnMsgCallback, pUserData);
1166 if (res != XGL_SUCCESS) {
1167 break;
1168 }
1169
1170 icd = icd->next;
1171 }
1172
1173 /* roll back on errors */
1174 if (icd) {
1175 const struct loader_icd *tmp = loader.icds;
1176
1177 while (tmp != icd) {
1178 tmp->DbgUnregisterMsgCallback(pfnMsgCallback);
1179 tmp = tmp->next;
1180 }
1181
1182 return res;
1183 }
1184
1185 return XGL_SUCCESS;
1186}
1187
Chia-I Wu19300602014-08-04 08:03:57 +08001188LOADER_EXPORT XGL_RESULT XGLAPI xglDbgUnregisterMsgCallback(XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback)
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001189{
1190 const struct loader_icd *icd = loader.icds;
1191 XGL_RESULT res = XGL_SUCCESS;
1192
1193 if (!loader.scanned) {
1194 return loader_msg_callback_remove(pfnMsgCallback);
1195 }
1196
1197 while (icd) {
1198 XGL_RESULT r = icd->DbgUnregisterMsgCallback(pfnMsgCallback);
1199 if (r != XGL_SUCCESS) {
1200 res = r;
1201 }
1202 icd = icd->next;
1203 }
1204
1205 return res;
1206}
1207
Chia-I Wu19300602014-08-04 08:03:57 +08001208LOADER_EXPORT XGL_RESULT XGLAPI xglDbgSetGlobalOption(XGL_DBG_GLOBAL_OPTION dbgOption, XGL_SIZE dataSize, const XGL_VOID* pData)
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001209{
1210 const struct loader_icd *icd = loader.icds;
1211 XGL_RESULT res = XGL_SUCCESS;
1212
1213 if (!loader.scanned) {
1214 if (dataSize == 0)
1215 return XGL_ERROR_INVALID_VALUE;
1216
1217 switch (dbgOption) {
1218 case XGL_DBG_OPTION_DEBUG_ECHO_ENABLE:
1219 loader.debug_echo_enable = *((const bool *) pData);
1220 break;
1221 case XGL_DBG_OPTION_BREAK_ON_ERROR:
1222 loader.break_on_error = *((const bool *) pData);
1223 break;
1224 case XGL_DBG_OPTION_BREAK_ON_WARNING:
1225 loader.break_on_warning = *((const bool *) pData);
1226 break;
1227 default:
1228 res = XGL_ERROR_INVALID_VALUE;
1229 break;
1230 }
1231
1232 return res;
1233 }
1234
1235 while (icd) {
1236 XGL_RESULT r = icd->DbgSetGlobalOption(dbgOption, dataSize, pData);
1237 /* unfortunately we cannot roll back */
1238 if (r != XGL_SUCCESS) {
1239 res = r;
1240 }
1241
1242 icd = icd->next;
1243 }
1244
1245 return res;
1246}