blob: b7c8dfd10158afd000b574e29d3fb360662208c9 [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 Wu44e42362014-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 */
28
29#include <stdio.h>
30#include <stdlib.h>
31#include <stdarg.h>
32#include <stdbool.h>
33#include <string.h>
34
Chia-I Wu894a1172014-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 Ashburnd43f9b62014-10-14 19:15:22 -060040#include <assert.h>
Chia-I Wu468e3c32014-08-04 08:03:57 +080041#include "loader.h"
Chia-I Wu5f72d0f2014-08-01 11:21:23 +080042
Jon Ashburn815bddd2014-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
45struct loader_icd {
46 void *handle;
47
Jon Ashburnb55278a2014-10-17 15:09:07 -060048 XGL_LAYER_DISPATCH_TABLE *loader_dispatch;
49 bool layers_activated;
50 XGL_UINT gpu_count;
51 XGL_BASE_LAYER_OBJECT *gpu;
Jon Ashburn815bddd2014-10-16 15:48:50 -060052
Jon Ashburnd43f9b62014-10-14 19:15:22 -060053 GetProcAddrType GetProcAddr;
54 InitAndEnumerateGpusType InitAndEnumerateGpus;
55 DbgRegisterMsgCallbackType DbgRegisterMsgCallback;
56 DbgUnregisterMsgCallbackType DbgUnregisterMsgCallback;
57 DbgSetGlobalOptionType DbgSetGlobalOption;
Jon Ashburn815bddd2014-10-16 15:48:50 -060058 SetDispatchType SetDispatch;
Chia-I Wu5f72d0f2014-08-01 11:21:23 +080059
60 struct loader_icd *next;
61};
62
Jon Ashburnd43f9b62014-10-14 19:15:22 -060063struct loader_layers {
64 void *lib_handle;
65 char lib_name[1024];
66};
67
Chia-I Wu5f72d0f2014-08-01 11:21:23 +080068struct loader_msg_callback {
69 XGL_DBG_MSG_CALLBACK_FUNCTION func;
70 XGL_VOID *data;
71
72 struct loader_msg_callback *next;
73};
74
Jon Ashburnd43f9b62014-10-14 19:15:22 -060075
Chia-I Wu5f72d0f2014-08-01 11:21:23 +080076static struct {
77 bool scanned;
78 struct loader_icd *icds;
Jon Ashburnd43f9b62014-10-14 19:15:22 -060079 XGL_UINT layer_count;
80 bool layer_scaned;
81 char layer_dirs[4096];
82 struct loader_layers layer_libs[MAX_LAYER_LIBRARIES];
Chia-I Wu5f72d0f2014-08-01 11:21:23 +080083 struct loader_msg_callback *msg_callbacks;
84
85 bool debug_echo_enable;
86 bool break_on_error;
87 bool break_on_warning;
88} loader;
89
90static XGL_RESULT loader_msg_callback_add(XGL_DBG_MSG_CALLBACK_FUNCTION func,
91 XGL_VOID *data)
92{
93 struct loader_msg_callback *cb;
94
95 cb = malloc(sizeof(*cb));
96 if (!cb)
97 return XGL_ERROR_OUT_OF_MEMORY;
98
99 cb->func = func;
100 cb->data = data;
101
102 cb->next = loader.msg_callbacks;
103 loader.msg_callbacks = cb;
104
105 return XGL_SUCCESS;
106}
107
108static XGL_RESULT loader_msg_callback_remove(XGL_DBG_MSG_CALLBACK_FUNCTION func)
109{
110 struct loader_msg_callback *cb = loader.msg_callbacks;
111
112 /*
113 * Find the first match (last registered).
114 *
115 * XXX What if the same callback function is registered more than once?
116 */
117 while (cb) {
118 if (cb->func == func) {
119 break;
120 }
121
122 cb = cb->next;
123 }
124
125 if (!cb)
126 return XGL_ERROR_INVALID_POINTER;
127
128 free(cb);
129
130 return XGL_SUCCESS;
131}
132
133static void loader_msg_callback_clear(void)
134{
135 struct loader_msg_callback *cb = loader.msg_callbacks;
136
137 while (cb) {
138 struct loader_msg_callback *next = cb->next;
139 free(cb);
140 cb = next;
141 }
142
143 loader.msg_callbacks = NULL;
144}
145
146static void loader_log(XGL_DBG_MSG_TYPE msg_type, XGL_INT msg_code,
147 const char *format, ...)
148{
149 const struct loader_msg_callback *cb = loader.msg_callbacks;
150 char msg[256];
151 va_list ap;
152 int ret;
153
154 va_start(ap, format);
155 ret = vsnprintf(msg, sizeof(msg), format, ap);
156 if (ret >= sizeof(msg) || ret < 0) {
157 msg[sizeof(msg) - 1] = '\0';
158 }
159 va_end(ap);
160
161 if (loader.debug_echo_enable || !cb) {
162 fputs(msg, stderr);
163 fputc('\n', stderr);
164 }
165
166 while (cb) {
167 cb->func(msg_type, XGL_VALIDATION_LEVEL_0, XGL_NULL_HANDLE, 0,
168 msg_code, (const XGL_CHAR *) msg, cb->data);
169 cb = cb->next;
170 }
171
172 switch (msg_type) {
173 case XGL_DBG_MSG_ERROR:
174 if (loader.break_on_error) {
175 exit(1);
176 }
177 /* fall through */
178 case XGL_DBG_MSG_WARNING:
179 if (loader.break_on_warning) {
180 exit(1);
181 }
182 break;
183 default:
184 break;
185 }
186}
187
188static void
189loader_icd_destroy(struct loader_icd *icd)
190{
191 dlclose(icd->handle);
192 free(icd);
193}
194
195static struct loader_icd *
196loader_icd_create(const char *filename)
197{
198 struct loader_icd *icd;
199
200 icd = malloc(sizeof(*icd));
201 if (!icd)
202 return NULL;
203
Courtney Goeltzenleuchter6f928162014-10-28 10:29:27 -0600204 memset(icd, 0, sizeof(*icd));
205
Chia-I Wu5f72d0f2014-08-01 11:21:23 +0800206 icd->handle = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
207 if (!icd->handle) {
208 loader_log(XGL_DBG_MSG_WARNING, 0, dlerror());
209 free(icd);
210 return NULL;
211 }
212
213#define LOOKUP(icd, func) do { \
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600214 icd->func = (func## Type) dlsym(icd->handle, "xgl" #func); \
Chia-I Wu5f72d0f2014-08-01 11:21:23 +0800215 if (!icd->func) { \
216 loader_log(XGL_DBG_MSG_WARNING, 0, dlerror()); \
217 loader_icd_destroy(icd); \
218 return NULL; \
219 } \
220} while (0)
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600221 LOOKUP(icd, GetProcAddr);
Chia-I Wu5f72d0f2014-08-01 11:21:23 +0800222 LOOKUP(icd, InitAndEnumerateGpus);
223 LOOKUP(icd, DbgRegisterMsgCallback);
224 LOOKUP(icd, DbgUnregisterMsgCallback);
225 LOOKUP(icd, DbgSetGlobalOption);
Jon Ashburn815bddd2014-10-16 15:48:50 -0600226 LOOKUP(icd, SetDispatch);
Chia-I Wu5f72d0f2014-08-01 11:21:23 +0800227#undef LOOKUP
228
229 return icd;
230}
231
232static XGL_RESULT loader_icd_register_msg_callbacks(const struct loader_icd *icd)
233{
234 const struct loader_msg_callback *cb = loader.msg_callbacks;
235 XGL_RESULT res;
236
237 while (cb) {
238 res = icd->DbgRegisterMsgCallback(cb->func, cb->data);
239 if (res != XGL_SUCCESS) {
240 break;
241 }
242
243 cb = cb->next;
244 }
245
246 /* roll back on errors */
247 if (cb) {
248 const struct loader_msg_callback *tmp = loader.msg_callbacks;
249
250 while (tmp != cb) {
251 icd->DbgUnregisterMsgCallback(cb->func);
252 tmp = tmp->next;
253 }
254
255 return res;
256 }
257
258 return XGL_SUCCESS;
259}
260
261static XGL_RESULT loader_icd_set_global_options(const struct loader_icd *icd)
262{
263#define SETB(icd, opt, val) do { \
264 if (val) { \
265 const XGL_RESULT res = \
266 icd->DbgSetGlobalOption(opt, sizeof(val), &val); \
267 if (res != XGL_SUCCESS) \
268 return res; \
269 } \
270} while (0)
271 SETB(icd, XGL_DBG_OPTION_DEBUG_ECHO_ENABLE, loader.debug_echo_enable);
272 SETB(icd, XGL_DBG_OPTION_BREAK_ON_ERROR, loader.break_on_error);
273 SETB(icd, XGL_DBG_OPTION_BREAK_ON_WARNING, loader.break_on_warning);
274#undef SETB
275
276return XGL_SUCCESS;
277}
278
Chia-I Wu894a1172014-08-04 11:18:20 +0800279static struct loader_icd *loader_icd_add(const char *filename)
280{
281 struct loader_icd *icd;
282
283 icd = loader_icd_create(filename);
284 if (!icd)
285 return NULL;
286
287 if (loader_icd_set_global_options(icd) != XGL_SUCCESS ||
288 loader_icd_register_msg_callbacks(icd) != XGL_SUCCESS) {
289 loader_log(XGL_DBG_MSG_WARNING, 0,
290 "%s ignored: failed to migrate settings", filename);
291 loader_icd_destroy(icd);
292 }
293
294 /* prepend to the list */
295 icd->next = loader.icds;
296 loader.icds = icd;
297
298 return icd;
299}
300
Courtney Goeltzenleuchter4af9bd12014-08-01 14:18:11 -0600301#ifndef DEFAULT_XGL_DRIVERS_PATH
302// TODO: Is this a good default location?
303// Need to search for both 32bit and 64bit ICDs
304#define DEFAULT_XGL_DRIVERS_PATH "/usr/lib/i386-linux-gnu/xgl:/usr/lib/x86_64-linux-gnu/xgl"
305#endif
306
307/**
308 * Try to \c loader_icd_scan XGL driver(s).
309 *
310 * This function scans the default system path or path
311 * specified by the \c LIBXGL_DRIVERS_PATH environment variable in
312 * order to find loadable XGL ICDs with the name of libXGL_*.
313 *
314 * \returns
315 * void; but side effect is to set loader_icd_scanned to true
316 */
317static void loader_icd_scan(void)
Chia-I Wu5f72d0f2014-08-01 11:21:23 +0800318{
Courtney Goeltzenleuchter4af9bd12014-08-01 14:18:11 -0600319 const char *libPaths, *p, *next;
320 DIR *sysdir;
321 struct dirent *dent;
322 char icd_library[1024];
Jon Ashburn0f45b2a2014-10-03 16:31:35 -0600323 char path[1024];
Courtney Goeltzenleuchter4af9bd12014-08-01 14:18:11 -0600324 int len;
Chia-I Wu5f72d0f2014-08-01 11:21:23 +0800325
Courtney Goeltzenleuchter4af9bd12014-08-01 14:18:11 -0600326 libPaths = NULL;
327 if (geteuid() == getuid()) {
328 /* don't allow setuid apps to use LIBXGL_DRIVERS_PATH */
329 libPaths = getenv("LIBXGL_DRIVERS_PATH");
330 }
331 if (libPaths == NULL)
332 libPaths = DEFAULT_XGL_DRIVERS_PATH;
Chia-I Wu5f72d0f2014-08-01 11:21:23 +0800333
Courtney Goeltzenleuchter4af9bd12014-08-01 14:18:11 -0600334 for (p = libPaths; *p; p = next) {
335 next = strchr(p, ':');
336 if (next == NULL) {
337 len = strlen(p);
338 next = p + len;
339 }
340 else {
341 len = next - p;
Jon Ashburn0f45b2a2014-10-03 16:31:35 -0600342 sprintf(path, "%.*s", (len > sizeof(path) - 1) ? (int) sizeof(path) - 1 : len, p);
343 p = path;
Courtney Goeltzenleuchter4af9bd12014-08-01 14:18:11 -0600344 next++;
345 }
Chia-I Wu5f72d0f2014-08-01 11:21:23 +0800346
Courtney Goeltzenleuchter4af9bd12014-08-01 14:18:11 -0600347 sysdir = opendir(p);
348 if (sysdir) {
349 dent = readdir(sysdir);
350 while (dent) {
351 /* look for ICDs starting with "libXGL_" */
352 if (!strncmp(dent->d_name, "libXGL_", 7)) {
Courtney Goeltzenleuchter4af9bd12014-08-01 14:18:11 -0600353 snprintf(icd_library, 1024, "%s/%s",p,dent->d_name);
Chia-I Wu894a1172014-08-04 11:18:20 +0800354 loader_icd_add(icd_library);
Courtney Goeltzenleuchter4af9bd12014-08-01 14:18:11 -0600355 }
356
357 dent = readdir(sysdir);
358 }
359 closedir(sysdir);
360 }
Chia-I Wu5f72d0f2014-08-01 11:21:23 +0800361 }
362
363 /* we have nothing to log anymore */
364 loader_msg_callback_clear();
365
366 loader.scanned = true;
367}
368
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600369#ifndef DEFAULT_XGL_LAYERS_PATH
370// TODO: Is this a good default locations
371#define DEFAULT_XGL_LAYERS_PATH ".:/usr/lib/i386-linux-gnu/xgl:/usr/lib/x86_64-linux-gnu/xgl"
372#endif
373
374static void layer_lib_scan(const char * libInPaths, const bool useDefaultDirs, const bool openLibs)
375{
376 const char *p, *next;
377 char *libPaths = &loader.layer_dirs[0];
378 DIR *curdir;
379 struct dirent *dent;
380 int len, i, n;
381
382 if (libInPaths){
383 strncpy(libPaths, libInPaths, sizeof(loader.layer_dirs));
384 }
385 else {
386 *libPaths = '\0';
387 }
388
389 /* cleanup any previously scanned libraries */
390 for (i = 0; i < loader.layer_count; i++) {
391 if (loader.layer_libs[i].lib_handle != NULL)
392 dlclose(loader.layer_libs[i].lib_handle);
393 loader.layer_libs[i].lib_handle = NULL;
394 }
395 loader.layer_count = 0;
396
397 if (useDefaultDirs)
398 strncat(libPaths, DEFAULT_XGL_LAYERS_PATH, sizeof(loader.layer_dirs) - sizeof(DEFAULT_XGL_LAYERS_PATH));
399
400 for (p = libPaths; *p; p = next) {
401 next = strchr(p, ':');
402 if (next == NULL) {
403 len = strlen(p);
404 next = p + len;
405 }
406 else {
407 len = next - p;
408 *(char *) next = '\0';
409 next++;
410 }
411
412 curdir = opendir(p);
413 if (curdir) {
414 dent = readdir(curdir);
415 while (dent) {
416 n = loader.layer_count;
417 /* look for wrappers starting with "libXGLlayer" */
418 if (!strncmp(dent->d_name, "libXGLLayer", strlen("libXGLLayer"))) {
419 snprintf((char *) &(loader.layer_libs[n].lib_name), sizeof(loader.layer_libs[0].lib_name), "%s/%s",p,dent->d_name);
420 if ((loader.layer_libs[n].lib_handle = dlopen((const char *) &(loader.layer_libs[n].lib_name), RTLD_LAZY)) == NULL)
421 continue;
422
423 loader.layer_count++;
424 if (!openLibs)
425 dlclose(loader.layer_libs[n].lib_handle);
426 }
427
428 dent = readdir(curdir);
429 }
430 closedir(curdir);
431 }
432 }
433
434 loader.layer_scaned = true;
435}
436
437#if 0
438static bool layer_lib_sort(char * str, const XGL_UINT count)
439{
440 XGL_UINT i;
441 struct loader_layers temp, *cur, *start;
442
443 start = &loader.layer_libs[count];
444 for (i = count; i < loader.layer_count; i++) {
445 cur = &loader.layer_libs[i];
446
447 if (!strcmp(str, cur->lib_name) && cur->lib_handle != NULL) {
448 if (count == i)
449 return true;
450 strcpy(temp.lib_name, cur->lib_name);
451 temp.lib_handle = cur->lib_handle;
452 strcpy(cur->lib_name, start->lib_name);
453 cur->lib_handle = start->lib_handle;
454 strcpy(start->lib_name, temp.lib_name);
455 start->lib_handle = temp.lib_handle;
456 return true;
457 }
458 }
459 return false;
460}
461#endif
462LOADER_EXPORT XGL_RESULT XGLAPI ScanForLayers(const XGL_CHAR* pLibraryDirectories, XGL_CHAR * pStr)
463{
464 size_t size = 0;
465 XGL_UINT i;
466 static XGL_CHAR *lib_str=NULL;
467
468 if (!pLibraryDirectories)
469 return XGL_ERROR_INVALID_POINTER;
470
471 if (strlen((const char *) pLibraryDirectories) > sizeof(loader.layer_dirs))
472 return XGL_ERROR_INVALID_POINTER;
473
474 layer_lib_scan((const char *) pLibraryDirectories, true, false);
475
476 for (i = 0; i < loader.layer_count; i++) {
477 size += strlen(loader.layer_libs[i].lib_name) + 1;
478 }
479
480 free(lib_str);
481 lib_str = malloc(size);
482 if (!lib_str)
483 return XGL_ERROR_OUT_OF_MEMORY;
484
485 pStr = lib_str;
486 for (i = 0; i < loader.layer_count; i++) {
487 strncat((char *) pStr, loader.layer_libs[i].lib_name, strlen(loader.layer_libs[i].lib_name));
488 strcat((char *) pStr, ":");
489 }
490 return XGL_SUCCESS;
491}
492
Jon Ashburnb55278a2014-10-17 15:09:07 -0600493static void loader_init_dispatch_table(XGL_LAYER_DISPATCH_TABLE *tab, GetProcAddrType fpGPA, XGL_PHYSICAL_GPU gpu)
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600494{
495 tab->GetProcAddr = fpGPA;
496 tab->InitAndEnumerateGpus = fpGPA(gpu, (const XGL_CHAR *) "xglInitAndEnumerateGpus");
497 tab->GetGpuInfo = fpGPA(gpu, (const XGL_CHAR *) "xglGetGpuInfo");
498 tab->CreateDevice = fpGPA(gpu, (const XGL_CHAR *) "xglCreateDevice");
499 tab->DestroyDevice = fpGPA(gpu, (const XGL_CHAR *) "xglDestroyDevice");
500 tab->GetExtensionSupport = fpGPA(gpu, (const XGL_CHAR *) "xglGetExtensionSupport");
Jon Ashburn96f28fc2014-10-15 15:30:23 -0600501 tab->EnumerateLayers = fpGPA(gpu, (const XGL_CHAR *) "xglEnumerateLayers");
502 if (tab->EnumerateLayers == NULL)
503 tab->EnumerateLayers = xglEnumerateLayers;
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600504 tab->GetDeviceQueue = fpGPA(gpu, (const XGL_CHAR *) "xglGetDeviceQueue");
505 tab->QueueSubmit = fpGPA(gpu, (const XGL_CHAR *) "xglQueueSubmit");
506 tab->QueueSetGlobalMemReferences = fpGPA(gpu, (const XGL_CHAR *) "xglQueueSetGlobalMemReferences");
507 tab->QueueWaitIdle = fpGPA(gpu, (const XGL_CHAR *) "xglQueueWaitIdle");
508 tab->DeviceWaitIdle = fpGPA(gpu, (const XGL_CHAR *) "xglDeviceWaitIdle");
509 tab->GetMemoryHeapCount = fpGPA(gpu, (const XGL_CHAR *) "xglGetMemoryHeapCount");
510 tab->GetMemoryHeapInfo = fpGPA(gpu, (const XGL_CHAR *) "xglGetMemoryHeapInfo");
511 tab->AllocMemory = fpGPA(gpu, (const XGL_CHAR *) "xglAllocMemory");
512 tab->FreeMemory = fpGPA(gpu, (const XGL_CHAR *) "xglFreeMemory");
513 tab->SetMemoryPriority = fpGPA(gpu, (const XGL_CHAR *) "xglSetMemoryPriority");
514 tab->MapMemory = fpGPA(gpu, (const XGL_CHAR *) "xglMapMemory");
515 tab->UnmapMemory = fpGPA(gpu, (const XGL_CHAR *) "xglUnmapMemory");
516 tab->PinSystemMemory = fpGPA(gpu, (const XGL_CHAR *) "xglPinSystemMemory");
517 tab->RemapVirtualMemoryPages = fpGPA(gpu, (const XGL_CHAR *) "xglRemapVirtualMemoryPages");
518 tab->GetMultiGpuCompatibility = fpGPA(gpu, (const XGL_CHAR *) "xglGetMultiGpuCompatibility");
519 tab->OpenSharedMemory = fpGPA(gpu, (const XGL_CHAR *) "xglOpenSharedMemory");
520 tab->OpenSharedQueueSemaphore = fpGPA(gpu, (const XGL_CHAR *) "xglOpenSharedQueueSemaphore");
521 tab->OpenPeerMemory = fpGPA(gpu, (const XGL_CHAR *) "xglOpenPeerMemory");
522 tab->OpenPeerImage = fpGPA(gpu, (const XGL_CHAR *) "xglOpenPeerImage");
523 tab->DestroyObject = fpGPA(gpu, (const XGL_CHAR *) "xglDestroyObject");
524 tab->GetObjectInfo = fpGPA(gpu, (const XGL_CHAR *) "xglGetObjectInfo");
525 tab->BindObjectMemory = fpGPA(gpu, (const XGL_CHAR *) "xglBindObjectMemory");
526 tab->CreateFence = fpGPA(gpu, (const XGL_CHAR *) "xglCreateFence");
527 tab->GetFenceStatus = fpGPA(gpu, (const XGL_CHAR *) "xglGetFenceStatus");
528 tab->WaitForFences = fpGPA(gpu, (const XGL_CHAR *) "xglWaitForFences");
529 tab->CreateQueueSemaphore = fpGPA(gpu, (const XGL_CHAR *) "xglCreateQueueSemaphore");
530 tab->SignalQueueSemaphore = fpGPA(gpu, (const XGL_CHAR *) "xglSignalQueueSemaphore");
531 tab->WaitQueueSemaphore = fpGPA(gpu, (const XGL_CHAR *) "xglWaitQueueSemaphore");
532 tab->CreateEvent = fpGPA(gpu, (const XGL_CHAR *) "xglCreateEvent");
533 tab->GetEventStatus = fpGPA(gpu, (const XGL_CHAR *) "xglGetEventStatus");
534 tab->SetEvent = fpGPA(gpu, (const XGL_CHAR *) "xglSetEvent");
535 tab->ResetEvent = fpGPA(gpu, (const XGL_CHAR *) "xglResetEvent");
536 tab->CreateQueryPool = fpGPA(gpu, (const XGL_CHAR *) "xglCreateQueryPool");
537 tab->GetQueryPoolResults = fpGPA(gpu, (const XGL_CHAR *) "xglGetQueryPoolResults");
538 tab->GetFormatInfo = fpGPA(gpu, (const XGL_CHAR *) "xglGetFormatInfo");
539 tab->CreateImage = fpGPA(gpu, (const XGL_CHAR *) "xglCreateImage");
540 tab->GetImageSubresourceInfo = fpGPA(gpu, (const XGL_CHAR *) "xglGetImageSubresourceInfo");
541 tab->CreateImageView = fpGPA(gpu, (const XGL_CHAR *) "xglCreateImageView");
542 tab->CreateColorAttachmentView = fpGPA(gpu, (const XGL_CHAR *) "xglCreateColorAttachmentView");
543 tab->CreateDepthStencilView = fpGPA(gpu, (const XGL_CHAR *) "xglCreateDepthStencilView");
544 tab->CreateShader = fpGPA(gpu, (const XGL_CHAR *) "xglCreateShader");
545 tab->CreateGraphicsPipeline = fpGPA(gpu, (const XGL_CHAR *) "xglCreateGraphicsPipeline");
546 tab->CreateComputePipeline = fpGPA(gpu, (const XGL_CHAR *) "xglCreateComputePipeline");
547 tab->StorePipeline = fpGPA(gpu, (const XGL_CHAR *) "xglStorePipeline");
548 tab->LoadPipeline = fpGPA(gpu, (const XGL_CHAR *) "xglLoadPipeline");
549 tab->CreatePipelineDelta = fpGPA(gpu, (const XGL_CHAR *) "xglCreatePipelineDelta");
550 tab->CreateSampler = fpGPA(gpu, (const XGL_CHAR *) "xglCreateSampler");
551 tab->CreateDescriptorSet = fpGPA(gpu, (const XGL_CHAR *) "xglCreateDescriptorSet");
552 tab->BeginDescriptorSetUpdate = fpGPA(gpu, (const XGL_CHAR *) "xglBeginDescriptorSetUpdate");
553 tab->EndDescriptorSetUpdate = fpGPA(gpu, (const XGL_CHAR *) "xglEndDescriptorSetUpdate");
554 tab->AttachSamplerDescriptors = fpGPA(gpu, (const XGL_CHAR *) "xglAttachSamplerDescriptors");
555 tab->AttachImageViewDescriptors = fpGPA(gpu, (const XGL_CHAR *) "xglAttachImageViewDescriptors");
556 tab->AttachMemoryViewDescriptors = fpGPA(gpu, (const XGL_CHAR *) "xglAttachMemoryViewDescriptors");
557 tab->AttachNestedDescriptors = fpGPA(gpu, (const XGL_CHAR *) "xglAttachNestedDescriptors");
558 tab->ClearDescriptorSetSlots = fpGPA(gpu, (const XGL_CHAR *) "xglClearDescriptorSetSlots");
559 tab->CreateViewportState = fpGPA(gpu, (const XGL_CHAR *) "xglCreateViewportState");
560 tab->CreateRasterState = fpGPA(gpu, (const XGL_CHAR *) "xglCreateRasterState");
561 tab->CreateMsaaState = fpGPA(gpu, (const XGL_CHAR *) "xglCreateMsaaState");
562 tab->CreateColorBlendState = fpGPA(gpu, (const XGL_CHAR *) "xglCreateColorBlendState");
563 tab->CreateDepthStencilState = fpGPA(gpu, (const XGL_CHAR *) "xglCreateDepthStencilState");
564 tab->CreateCommandBuffer = fpGPA(gpu, (const XGL_CHAR *) "xglCreateCommandBuffer");
565 tab->BeginCommandBuffer = fpGPA(gpu, (const XGL_CHAR *) "xglBeginCommandBuffer");
566 tab->EndCommandBuffer = fpGPA(gpu, (const XGL_CHAR *) "xglEndCommandBuffer");
567 tab->ResetCommandBuffer = fpGPA(gpu, (const XGL_CHAR *) "xglResetCommandBuffer");
568 tab->CmdBindPipeline = fpGPA(gpu, (const XGL_CHAR *) "xglCmdBindPipeline");
569 tab->CmdBindPipelineDelta = fpGPA(gpu, (const XGL_CHAR *) "xglCmdBindPipelineDelta");
570 tab->CmdBindStateObject = fpGPA(gpu, (const XGL_CHAR *) "xglCmdBindStateObject");
571 tab->CmdBindDescriptorSet = fpGPA(gpu, (const XGL_CHAR *) "xglCmdBindDescriptorSet");
572 tab->CmdBindDynamicMemoryView = fpGPA(gpu, (const XGL_CHAR *) "xglCmdBindDynamicMemoryView");
573 tab->CmdBindIndexData = fpGPA(gpu, (const XGL_CHAR *) "xglCmdBindIndexData");
574 tab->CmdBindAttachments = fpGPA(gpu, (const XGL_CHAR *) "xglCmdBindAttachments");
575 tab->CmdPrepareMemoryRegions = fpGPA(gpu, (const XGL_CHAR *) "xglCmdPrepareMemoryRegions");
576 tab->CmdPrepareImages = fpGPA(gpu, (const XGL_CHAR *) "xglCmdPrepareImages");
577 tab->CmdDraw = fpGPA(gpu, (const XGL_CHAR *) "xglCmdDraw");
578 tab->CmdDrawIndexed = fpGPA(gpu, (const XGL_CHAR *) "xglCmdDrawIndexed");
579 tab->CmdDrawIndirect = fpGPA(gpu, (const XGL_CHAR *) "xglCmdDrawIndirect");
580 tab->CmdDrawIndexedIndirect = fpGPA(gpu, (const XGL_CHAR *) "xglCmdDrawIndexedIndirect");
581 tab->CmdDispatch = fpGPA(gpu, (const XGL_CHAR *) "xglCmdDispatch");
582 tab->CmdDispatchIndirect = fpGPA(gpu, (const XGL_CHAR *) "xglCmdDispatchIndirect");
583 tab->CmdCopyMemory = fpGPA(gpu, (const XGL_CHAR *) "xglCmdCopyMemory");
584 tab->CmdCopyImage = fpGPA(gpu, (const XGL_CHAR *) "xglCmdCopyImage");
585 tab->CmdCopyMemoryToImage = fpGPA(gpu, (const XGL_CHAR *) "xglCmdCopyMemoryToImage");
586 tab->CmdCopyImageToMemory = fpGPA(gpu, (const XGL_CHAR *) "xglCmdCopyImageToMemory");
587 tab->CmdCloneImageData = fpGPA(gpu, (const XGL_CHAR *) "xglCmdCloneImageData");
588 tab->CmdUpdateMemory = fpGPA(gpu, (const XGL_CHAR *) "xglCmdUpdateMemory");
589 tab->CmdFillMemory = fpGPA(gpu, (const XGL_CHAR *) "xglCmdFillMemory");
590 tab->CmdClearColorImage = fpGPA(gpu, (const XGL_CHAR *) "xglCmdClearColorImage");
591 tab->CmdClearColorImageRaw = fpGPA(gpu, (const XGL_CHAR *) "xglCmdClearColorImageRaw");
592 tab->CmdClearDepthStencil = fpGPA(gpu, (const XGL_CHAR *) "xglCmdClearDepthStencil");
593 tab->CmdResolveImage = fpGPA(gpu, (const XGL_CHAR *) "xglCmdResolveImage");
594 tab->CmdSetEvent = fpGPA(gpu, (const XGL_CHAR *) "xglCmdSetEvent");
595 tab->CmdResetEvent = fpGPA(gpu, (const XGL_CHAR *) "xglCmdResetEvent");
596 tab->CmdMemoryAtomic = fpGPA(gpu, (const XGL_CHAR *) "xglCmdMemoryAtomic");
597 tab->CmdBeginQuery = fpGPA(gpu, (const XGL_CHAR *) "xglCmdBeginQuery");
598 tab->CmdEndQuery = fpGPA(gpu, (const XGL_CHAR *) "xglCmdEndQuery");
599 tab->CmdResetQueryPool = fpGPA(gpu, (const XGL_CHAR *) "xglCmdResetQueryPool");
600 tab->CmdWriteTimestamp = fpGPA(gpu, (const XGL_CHAR *) "xglCmdWriteTimestamp");
601 tab->CmdInitAtomicCounters = fpGPA(gpu, (const XGL_CHAR *) "xglCmdInitAtomicCounters");
602 tab->CmdLoadAtomicCounters = fpGPA(gpu, (const XGL_CHAR *) "xglCmdLoadAtomicCounters");
603 tab->CmdSaveAtomicCounters = fpGPA(gpu, (const XGL_CHAR *) "xglCmdSaveAtomicCounters");
604 tab->DbgSetValidationLevel = fpGPA(gpu, (const XGL_CHAR *) "xglDbgSetValidationLevel");
605 tab->DbgRegisterMsgCallback = fpGPA(gpu, (const XGL_CHAR *) "xglDbgRegisterMsgCallback");
606 tab->DbgUnregisterMsgCallback = fpGPA(gpu, (const XGL_CHAR *) "xglDbgUnregisterMsgCallback");
607 tab->DbgSetMessageFilter = fpGPA(gpu, (const XGL_CHAR *) "xglDbgSetMessageFilter");
608 tab->DbgSetObjectTag = fpGPA(gpu, (const XGL_CHAR *) "xglDbgSetObjectTag");
609 tab->DbgSetGlobalOption = fpGPA(gpu, (const XGL_CHAR *) "xglDbgSetGlobalOption");
610 tab->DbgSetDeviceOption = fpGPA(gpu, (const XGL_CHAR *) "xglDbgSetDeviceOption");
611 tab->CmdDbgMarkerBegin = fpGPA(gpu, (const XGL_CHAR *) "xglCmdDbgMarkerBegin");
612 tab->CmdDbgMarkerEnd = fpGPA(gpu, (const XGL_CHAR *) "xglCmdDbgMarkerEnd");
613 tab->WsiX11AssociateConnection = fpGPA(gpu, (const XGL_CHAR *) "xglWsiX11AssociateConnection");
614 tab->WsiX11GetMSC = fpGPA(gpu, (const XGL_CHAR *) "xglWsiX11GetMSC");
615 tab->WsiX11CreatePresentableImage = fpGPA(gpu, (const XGL_CHAR *) "xglWsiX11CreatePresentableImage");
616 tab->WsiX11QueuePresent = fpGPA(gpu, (const XGL_CHAR *) "xglWsiX11QueuePresent");
617}
618
Jon Ashburnb55278a2014-10-17 15:09:07 -0600619static struct loader_icd * loader_get_icd(const XGL_BASE_LAYER_OBJECT *gpu, XGL_UINT *gpu_index)
620{
621 for (struct loader_icd * icd = loader.icds; icd; icd = icd->next) {
622 for (XGL_UINT i = 0; i < icd->gpu_count; i++)
623 if ((icd->gpu + i) == gpu) {
624 *gpu_index = i;
625 return icd;
626 }
627 }
628 return NULL;
629}
630
631static void loader_deactivate_layer()
632{
633 struct loader_icd *icd;
634
635 for (icd = loader.icds; icd; icd = icd->next) {
636 //TODO clean up the wrapped gpu structs malloced during layer activation
637 if (icd->gpu)
638 free(icd->gpu);
639 icd->gpu = NULL;
640 icd->gpu_count = 0;
641 if (icd->loader_dispatch)
642 free(icd->loader_dispatch);
643 icd->loader_dispatch = NULL;
644 icd->SetDispatch(NULL, true);
645 icd->layers_activated = false;
646 }
647}
648
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600649extern XGL_UINT ActivateLayers(XGL_PHYSICAL_GPU *gpu)
650{
Jon Ashburnb55278a2014-10-17 15:09:07 -0600651 XGL_UINT gpu_index;
652 struct loader_icd *icd = loader_get_icd((const XGL_BASE_LAYER_OBJECT *) *gpu, &gpu_index);
Jon Ashburn815bddd2014-10-16 15:48:50 -0600653
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600654 /* activate any layer libraries */
Jon Ashburnb55278a2014-10-17 15:09:07 -0600655 // TODO layer active list should be per icd/gpu rather than global
656 if (loader.layer_count > 0 && !icd->layers_activated) {
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600657
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600658 // TODO For now just assume all layers scanned will be activated in the order they were scanned
659 XGL_BASE_LAYER_OBJECT *gpuObj = (XGL_BASE_LAYER_OBJECT *) *gpu;
660 XGL_BASE_LAYER_OBJECT *nextGpuObj;
Jon Ashburn8eecd422014-10-22 12:42:13 -0600661 GetProcAddrType nextGPA = xglGetProcAddr;
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600662 for (XGL_INT i = loader.layer_count - 1; i >= 0; i--) {
663
664 if ((loader.layer_libs[i].lib_handle = dlopen((const char *) &(loader.layer_libs[i].lib_name), RTLD_LAZY | RTLD_DEEPBIND)) == NULL) {
665 loader_log(XGL_DBG_MSG_ERROR, 0, "Failed to open layer library %s got error %d", loader.layer_libs[i].lib_name, dlerror());
666 continue;
667 } else {
668 loader_log(XGL_DBG_MSG_UNKNOWN, 0, "Inserting layer lib %s",loader.layer_libs[i].lib_name);
669 }
670
671 //create newly wrapped gpu object
672 nextGpuObj = malloc(sizeof(XGL_BASE_LAYER_OBJECT));
673 if (! nextGpuObj)
674 loader_log(XGL_DBG_MSG_ERROR, 0, "Failed to malloc Gpu object for layer");
675 nextGpuObj->pGPA = nextGPA;
676 nextGpuObj->baseObject = gpuObj->baseObject;
677 nextGpuObj->nextObject = gpuObj;
678 gpuObj = nextGpuObj;
679
680 nextGPA = dlsym(loader.layer_libs[i].lib_handle, "xglGetProcAddr");
681 if (!nextGPA) {
682 loader_log(XGL_DBG_MSG_ERROR, 0, "Failed to find xglGetProcAddr in layer %s", loader.layer_libs[i].lib_name);
683 continue;
684 }
685
Jon Ashburnb55278a2014-10-17 15:09:07 -0600686 if (i == 0)
687 loader_init_dispatch_table(icd->loader_dispatch + gpu_index, nextGPA, gpuObj);
688
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600689 }
690 *gpu = ((XGL_PHYSICAL_GPU *) gpuObj);
Jon Ashburnb55278a2014-10-17 15:09:07 -0600691 icd->layers_activated = true;
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600692 }
693 return loader.layer_count;
694}
695
696#if 0
697LOADER_EXPORT XGL_RESULT xglSetLayers(const XGL_CHAR * pStr)
698{
699 char *p, *next, *str;
700 int len;
701 XGL_UINT count= 0;
702
703 if (!pStr)
704 return XGL_ERROR_INVALID_POINTER;
705
706 p= (char *) pStr;
707 str = malloc(strlen(p) + 1);
708 do {
709 next = strchr(p, ':');
710 if (next == NULL) {
711 len = strlen(p);
712 next = p + len;
713 }
714 else {
715 len = next - p;
716 *(char *) next = '\0';
717 next++;
718 }
719
720 strncpy(str, p, len);
721 str[len] = '\0';
722 if (layer_lib_sort(str, count))
723 count++;
724 p = next;
725
726 } while (*p && count < MAX_LAYER_LIBRARIES-1);
727
728 for (int i = count; i < loader.layer_count; i++) {
729 loader.layer_libs[i].lib_handle = NULL;
730 }
731
732 loader.layer_count = count;
733 free(str);
734
735 return XGL_SUCCESS;
736}
737
738#endif
739
Jon Ashburn21734942014-10-17 15:31:22 -0600740LOADER_EXPORT XGL_VOID * XGLAPI xglGetProcAddr(XGL_PHYSICAL_GPU gpu, const XGL_CHAR * pName) {
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600741
742 if (gpu == NULL)
743 return NULL;
Jon Ashburn8eecd422014-10-22 12:42:13 -0600744 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
745 XGL_LAYER_DISPATCH_TABLE * disp_table = * (XGL_LAYER_DISPATCH_TABLE **) gpuw->nextObject;
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600746
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600747 if (disp_table == NULL)
748 return NULL;
749
750 if (!strncmp("xglGetProcAddr", (const char *) pName, sizeof("xglGetProcAddr")))
751 return xglGetProcAddr;
752 else if (!strncmp("xglInitAndEnumerateGpus", (const char *) pName, sizeof("xglInitAndEnumerateGpus")))
753 return disp_table->InitAndEnumerateGpus;
754 else if (!strncmp("xglGetGpuInfo", (const char *) pName, sizeof ("xglGetGpuInfo")))
755 return disp_table->GetGpuInfo;
756 else if (!strncmp("xglCreateDevice", (const char *) pName, sizeof ("xglCreateDevice")))
757 return disp_table->CreateDevice;
758 else if (!strncmp("xglDestroyDevice", (const char *) pName, sizeof ("xglDestroyDevice")))
759 return disp_table->DestroyDevice;
760 else if (!strncmp("xglGetExtensionSupport", (const char *) pName, sizeof ("xglGetExtensionSupport")))
761 return disp_table->GetExtensionSupport;
Jon Ashburn96f28fc2014-10-15 15:30:23 -0600762 else if (!strncmp("xglEnumerateLayers", (const char *) pName, sizeof ("xglEnumerateLayers")))
763 return disp_table->EnumerateLayers;
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600764 else if (!strncmp("xglGetDeviceQueue", (const char *) pName, sizeof ("xglGetDeviceQueue")))
765 return disp_table->GetDeviceQueue;
766 else if (!strncmp("xglQueueSubmit", (const char *) pName, sizeof ("xglQueueSubmit")))
767 return disp_table->QueueSubmit;
768 else if (!strncmp("xglQueueSetGlobalMemReferences", (const char *) pName, sizeof ("xglQueueSetGlobalMemReferences")))
769 return disp_table->QueueSetGlobalMemReferences;
770 else if (!strncmp("xglQueueWaitIdle", (const char *) pName, sizeof ("xglQueueWaitIdle")))
771 return disp_table->QueueWaitIdle;
772 else if (!strncmp("xglDeviceWaitIdle", (const char *) pName, sizeof ("xglDeviceWaitIdle")))
773 return disp_table->DeviceWaitIdle;
774 else if (!strncmp("xglGetMemoryHeapCount", (const char *) pName, sizeof ("xglGetMemoryHeapCount")))
775 return disp_table->GetMemoryHeapCount;
776 else if (!strncmp("xglGetMemoryHeapInfo", (const char *) pName, sizeof ("xglGetMemoryHeapInfo")))
777 return disp_table->GetMemoryHeapInfo;
778 else if (!strncmp("xglAllocMemory", (const char *) pName, sizeof ("xglAllocMemory")))
779 return disp_table->AllocMemory;
780 else if (!strncmp("xglFreeMemory", (const char *) pName, sizeof ("xglFreeMemory")))
781 return disp_table->FreeMemory;
782 else if (!strncmp("xglSetMemoryPriority", (const char *) pName, sizeof ("xglSetMemoryPriority")))
783 return disp_table->SetMemoryPriority;
784 else if (!strncmp("xglMapMemory", (const char *) pName, sizeof ("xglMapMemory")))
785 return disp_table->MapMemory;
786 else if (!strncmp("xglUnmapMemory", (const char *) pName, sizeof ("xglUnmapMemory")))
787 return disp_table->UnmapMemory;
788 else if (!strncmp("xglPinSystemMemory", (const char *) pName, sizeof ("xglPinSystemMemory")))
789 return disp_table->PinSystemMemory;
790 else if (!strncmp("xglRemapVirtualMemoryPages", (const char *) pName, sizeof ("xglRemapVirtualMemoryPages")))
791 return disp_table->RemapVirtualMemoryPages;
792 else if (!strncmp("xglGetMultiGpuCompatibility", (const char *) pName, sizeof ("xglGetMultiGpuCompatibility")))
793 return disp_table->GetMultiGpuCompatibility;
794 else if (!strncmp("xglOpenSharedMemory", (const char *) pName, sizeof ("xglOpenSharedMemory")))
795 return disp_table->OpenSharedMemory;
796 else if (!strncmp("xglOpenSharedQueueSemaphore", (const char *) pName, sizeof ("xglOpenSharedQueueSemaphore")))
797 return disp_table->OpenSharedQueueSemaphore;
798 else if (!strncmp("xglOpenPeerMemory", (const char *) pName, sizeof ("xglOpenPeerMemory")))
799 return disp_table->OpenPeerMemory;
800 else if (!strncmp("xglOpenPeerImage", (const char *) pName, sizeof ("xglOpenPeerImage")))
801 return disp_table->OpenPeerImage;
802 else if (!strncmp("xglDestroyObject", (const char *) pName, sizeof ("xglDestroyObject")))
803 return disp_table->DestroyObject;
804 else if (!strncmp("xglGetObjectInfo", (const char *) pName, sizeof ("xglGetObjectInfo")))
805 return disp_table->GetObjectInfo;
806 else if (!strncmp("xglBindObjectMemory", (const char *) pName, sizeof ("xglBindObjectMemory")))
807 return disp_table->BindObjectMemory;
808 else if (!strncmp("xglCreateFence", (const char *) pName, sizeof ("xgllCreateFence")))
809 return disp_table->CreateFence;
810 else if (!strncmp("xglGetFenceStatus", (const char *) pName, sizeof ("xglGetFenceStatus")))
811 return disp_table->GetFenceStatus;
812 else if (!strncmp("xglWaitForFences", (const char *) pName, sizeof ("xglWaitForFences")))
813 return disp_table->WaitForFences;
814 else if (!strncmp("xglCreateQueueSemaphore", (const char *) pName, sizeof ("xgllCreateQueueSemaphore")))
815 return disp_table->CreateQueueSemaphore;
816 else if (!strncmp("xglSignalQueueSemaphore", (const char *) pName, sizeof ("xglSignalQueueSemaphore")))
817 return disp_table->SignalQueueSemaphore;
818 else if (!strncmp("xglWaitQueueSemaphore", (const char *) pName, sizeof ("xglWaitQueueSemaphore")))
819 return disp_table->WaitQueueSemaphore;
820 else if (!strncmp("xglCreateEvent", (const char *) pName, sizeof ("xgllCreateEvent")))
821 return disp_table->CreateEvent;
822 else if (!strncmp("xglGetEventStatus", (const char *) pName, sizeof ("xglGetEventStatus")))
823 return disp_table->GetEventStatus;
824 else if (!strncmp("xglSetEvent", (const char *) pName, sizeof ("xglSetEvent")))
825 return disp_table->SetEvent;
826 else if (!strncmp("xglResetEvent", (const char *) pName, sizeof ("xgllResetEvent")))
827 return disp_table->ResetEvent;
828 else if (!strncmp("xglCreateQueryPool", (const char *) pName, sizeof ("xglCreateQueryPool")))
829 return disp_table->CreateQueryPool;
830 else if (!strncmp("xglGetQueryPoolResults", (const char *) pName, sizeof ("xglGetQueryPoolResults")))
831 return disp_table->GetQueryPoolResults;
832 else if (!strncmp("xglGetFormatInfo", (const char *) pName, sizeof ("xglGetFormatInfo")))
833 return disp_table->GetFormatInfo;
834 else if (!strncmp("xglCreateImage", (const char *) pName, sizeof ("xglCreateImage")))
835 return disp_table->CreateImage;
836 else if (!strncmp("xglGetImageSubresourceInfo", (const char *) pName, sizeof ("xglGetImageSubresourceInfo")))
837 return disp_table->GetImageSubresourceInfo;
838 else if (!strncmp("xglCreateImageView", (const char *) pName, sizeof ("xglCreateImageView")))
839 return disp_table->CreateImageView;
840 else if (!strncmp("xglCreateColorAttachmentView", (const char *) pName, sizeof ("xglCreateColorAttachmentView")))
841 return disp_table->CreateColorAttachmentView;
842 else if (!strncmp("xglCreateDepthStencilView", (const char *) pName, sizeof ("xglCreateDepthStencilView")))
843 return disp_table->CreateDepthStencilView;
844 else if (!strncmp("xglCreateShader", (const char *) pName, sizeof ("xglCreateShader")))
845 return disp_table->CreateShader;
846 else if (!strncmp("xglCreateGraphicsPipeline", (const char *) pName, sizeof ("xglCreateGraphicsPipeline")))
847 return disp_table->CreateGraphicsPipeline;
848 else if (!strncmp("xglCreateComputePipeline", (const char *) pName, sizeof ("xglCreateComputePipeline")))
849 return disp_table->CreateComputePipeline;
850 else if (!strncmp("xglStorePipeline", (const char *) pName, sizeof ("xglStorePipeline")))
851 return disp_table->StorePipeline;
852 else if (!strncmp("xglLoadPipeline", (const char *) pName, sizeof ("xglLoadPipeline")))
853 return disp_table->LoadPipeline;
854 else if (!strncmp("xglCreatePipelineDelta", (const char *) pName, sizeof ("xglCreatePipelineDelta")))
855 return disp_table->CreatePipelineDelta;
856 else if (!strncmp("xglCreateSampler", (const char *) pName, sizeof ("xglCreateSampler")))
857 return disp_table->CreateSampler;
858 else if (!strncmp("xglCreateDescriptorSet", (const char *) pName, sizeof ("xglCreateDescriptorSet")))
859 return disp_table->CreateDescriptorSet;
860 else if (!strncmp("xglBeginDescriptorSetUpdate", (const char *) pName, sizeof ("xglBeginDescriptorSetUpdate")))
861 return disp_table->BeginDescriptorSetUpdate;
862 else if (!strncmp("xglEndDescriptorSetUpdate", (const char *) pName, sizeof ("xglEndDescriptorSetUpdate")))
863 return disp_table->EndDescriptorSetUpdate;
864 else if (!strncmp("xglAttachSamplerDescriptors", (const char *) pName, sizeof ("xglAttachSamplerDescriptors")))
865 return disp_table->AttachSamplerDescriptors;
866 else if (!strncmp("xglAttachImageViewDescriptors", (const char *) pName, sizeof ("xglAttachImageViewDescriptors")))
867 return disp_table->AttachImageViewDescriptors;
868 else if (!strncmp("xglAttachMemoryViewDescriptors", (const char *) pName, sizeof ("xglAttachMemoryViewDescriptors")))
869 return disp_table->AttachMemoryViewDescriptors;
870 else if (!strncmp("xglAttachNestedDescriptors", (const char *) pName, sizeof ("xglAttachNestedDescriptors")))
871 return disp_table->AttachNestedDescriptors;
872 else if (!strncmp("xglClearDescriptorSetSlots", (const char *) pName, sizeof ("xglClearDescriptorSetSlots")))
873 return disp_table->ClearDescriptorSetSlots;
874 else if (!strncmp("xglCreateViewportState", (const char *) pName, sizeof ("xglCreateViewportState")))
875 return disp_table->CreateViewportState;
876 else if (!strncmp("xglCreateRasterState", (const char *) pName, sizeof ("xglCreateRasterState")))
877 return disp_table->CreateRasterState;
878 else if (!strncmp("xglCreateMsaaState", (const char *) pName, sizeof ("xglCreateMsaaState")))
879 return disp_table->CreateMsaaState;
880 else if (!strncmp("xglCreateColorBlendState", (const char *) pName, sizeof ("xglCreateColorBlendState")))
881 return disp_table->CreateColorBlendState;
882 else if (!strncmp("xglCreateDepthStencilState", (const char *) pName, sizeof ("xglCreateDepthStencilState")))
883 return disp_table->CreateDepthStencilState;
884 else if (!strncmp("xglCreateCommandBuffer", (const char *) pName, sizeof ("xglCreateCommandBuffer")))
885 return disp_table->CreateCommandBuffer;
886 else if (!strncmp("xglBeginCommandBuffer", (const char *) pName, sizeof ("xglBeginCommandBuffer")))
887 return disp_table->BeginCommandBuffer;
888 else if (!strncmp("xglEndCommandBuffer", (const char *) pName, sizeof ("xglEndCommandBuffer")))
889 return disp_table->EndCommandBuffer;
890 else if (!strncmp("xglResetCommandBuffer", (const char *) pName, sizeof ("xglResetCommandBuffer")))
891 return disp_table->ResetCommandBuffer;
892 else if (!strncmp("xglCmdBindPipeline", (const char *) pName, sizeof ("xglCmdBindPipeline")))
893 return disp_table->CmdBindPipeline;
894 else if (!strncmp("xglCmdBindPipelineDelta", (const char *) pName, sizeof ("xglCmdBindPipelineDelta")))
895 return disp_table->CmdBindPipelineDelta;
896 else if (!strncmp("xglCmdBindStateObject", (const char *) pName, sizeof ("xglCmdBindStateObject")))
897 return disp_table->CmdBindStateObject;
898 else if (!strncmp("xglCmdBindDescriptorSet", (const char *) pName, sizeof ("xglCmdBindDescriptorSet")))
899 return disp_table->CmdBindDescriptorSet;
900 else if (!strncmp("xglCmdBindDynamicMemoryView", (const char *) pName, sizeof ("xglCmdBindDynamicMemoryView")))
901 return disp_table->CmdBindDynamicMemoryView;
902 else if (!strncmp("xglCmdBindIndexData", (const char *) pName, sizeof ("xglCmdBindIndexData")))
903 return disp_table->CmdBindIndexData;
904 else if (!strncmp("xglCmdBindAttachments", (const char *) pName, sizeof ("xglCmdBindAttachments")))
905 return disp_table->CmdBindAttachments;
906 else if (!strncmp("xglCmdPrepareMemoryRegions", (const char *) pName, sizeof ("xglCmdPrepareMemoryRegions")))
907 return disp_table->CmdPrepareMemoryRegions;
908 else if (!strncmp("xglCmdPrepareImages", (const char *) pName, sizeof ("xglCmdPrepareImages")))
909 return disp_table->CmdPrepareImages;
910 else if (!strncmp("xglCmdDraw", (const char *) pName, sizeof ("xglCmdDraw")))
911 return disp_table->CmdDraw;
912 else if (!strncmp("xglCmdDrawIndexed", (const char *) pName, sizeof ("xglCmdDrawIndexed")))
913 return disp_table->CmdDrawIndexed;
914 else if (!strncmp("xglCmdDrawIndirect", (const char *) pName, sizeof ("xglCmdDrawIndirect")))
915 return disp_table->CmdDrawIndirect;
916 else if (!strncmp("xglCmdDrawIndexedIndirect", (const char *) pName, sizeof ("xglCmdDrawIndexedIndirect")))
917 return disp_table->CmdDrawIndexedIndirect;
918 else if (!strncmp("xglCmdDispatch", (const char *) pName, sizeof ("xglCmdDispatch")))
919 return disp_table->CmdDispatch;
920 else if (!strncmp("xglCmdDispatchIndirect", (const char *) pName, sizeof ("xglCmdDispatchIndirect")))
921 return disp_table->CmdDispatchIndirect;
922 else if (!strncmp("xglCmdCopyMemory", (const char *) pName, sizeof ("xglCmdCopyMemory")))
923 return disp_table->CmdCopyMemory;
924 else if (!strncmp("xglCmdCopyImage", (const char *) pName, sizeof ("xglCmdCopyImage")))
925 return disp_table->CmdCopyImage;
926 else if (!strncmp("xglCmdCopyMemoryToImage", (const char *) pName, sizeof ("xglCmdCopyMemoryToImage")))
927 return disp_table->CmdCopyMemoryToImage;
928 else if (!strncmp("xglCmdCopyImageToMemory", (const char *) pName, sizeof ("xglCmdCopyImageToMemory")))
929 return disp_table->CmdCopyImageToMemory;
930 else if (!strncmp("xglCmdCloneImageData", (const char *) pName, sizeof ("xglCmdCloneImageData")))
931 return disp_table->CmdCloneImageData;
932 else if (!strncmp("xglCmdUpdateMemory", (const char *) pName, sizeof ("xglCmdUpdateMemory")))
933 return disp_table->CmdUpdateMemory;
934 else if (!strncmp("xglCmdFillMemory", (const char *) pName, sizeof ("xglCmdFillMemory")))
935 return disp_table->CmdFillMemory;
936 else if (!strncmp("xglCmdClearColorImage", (const char *) pName, sizeof ("xglCmdClearColorImage")))
937 return disp_table->CmdClearColorImage;
938 else if (!strncmp("xglCmdClearColorImageRaw", (const char *) pName, sizeof ("xglCmdClearColorImageRaw")))
939 return disp_table->CmdClearColorImageRaw;
940 else if (!strncmp("xglCmdClearDepthStencil", (const char *) pName, sizeof ("xglCmdClearDepthStencil")))
941 return disp_table->CmdClearDepthStencil;
942 else if (!strncmp("xglCmdResolveImage", (const char *) pName, sizeof ("xglCmdResolveImage")))
943 return disp_table->CmdResolveImage;
944 else if (!strncmp("xglCmdSetEvent", (const char *) pName, sizeof ("xglCmdSetEvent")))
945 return disp_table->CmdSetEvent;
946 else if (!strncmp("xglCmdResetEvent", (const char *) pName, sizeof ("xglCmdResetEvent")))
947 return disp_table->CmdResetEvent;
948 else if (!strncmp("xglCmdMemoryAtomic", (const char *) pName, sizeof ("xglCmdMemoryAtomic")))
949 return disp_table->CmdMemoryAtomic;
950 else if (!strncmp("xglCmdBeginQuery", (const char *) pName, sizeof ("xglCmdBeginQuery")))
951 return disp_table->CmdBeginQuery;
952 else if (!strncmp("xglCmdEndQuery", (const char *) pName, sizeof ("xglCmdEndQuery")))
953 return disp_table->CmdEndQuery;
954 else if (!strncmp("xglCmdResetQueryPool", (const char *) pName, sizeof ("xglCmdResetQueryPool")))
955 return disp_table->CmdResetQueryPool;
956 else if (!strncmp("xglCmdWriteTimestamp", (const char *) pName, sizeof ("xglCmdWriteTimestamp")))
957 return disp_table->CmdWriteTimestamp;
958 else if (!strncmp("xglCmdInitAtomicCounters", (const char *) pName, sizeof ("xglCmdInitAtomicCounters")))
959 return disp_table->CmdInitAtomicCounters;
960 else if (!strncmp("xglCmdLoadAtomicCounters", (const char *) pName, sizeof ("xglCmdLoadAtomicCounters")))
961 return disp_table->CmdLoadAtomicCounters;
962 else if (!strncmp("xglCmdSaveAtomicCounters", (const char *) pName, sizeof ("xglCmdSaveAtomicCounters")))
963 return disp_table->CmdSaveAtomicCounters;
964 else if (!strncmp("xglDbgSetValidationLevel", (const char *) pName, sizeof ("xglDbgSetValidationLevel")))
965 return disp_table->DbgSetValidationLevel;
966 else if (!strncmp("xglDbgRegisterMsgCallback", (const char *) pName, sizeof ("xglDbgRegisterMsgCallback")))
967 return disp_table->DbgRegisterMsgCallback;
968 else if (!strncmp("xglDbgUnregisterMsgCallback", (const char *) pName, sizeof ("xglDbgUnregisterMsgCallback")))
969 return disp_table->DbgUnregisterMsgCallback;
970 else if (!strncmp("xglDbgSetMessageFilter", (const char *) pName, sizeof ("xglDbgSetMessageFilter")))
971 return disp_table->DbgSetMessageFilter;
972 else if (!strncmp("xglDbgSetObjectTag", (const char *) pName, sizeof ("xglDbgSetObjectTag")))
973 return disp_table->DbgSetObjectTag;
974 else if (!strncmp("xglDbgSetGlobalOption", (const char *) pName, sizeof ("xglDbgSetGlobalOption")))
975 return disp_table->DbgSetGlobalOption;
976 else if (!strncmp("xglDbgSetDeviceOption", (const char *) pName, sizeof ("xglDbgSetDeviceOption")))
977 return disp_table->DbgSetDeviceOption;
978 else if (!strncmp("xglCmdDbgMarkerBegin", (const char *) pName, sizeof ("xglCmdDbgMarkerBegin")))
979 return disp_table->CmdDbgMarkerBegin;
980 else if (!strncmp("xglCmdDbgMarkerEnd", (const char *) pName, sizeof ("xglCmdDbgMarkerEnd")))
981 return disp_table->CmdDbgMarkerEnd;
982 else if (!strncmp("xglWsiX11AssociateConnection", (const char *) pName, sizeof("xglWsiX11AssociateConnection")))
983 return disp_table->WsiX11AssociateConnection;
984 else if (!strncmp("xglWsiX11GetMSC", (const char *) pName, sizeof("xglWsiX11GetMSC")))
985 return disp_table->WsiX11GetMSC;
986 else if (!strncmp("xglWsiX11CreatePresentableImage", (const char *) pName, sizeof("xglWsiX11CreatePresentableImage")))
987 return disp_table->WsiX11CreatePresentableImage;
988 else if (!strncmp("xglWsiX11QueuePresent", (const char *) pName, sizeof("xglWsiX11QueuePresent")))
989 return disp_table->WsiX11QueuePresent;
990 else {
991 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
992 if (gpuw->pGPA == NULL)
993 return NULL;
994 return gpuw->pGPA(gpuw->nextObject, pName);
995 }
996}
997
Chia-I Wu468e3c32014-08-04 08:03:57 +0800998LOADER_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 +0800999{
1000 static pthread_once_t once = PTHREAD_ONCE_INIT;
Jon Ashburn815bddd2014-10-16 15:48:50 -06001001 struct loader_icd *icd;
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001002 XGL_UINT count = 0;
1003 XGL_RESULT res;
1004
Jon Ashburn815bddd2014-10-16 15:48:50 -06001005 // cleanup any prior layer initializations
Jon Ashburnb55278a2014-10-17 15:09:07 -06001006 loader_deactivate_layer();
Jon Ashburn815bddd2014-10-16 15:48:50 -06001007
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001008 pthread_once(&once, loader_icd_scan);
1009
1010 if (!loader.icds)
1011 return XGL_ERROR_UNAVAILABLE;
1012
1013 icd = loader.icds;
1014 while (icd) {
1015 XGL_PHYSICAL_GPU gpus[XGL_MAX_PHYSICAL_GPUS];
Jon Ashburnd43f9b62014-10-14 19:15:22 -06001016 XGL_BASE_LAYER_OBJECT * wrappedGpus;
1017 GetProcAddrType getProcAddr = icd->GetProcAddr;
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001018 XGL_UINT n, max = maxGpus - count;
1019
1020 if (max > XGL_MAX_PHYSICAL_GPUS) {
1021 max = XGL_MAX_PHYSICAL_GPUS;
1022 }
1023
1024 res = icd->InitAndEnumerateGpus(pAppInfo, pAllocCb, max, &n, gpus);
Chia-I Wu74916ed2014-08-06 12:17:04 +08001025 if (res == XGL_SUCCESS && n) {
Jon Ashburnd43f9b62014-10-14 19:15:22 -06001026 wrappedGpus = (XGL_BASE_LAYER_OBJECT*) malloc(n * sizeof(XGL_BASE_LAYER_OBJECT));
Jon Ashburnb55278a2014-10-17 15:09:07 -06001027 icd->gpu = wrappedGpus;
1028 icd->gpu_count = n;
Jon Ashburn815bddd2014-10-16 15:48:50 -06001029 icd->loader_dispatch = (XGL_LAYER_DISPATCH_TABLE *) malloc(n * sizeof(XGL_LAYER_DISPATCH_TABLE));
Jon Ashburnd43f9b62014-10-14 19:15:22 -06001030 for (int i = 0; i < n; i++) {
1031 (wrappedGpus + i)->baseObject = gpus[i];
Jon Ashburn815bddd2014-10-16 15:48:50 -06001032 (wrappedGpus + i)->pGPA = getProcAddr;
Jon Ashburnd43f9b62014-10-14 19:15:22 -06001033 (wrappedGpus + i)->nextObject = gpus[i];
1034 memcpy(pGpus + count, &wrappedGpus, sizeof(*pGpus));
Jon Ashburn8eecd422014-10-22 12:42:13 -06001035 loader_init_dispatch_table(icd->loader_dispatch + i, getProcAddr, gpus[i]);
Jon Ashburnd43f9b62014-10-14 19:15:22 -06001036 const XGL_LAYER_DISPATCH_TABLE * *disp = (const XGL_LAYER_DISPATCH_TABLE * *) gpus[i];
Jon Ashburn815bddd2014-10-16 15:48:50 -06001037 *disp = icd->loader_dispatch + i;
1038 icd->SetDispatch(icd->loader_dispatch + i, true);
Jon Ashburnd43f9b62014-10-14 19:15:22 -06001039 }
1040
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001041 count += n;
1042
1043 if (count >= maxGpus) {
1044 break;
1045 }
1046 }
1047
1048 icd = icd->next;
1049 }
1050
Jon Ashburnd43f9b62014-10-14 19:15:22 -06001051 /* get layer libraries */
1052 if (!loader.layer_scaned)
1053 layer_lib_scan(NULL, true, false);
1054
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001055 *pGpuCount = count;
1056
1057 return (count > 0) ? XGL_SUCCESS : res;
1058}
1059
Jon Ashburn96f28fc2014-10-15 15:30:23 -06001060LOADER_EXPORT XGL_RESULT XGLAPI xglEnumerateLayers(XGL_PHYSICAL_GPU gpu, XGL_SIZE maxLayerCount, XGL_SIZE maxStringSize, XGL_CHAR* const* pOutLayers, XGL_SIZE* pOutLayerCount)
1061{
1062 XGL_SIZE count = loader.layer_count;
1063 // TODO handle layers per GPU, multiple icds
1064
1065 if (pOutLayerCount == NULL)
1066 return XGL_ERROR_INVALID_POINTER;
1067
1068 if (maxLayerCount < loader.layer_count)
1069 count = maxLayerCount;
1070 *pOutLayerCount = count;
1071
1072 if (pOutLayers == NULL)
1073 return XGL_SUCCESS;
1074 for (XGL_SIZE i = 0; i < count; i++) {
1075 strncpy((char *) (pOutLayers[i]), loader.layer_libs[i].lib_name, maxStringSize);
1076 if (maxStringSize > 0)
1077 pOutLayers[i][maxStringSize - 1] = '\0';
1078 }
1079 return XGL_SUCCESS;
1080}
1081
Chia-I Wu468e3c32014-08-04 08:03:57 +08001082LOADER_EXPORT XGL_RESULT XGLAPI xglDbgRegisterMsgCallback(XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback, XGL_VOID* pUserData)
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001083{
1084 const struct loader_icd *icd = loader.icds;
1085 XGL_RESULT res;
1086
1087 if (!loader.scanned) {
1088 return loader_msg_callback_add(pfnMsgCallback, pUserData);
1089 }
1090
1091 while (icd) {
1092 res = icd->DbgRegisterMsgCallback(pfnMsgCallback, pUserData);
1093 if (res != XGL_SUCCESS) {
1094 break;
1095 }
1096
1097 icd = icd->next;
1098 }
1099
1100 /* roll back on errors */
1101 if (icd) {
1102 const struct loader_icd *tmp = loader.icds;
1103
1104 while (tmp != icd) {
1105 tmp->DbgUnregisterMsgCallback(pfnMsgCallback);
1106 tmp = tmp->next;
1107 }
1108
1109 return res;
1110 }
1111
1112 return XGL_SUCCESS;
1113}
1114
Chia-I Wu468e3c32014-08-04 08:03:57 +08001115LOADER_EXPORT XGL_RESULT XGLAPI xglDbgUnregisterMsgCallback(XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback)
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001116{
1117 const struct loader_icd *icd = loader.icds;
1118 XGL_RESULT res = XGL_SUCCESS;
1119
1120 if (!loader.scanned) {
1121 return loader_msg_callback_remove(pfnMsgCallback);
1122 }
1123
1124 while (icd) {
1125 XGL_RESULT r = icd->DbgUnregisterMsgCallback(pfnMsgCallback);
1126 if (r != XGL_SUCCESS) {
1127 res = r;
1128 }
1129 icd = icd->next;
1130 }
1131
1132 return res;
1133}
1134
Chia-I Wu468e3c32014-08-04 08:03:57 +08001135LOADER_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 +08001136{
1137 const struct loader_icd *icd = loader.icds;
1138 XGL_RESULT res = XGL_SUCCESS;
1139
1140 if (!loader.scanned) {
1141 if (dataSize == 0)
1142 return XGL_ERROR_INVALID_VALUE;
1143
1144 switch (dbgOption) {
1145 case XGL_DBG_OPTION_DEBUG_ECHO_ENABLE:
1146 loader.debug_echo_enable = *((const bool *) pData);
1147 break;
1148 case XGL_DBG_OPTION_BREAK_ON_ERROR:
1149 loader.break_on_error = *((const bool *) pData);
1150 break;
1151 case XGL_DBG_OPTION_BREAK_ON_WARNING:
1152 loader.break_on_warning = *((const bool *) pData);
1153 break;
1154 default:
1155 res = XGL_ERROR_INVALID_VALUE;
1156 break;
1157 }
1158
1159 return res;
1160 }
1161
1162 while (icd) {
1163 XGL_RESULT r = icd->DbgSetGlobalOption(dbgOption, dataSize, pData);
1164 /* unfortunately we cannot roll back */
1165 if (r != XGL_SUCCESS) {
1166 res = r;
1167 }
1168
1169 icd = icd->next;
1170 }
1171
1172 return res;
1173}