blob: 87730bee3f19582f3ad6c919321b17b8625359eb [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>
Jon Ashburn406a0fe2014-11-14 09:52:42 -070026 * Jon Ashburn <jon@lunarg.com>
Chia-I Wu44e42362014-09-02 08:32:09 +080027 * Courtney Goeltzenleuchter <courtney@lunarg.com>
Chia-I Wu5f72d0f2014-08-01 11:21:23 +080028 */
Jon Ashburn183dfd02014-10-22 18:13:16 -060029#define _GNU_SOURCE
Chia-I Wu5f72d0f2014-08-01 11:21:23 +080030#include <stdio.h>
31#include <stdlib.h>
32#include <stdarg.h>
33#include <stdbool.h>
34#include <string.h>
35
Chia-I Wu894a1172014-08-04 11:18:20 +080036#include <sys/types.h>
37#include <dirent.h>
Courtney Goeltzenleuchter4af9bd12014-08-01 14:18:11 -060038#include <unistd.h>
Chia-I Wu5f72d0f2014-08-01 11:21:23 +080039#include <dlfcn.h>
40#include <pthread.h>
Jon Ashburnd43f9b62014-10-14 19:15:22 -060041#include <assert.h>
Chia-I Wu468e3c32014-08-04 08:03:57 +080042#include "loader.h"
Chia-I Wu5f72d0f2014-08-01 11:21:23 +080043
Jon Ashburn183dfd02014-10-22 18:13:16 -060044struct loader_layers {
45 void *lib_handle;
Jon Ashburnead95c52014-11-18 09:06:04 -070046 char name[256];
47};
48
49struct layer_name_pair {
50 char *layer_name;
51 const char *lib_name;
Jon Ashburn183dfd02014-10-22 18:13:16 -060052};
53
Chia-I Wu5f72d0f2014-08-01 11:21:23 +080054struct loader_icd {
55 void *handle;
56
Jon Ashburnb55278a2014-10-17 15:09:07 -060057 XGL_LAYER_DISPATCH_TABLE *loader_dispatch;
Jon Ashburn183dfd02014-10-22 18:13:16 -060058 XGL_UINT layer_count[XGL_MAX_PHYSICAL_GPUS];
59 struct loader_layers layer_libs[XGL_MAX_PHYSICAL_GPUS][MAX_LAYER_LIBRARIES];
Jon Ashburnb4d00532014-10-22 21:15:26 -060060 XGL_BASE_LAYER_OBJECT *wrappedGpus[XGL_MAX_PHYSICAL_GPUS];
Jon Ashburnb55278a2014-10-17 15:09:07 -060061 XGL_UINT gpu_count;
Jon Ashburn183dfd02014-10-22 18:13:16 -060062 XGL_BASE_LAYER_OBJECT *gpus;
Jon Ashburn815bddd2014-10-16 15:48:50 -060063
Jon Ashburnd43f9b62014-10-14 19:15:22 -060064 GetProcAddrType GetProcAddr;
65 InitAndEnumerateGpusType InitAndEnumerateGpus;
Chia-I Wu5f72d0f2014-08-01 11:21:23 +080066
67 struct loader_icd *next;
68};
69
Jon Ashburnd43f9b62014-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 Ashburnd43f9b62014-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 Ashburn183dfd02014-10-22 18:13:16 -060082 bool layer_scanned;
Courtney Goeltzenleuchterbce445a2014-12-01 09:29:42 -070083 char *layer_dirs;
Jon Ashburn183dfd02014-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 Goeltzenleuchter6f928162014-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 Ashburnd43f9b62014-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 Ashburnd43f9b62014-10-14 19:15:22 -0600224 LOOKUP(icd, GetProcAddr);
Chia-I Wu5f72d0f2014-08-01 11:21:23 +0800225 LOOKUP(icd, InitAndEnumerateGpus);
Chia-I Wu5f72d0f2014-08-01 11:21:23 +0800226#undef LOOKUP
227
228 return icd;
229}
230
231static XGL_RESULT loader_icd_register_msg_callbacks(const struct loader_icd *icd)
232{
233 const struct loader_msg_callback *cb = loader.msg_callbacks;
234 XGL_RESULT res;
235
236 while (cb) {
Jon Ashburn406a0fe2014-11-14 09:52:42 -0700237 for (XGL_UINT i = 0; i < icd->gpu_count; i++) {
238 res = (icd->loader_dispatch + i)->DbgRegisterMsgCallback(cb->func, cb->data);
239 if (res != XGL_SUCCESS) {
240 break;
241 }
Chia-I Wu5f72d0f2014-08-01 11:21:23 +0800242 }
Chia-I Wu5f72d0f2014-08-01 11:21:23 +0800243 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) {
Jon Ashburn406a0fe2014-11-14 09:52:42 -0700251 for (XGL_UINT i = 0; i < icd->gpu_count; i++) {
252 (icd->loader_dispatch + i)->DbgUnregisterMsgCallback(cb->func);
253 }
Chia-I Wu5f72d0f2014-08-01 11:21:23 +0800254 tmp = tmp->next;
255 }
256
257 return res;
258 }
259
260 return XGL_SUCCESS;
261}
262
263static XGL_RESULT loader_icd_set_global_options(const struct loader_icd *icd)
264{
265#define SETB(icd, opt, val) do { \
266 if (val) { \
Jon Ashburn406a0fe2014-11-14 09:52:42 -0700267 for (XGL_UINT i = 0; i < icd->gpu_count; i++) { \
268 const XGL_RESULT res = \
269 (icd->loader_dispatch + i)->DbgSetGlobalOption(opt, sizeof(val), &val); \
270 if (res != XGL_SUCCESS) \
271 return res; \
272 } \
Chia-I Wu5f72d0f2014-08-01 11:21:23 +0800273 } \
274} while (0)
275 SETB(icd, XGL_DBG_OPTION_DEBUG_ECHO_ENABLE, loader.debug_echo_enable);
276 SETB(icd, XGL_DBG_OPTION_BREAK_ON_ERROR, loader.break_on_error);
277 SETB(icd, XGL_DBG_OPTION_BREAK_ON_WARNING, loader.break_on_warning);
278#undef SETB
279
280return XGL_SUCCESS;
281}
282
Chia-I Wu894a1172014-08-04 11:18:20 +0800283static struct loader_icd *loader_icd_add(const char *filename)
284{
285 struct loader_icd *icd;
286
287 icd = loader_icd_create(filename);
288 if (!icd)
289 return NULL;
290
Chia-I Wu894a1172014-08-04 11:18:20 +0800291 /* prepend to the list */
292 icd->next = loader.icds;
293 loader.icds = icd;
294
295 return icd;
296}
297
Courtney Goeltzenleuchter4af9bd12014-08-01 14:18:11 -0600298#ifndef DEFAULT_XGL_DRIVERS_PATH
299// TODO: Is this a good default location?
300// Need to search for both 32bit and 64bit ICDs
301#define DEFAULT_XGL_DRIVERS_PATH "/usr/lib/i386-linux-gnu/xgl:/usr/lib/x86_64-linux-gnu/xgl"
302#endif
303
304/**
305 * Try to \c loader_icd_scan XGL driver(s).
306 *
307 * This function scans the default system path or path
308 * specified by the \c LIBXGL_DRIVERS_PATH environment variable in
309 * order to find loadable XGL ICDs with the name of libXGL_*.
310 *
311 * \returns
312 * void; but side effect is to set loader_icd_scanned to true
313 */
314static void loader_icd_scan(void)
Chia-I Wu5f72d0f2014-08-01 11:21:23 +0800315{
Courtney Goeltzenleuchter4af9bd12014-08-01 14:18:11 -0600316 const char *libPaths, *p, *next;
317 DIR *sysdir;
318 struct dirent *dent;
319 char icd_library[1024];
Jon Ashburn0f45b2a2014-10-03 16:31:35 -0600320 char path[1024];
Courtney Goeltzenleuchter4af9bd12014-08-01 14:18:11 -0600321 int len;
Chia-I Wu5f72d0f2014-08-01 11:21:23 +0800322
Courtney Goeltzenleuchter4af9bd12014-08-01 14:18:11 -0600323 libPaths = NULL;
324 if (geteuid() == getuid()) {
325 /* don't allow setuid apps to use LIBXGL_DRIVERS_PATH */
326 libPaths = getenv("LIBXGL_DRIVERS_PATH");
327 }
328 if (libPaths == NULL)
329 libPaths = DEFAULT_XGL_DRIVERS_PATH;
Chia-I Wu5f72d0f2014-08-01 11:21:23 +0800330
Courtney Goeltzenleuchter4af9bd12014-08-01 14:18:11 -0600331 for (p = libPaths; *p; p = next) {
332 next = strchr(p, ':');
333 if (next == NULL) {
334 len = strlen(p);
335 next = p + len;
336 }
337 else {
338 len = next - p;
Jon Ashburn0f45b2a2014-10-03 16:31:35 -0600339 sprintf(path, "%.*s", (len > sizeof(path) - 1) ? (int) sizeof(path) - 1 : len, p);
340 p = path;
Courtney Goeltzenleuchter4af9bd12014-08-01 14:18:11 -0600341 next++;
342 }
Chia-I Wu5f72d0f2014-08-01 11:21:23 +0800343
Courtney Goeltzenleuchter4af9bd12014-08-01 14:18:11 -0600344 sysdir = opendir(p);
345 if (sysdir) {
346 dent = readdir(sysdir);
347 while (dent) {
348 /* look for ICDs starting with "libXGL_" */
349 if (!strncmp(dent->d_name, "libXGL_", 7)) {
Courtney Goeltzenleuchter4af9bd12014-08-01 14:18:11 -0600350 snprintf(icd_library, 1024, "%s/%s",p,dent->d_name);
Chia-I Wu894a1172014-08-04 11:18:20 +0800351 loader_icd_add(icd_library);
Courtney Goeltzenleuchter4af9bd12014-08-01 14:18:11 -0600352 }
353
354 dent = readdir(sysdir);
355 }
356 closedir(sysdir);
357 }
Chia-I Wu5f72d0f2014-08-01 11:21:23 +0800358 }
359
Chia-I Wu5f72d0f2014-08-01 11:21:23 +0800360
361 loader.scanned = true;
362}
363
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600364#ifndef DEFAULT_XGL_LAYERS_PATH
Courtney Goeltzenleuchterbce445a2014-12-01 09:29:42 -0700365// TODO: Are these good default locations?
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600366#define DEFAULT_XGL_LAYERS_PATH ".:/usr/lib/i386-linux-gnu/xgl:/usr/lib/x86_64-linux-gnu/xgl"
367#endif
368
Courtney Goeltzenleuchterbce445a2014-12-01 09:29:42 -0700369static void layer_lib_scan(const char * libInPaths)
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600370{
371 const char *p, *next;
Courtney Goeltzenleuchterbce445a2014-12-01 09:29:42 -0700372 char *libPaths;
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600373 DIR *curdir;
374 struct dirent *dent;
Jon Ashburn183dfd02014-10-22 18:13:16 -0600375 int len, i;
376 char temp_str[1024];
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600377
Courtney Goeltzenleuchterbce445a2014-12-01 09:29:42 -0700378 len = 0;
379 loader.layer_dirs = NULL;
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600380 if (libInPaths){
Courtney Goeltzenleuchterbce445a2014-12-01 09:29:42 -0700381 len = strlen(libInPaths);
382 p = libInPaths;
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600383 }
384 else {
Courtney Goeltzenleuchterbce445a2014-12-01 09:29:42 -0700385 if (geteuid() == getuid()) {
386 p = getenv("LIBXGL_LAYERS_PATH");
387 if (p != NULL)
388 len = strlen(p);
389 }
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600390 }
391
Courtney Goeltzenleuchterbce445a2014-12-01 09:29:42 -0700392 if (len == 0) {
393 len = strlen(DEFAULT_XGL_LAYERS_PATH);
394 p = DEFAULT_XGL_LAYERS_PATH;
395 }
396
397 if (len == 0) {
398 // Have no paths to search
399 return;
400 }
401 loader.layer_dirs = malloc(len+1);
Courtney Goeltzenleuchter688c74b2014-12-02 18:12:51 -0700402 if (loader.layer_dirs == NULL)
403 return;
404
405 // Alloc passed, so we know there is enough space to hold the string, don't need strncpy
406 strcpy(loader.layer_dirs, p);
Courtney Goeltzenleuchterbce445a2014-12-01 09:29:42 -0700407 libPaths = loader.layer_dirs;
408
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600409 /* cleanup any previously scanned libraries */
Jon Ashburn183dfd02014-10-22 18:13:16 -0600410 for (i = 0; i < loader.scanned_layer_count; i++) {
411 if (loader.scanned_layer_names[i] != NULL)
412 free(loader.scanned_layer_names[i]);
413 loader.scanned_layer_names[i] = NULL;
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600414 }
Jon Ashburn183dfd02014-10-22 18:13:16 -0600415 loader.scanned_layer_count = 0;
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600416
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600417 for (p = libPaths; *p; p = next) {
418 next = strchr(p, ':');
419 if (next == NULL) {
420 len = strlen(p);
421 next = p + len;
422 }
423 else {
424 len = next - p;
425 *(char *) next = '\0';
426 next++;
427 }
428
429 curdir = opendir(p);
430 if (curdir) {
431 dent = readdir(curdir);
432 while (dent) {
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600433 /* look for wrappers starting with "libXGLlayer" */
434 if (!strncmp(dent->d_name, "libXGLLayer", strlen("libXGLLayer"))) {
Jon Ashburn183dfd02014-10-22 18:13:16 -0600435 void * handle;
436 snprintf(temp_str, sizeof(temp_str), "%s/%s",p,dent->d_name);
437 if ((handle = dlopen((const char *) temp_str, RTLD_LAZY)) == NULL)
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600438 continue;
Jon Ashburn183dfd02014-10-22 18:13:16 -0600439 if (loader.scanned_layer_count == MAX_LAYER_LIBRARIES) {
440 loader_log(XGL_DBG_MSG_ERROR, 0, "%s ignored: max layer libraries exceed", temp_str);
441 break;
442 }
443 if ((loader.scanned_layer_names[loader.scanned_layer_count] = malloc(strlen(temp_str) + 1)) == NULL) {
444 loader_log(XGL_DBG_MSG_ERROR, 0, "%s ignored: out of memory", temp_str);
445 break;
446 }
447 strcpy(loader.scanned_layer_names[loader.scanned_layer_count], temp_str);
448 loader.scanned_layer_count++;
449 dlclose(handle);
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600450 }
451
452 dent = readdir(curdir);
453 }
454 closedir(curdir);
455 }
456 }
457
Jon Ashburn183dfd02014-10-22 18:13:16 -0600458 loader.layer_scanned = true;
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600459}
460
Jon Ashburnb55278a2014-10-17 15:09:07 -0600461static void loader_init_dispatch_table(XGL_LAYER_DISPATCH_TABLE *tab, GetProcAddrType fpGPA, XGL_PHYSICAL_GPU gpu)
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600462{
463 tab->GetProcAddr = fpGPA;
464 tab->InitAndEnumerateGpus = fpGPA(gpu, (const XGL_CHAR *) "xglInitAndEnumerateGpus");
465 tab->GetGpuInfo = fpGPA(gpu, (const XGL_CHAR *) "xglGetGpuInfo");
466 tab->CreateDevice = fpGPA(gpu, (const XGL_CHAR *) "xglCreateDevice");
467 tab->DestroyDevice = fpGPA(gpu, (const XGL_CHAR *) "xglDestroyDevice");
468 tab->GetExtensionSupport = fpGPA(gpu, (const XGL_CHAR *) "xglGetExtensionSupport");
Jon Ashburn96f28fc2014-10-15 15:30:23 -0600469 tab->EnumerateLayers = fpGPA(gpu, (const XGL_CHAR *) "xglEnumerateLayers");
470 if (tab->EnumerateLayers == NULL)
471 tab->EnumerateLayers = xglEnumerateLayers;
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600472 tab->GetDeviceQueue = fpGPA(gpu, (const XGL_CHAR *) "xglGetDeviceQueue");
473 tab->QueueSubmit = fpGPA(gpu, (const XGL_CHAR *) "xglQueueSubmit");
474 tab->QueueSetGlobalMemReferences = fpGPA(gpu, (const XGL_CHAR *) "xglQueueSetGlobalMemReferences");
475 tab->QueueWaitIdle = fpGPA(gpu, (const XGL_CHAR *) "xglQueueWaitIdle");
476 tab->DeviceWaitIdle = fpGPA(gpu, (const XGL_CHAR *) "xglDeviceWaitIdle");
477 tab->GetMemoryHeapCount = fpGPA(gpu, (const XGL_CHAR *) "xglGetMemoryHeapCount");
478 tab->GetMemoryHeapInfo = fpGPA(gpu, (const XGL_CHAR *) "xglGetMemoryHeapInfo");
479 tab->AllocMemory = fpGPA(gpu, (const XGL_CHAR *) "xglAllocMemory");
480 tab->FreeMemory = fpGPA(gpu, (const XGL_CHAR *) "xglFreeMemory");
481 tab->SetMemoryPriority = fpGPA(gpu, (const XGL_CHAR *) "xglSetMemoryPriority");
482 tab->MapMemory = fpGPA(gpu, (const XGL_CHAR *) "xglMapMemory");
483 tab->UnmapMemory = fpGPA(gpu, (const XGL_CHAR *) "xglUnmapMemory");
484 tab->PinSystemMemory = fpGPA(gpu, (const XGL_CHAR *) "xglPinSystemMemory");
485 tab->RemapVirtualMemoryPages = fpGPA(gpu, (const XGL_CHAR *) "xglRemapVirtualMemoryPages");
486 tab->GetMultiGpuCompatibility = fpGPA(gpu, (const XGL_CHAR *) "xglGetMultiGpuCompatibility");
487 tab->OpenSharedMemory = fpGPA(gpu, (const XGL_CHAR *) "xglOpenSharedMemory");
488 tab->OpenSharedQueueSemaphore = fpGPA(gpu, (const XGL_CHAR *) "xglOpenSharedQueueSemaphore");
489 tab->OpenPeerMemory = fpGPA(gpu, (const XGL_CHAR *) "xglOpenPeerMemory");
490 tab->OpenPeerImage = fpGPA(gpu, (const XGL_CHAR *) "xglOpenPeerImage");
491 tab->DestroyObject = fpGPA(gpu, (const XGL_CHAR *) "xglDestroyObject");
492 tab->GetObjectInfo = fpGPA(gpu, (const XGL_CHAR *) "xglGetObjectInfo");
493 tab->BindObjectMemory = fpGPA(gpu, (const XGL_CHAR *) "xglBindObjectMemory");
494 tab->CreateFence = fpGPA(gpu, (const XGL_CHAR *) "xglCreateFence");
495 tab->GetFenceStatus = fpGPA(gpu, (const XGL_CHAR *) "xglGetFenceStatus");
496 tab->WaitForFences = fpGPA(gpu, (const XGL_CHAR *) "xglWaitForFences");
497 tab->CreateQueueSemaphore = fpGPA(gpu, (const XGL_CHAR *) "xglCreateQueueSemaphore");
498 tab->SignalQueueSemaphore = fpGPA(gpu, (const XGL_CHAR *) "xglSignalQueueSemaphore");
499 tab->WaitQueueSemaphore = fpGPA(gpu, (const XGL_CHAR *) "xglWaitQueueSemaphore");
500 tab->CreateEvent = fpGPA(gpu, (const XGL_CHAR *) "xglCreateEvent");
501 tab->GetEventStatus = fpGPA(gpu, (const XGL_CHAR *) "xglGetEventStatus");
502 tab->SetEvent = fpGPA(gpu, (const XGL_CHAR *) "xglSetEvent");
503 tab->ResetEvent = fpGPA(gpu, (const XGL_CHAR *) "xglResetEvent");
504 tab->CreateQueryPool = fpGPA(gpu, (const XGL_CHAR *) "xglCreateQueryPool");
505 tab->GetQueryPoolResults = fpGPA(gpu, (const XGL_CHAR *) "xglGetQueryPoolResults");
506 tab->GetFormatInfo = fpGPA(gpu, (const XGL_CHAR *) "xglGetFormatInfo");
507 tab->CreateImage = fpGPA(gpu, (const XGL_CHAR *) "xglCreateImage");
508 tab->GetImageSubresourceInfo = fpGPA(gpu, (const XGL_CHAR *) "xglGetImageSubresourceInfo");
509 tab->CreateImageView = fpGPA(gpu, (const XGL_CHAR *) "xglCreateImageView");
510 tab->CreateColorAttachmentView = fpGPA(gpu, (const XGL_CHAR *) "xglCreateColorAttachmentView");
511 tab->CreateDepthStencilView = fpGPA(gpu, (const XGL_CHAR *) "xglCreateDepthStencilView");
512 tab->CreateShader = fpGPA(gpu, (const XGL_CHAR *) "xglCreateShader");
513 tab->CreateGraphicsPipeline = fpGPA(gpu, (const XGL_CHAR *) "xglCreateGraphicsPipeline");
514 tab->CreateComputePipeline = fpGPA(gpu, (const XGL_CHAR *) "xglCreateComputePipeline");
515 tab->StorePipeline = fpGPA(gpu, (const XGL_CHAR *) "xglStorePipeline");
516 tab->LoadPipeline = fpGPA(gpu, (const XGL_CHAR *) "xglLoadPipeline");
517 tab->CreatePipelineDelta = fpGPA(gpu, (const XGL_CHAR *) "xglCreatePipelineDelta");
518 tab->CreateSampler = fpGPA(gpu, (const XGL_CHAR *) "xglCreateSampler");
519 tab->CreateDescriptorSet = fpGPA(gpu, (const XGL_CHAR *) "xglCreateDescriptorSet");
520 tab->BeginDescriptorSetUpdate = fpGPA(gpu, (const XGL_CHAR *) "xglBeginDescriptorSetUpdate");
521 tab->EndDescriptorSetUpdate = fpGPA(gpu, (const XGL_CHAR *) "xglEndDescriptorSetUpdate");
522 tab->AttachSamplerDescriptors = fpGPA(gpu, (const XGL_CHAR *) "xglAttachSamplerDescriptors");
523 tab->AttachImageViewDescriptors = fpGPA(gpu, (const XGL_CHAR *) "xglAttachImageViewDescriptors");
524 tab->AttachMemoryViewDescriptors = fpGPA(gpu, (const XGL_CHAR *) "xglAttachMemoryViewDescriptors");
525 tab->AttachNestedDescriptors = fpGPA(gpu, (const XGL_CHAR *) "xglAttachNestedDescriptors");
526 tab->ClearDescriptorSetSlots = fpGPA(gpu, (const XGL_CHAR *) "xglClearDescriptorSetSlots");
527 tab->CreateViewportState = fpGPA(gpu, (const XGL_CHAR *) "xglCreateViewportState");
528 tab->CreateRasterState = fpGPA(gpu, (const XGL_CHAR *) "xglCreateRasterState");
529 tab->CreateMsaaState = fpGPA(gpu, (const XGL_CHAR *) "xglCreateMsaaState");
530 tab->CreateColorBlendState = fpGPA(gpu, (const XGL_CHAR *) "xglCreateColorBlendState");
531 tab->CreateDepthStencilState = fpGPA(gpu, (const XGL_CHAR *) "xglCreateDepthStencilState");
532 tab->CreateCommandBuffer = fpGPA(gpu, (const XGL_CHAR *) "xglCreateCommandBuffer");
533 tab->BeginCommandBuffer = fpGPA(gpu, (const XGL_CHAR *) "xglBeginCommandBuffer");
534 tab->EndCommandBuffer = fpGPA(gpu, (const XGL_CHAR *) "xglEndCommandBuffer");
535 tab->ResetCommandBuffer = fpGPA(gpu, (const XGL_CHAR *) "xglResetCommandBuffer");
536 tab->CmdBindPipeline = fpGPA(gpu, (const XGL_CHAR *) "xglCmdBindPipeline");
537 tab->CmdBindPipelineDelta = fpGPA(gpu, (const XGL_CHAR *) "xglCmdBindPipelineDelta");
538 tab->CmdBindStateObject = fpGPA(gpu, (const XGL_CHAR *) "xglCmdBindStateObject");
539 tab->CmdBindDescriptorSet = fpGPA(gpu, (const XGL_CHAR *) "xglCmdBindDescriptorSet");
540 tab->CmdBindDynamicMemoryView = fpGPA(gpu, (const XGL_CHAR *) "xglCmdBindDynamicMemoryView");
Chia-I Wu3b04af52014-11-08 10:48:20 +0800541 tab->CmdBindVertexData = fpGPA(gpu, (const XGL_CHAR *) "xglCmdBindVertexData");
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600542 tab->CmdBindIndexData = fpGPA(gpu, (const XGL_CHAR *) "xglCmdBindIndexData");
543 tab->CmdBindAttachments = fpGPA(gpu, (const XGL_CHAR *) "xglCmdBindAttachments");
544 tab->CmdPrepareMemoryRegions = fpGPA(gpu, (const XGL_CHAR *) "xglCmdPrepareMemoryRegions");
545 tab->CmdPrepareImages = fpGPA(gpu, (const XGL_CHAR *) "xglCmdPrepareImages");
546 tab->CmdDraw = fpGPA(gpu, (const XGL_CHAR *) "xglCmdDraw");
547 tab->CmdDrawIndexed = fpGPA(gpu, (const XGL_CHAR *) "xglCmdDrawIndexed");
548 tab->CmdDrawIndirect = fpGPA(gpu, (const XGL_CHAR *) "xglCmdDrawIndirect");
549 tab->CmdDrawIndexedIndirect = fpGPA(gpu, (const XGL_CHAR *) "xglCmdDrawIndexedIndirect");
550 tab->CmdDispatch = fpGPA(gpu, (const XGL_CHAR *) "xglCmdDispatch");
551 tab->CmdDispatchIndirect = fpGPA(gpu, (const XGL_CHAR *) "xglCmdDispatchIndirect");
552 tab->CmdCopyMemory = fpGPA(gpu, (const XGL_CHAR *) "xglCmdCopyMemory");
553 tab->CmdCopyImage = fpGPA(gpu, (const XGL_CHAR *) "xglCmdCopyImage");
554 tab->CmdCopyMemoryToImage = fpGPA(gpu, (const XGL_CHAR *) "xglCmdCopyMemoryToImage");
555 tab->CmdCopyImageToMemory = fpGPA(gpu, (const XGL_CHAR *) "xglCmdCopyImageToMemory");
556 tab->CmdCloneImageData = fpGPA(gpu, (const XGL_CHAR *) "xglCmdCloneImageData");
557 tab->CmdUpdateMemory = fpGPA(gpu, (const XGL_CHAR *) "xglCmdUpdateMemory");
558 tab->CmdFillMemory = fpGPA(gpu, (const XGL_CHAR *) "xglCmdFillMemory");
559 tab->CmdClearColorImage = fpGPA(gpu, (const XGL_CHAR *) "xglCmdClearColorImage");
560 tab->CmdClearColorImageRaw = fpGPA(gpu, (const XGL_CHAR *) "xglCmdClearColorImageRaw");
561 tab->CmdClearDepthStencil = fpGPA(gpu, (const XGL_CHAR *) "xglCmdClearDepthStencil");
562 tab->CmdResolveImage = fpGPA(gpu, (const XGL_CHAR *) "xglCmdResolveImage");
563 tab->CmdSetEvent = fpGPA(gpu, (const XGL_CHAR *) "xglCmdSetEvent");
564 tab->CmdResetEvent = fpGPA(gpu, (const XGL_CHAR *) "xglCmdResetEvent");
565 tab->CmdMemoryAtomic = fpGPA(gpu, (const XGL_CHAR *) "xglCmdMemoryAtomic");
566 tab->CmdBeginQuery = fpGPA(gpu, (const XGL_CHAR *) "xglCmdBeginQuery");
567 tab->CmdEndQuery = fpGPA(gpu, (const XGL_CHAR *) "xglCmdEndQuery");
568 tab->CmdResetQueryPool = fpGPA(gpu, (const XGL_CHAR *) "xglCmdResetQueryPool");
569 tab->CmdWriteTimestamp = fpGPA(gpu, (const XGL_CHAR *) "xglCmdWriteTimestamp");
570 tab->CmdInitAtomicCounters = fpGPA(gpu, (const XGL_CHAR *) "xglCmdInitAtomicCounters");
571 tab->CmdLoadAtomicCounters = fpGPA(gpu, (const XGL_CHAR *) "xglCmdLoadAtomicCounters");
572 tab->CmdSaveAtomicCounters = fpGPA(gpu, (const XGL_CHAR *) "xglCmdSaveAtomicCounters");
573 tab->DbgSetValidationLevel = fpGPA(gpu, (const XGL_CHAR *) "xglDbgSetValidationLevel");
574 tab->DbgRegisterMsgCallback = fpGPA(gpu, (const XGL_CHAR *) "xglDbgRegisterMsgCallback");
575 tab->DbgUnregisterMsgCallback = fpGPA(gpu, (const XGL_CHAR *) "xglDbgUnregisterMsgCallback");
576 tab->DbgSetMessageFilter = fpGPA(gpu, (const XGL_CHAR *) "xglDbgSetMessageFilter");
577 tab->DbgSetObjectTag = fpGPA(gpu, (const XGL_CHAR *) "xglDbgSetObjectTag");
578 tab->DbgSetGlobalOption = fpGPA(gpu, (const XGL_CHAR *) "xglDbgSetGlobalOption");
579 tab->DbgSetDeviceOption = fpGPA(gpu, (const XGL_CHAR *) "xglDbgSetDeviceOption");
580 tab->CmdDbgMarkerBegin = fpGPA(gpu, (const XGL_CHAR *) "xglCmdDbgMarkerBegin");
581 tab->CmdDbgMarkerEnd = fpGPA(gpu, (const XGL_CHAR *) "xglCmdDbgMarkerEnd");
582 tab->WsiX11AssociateConnection = fpGPA(gpu, (const XGL_CHAR *) "xglWsiX11AssociateConnection");
583 tab->WsiX11GetMSC = fpGPA(gpu, (const XGL_CHAR *) "xglWsiX11GetMSC");
584 tab->WsiX11CreatePresentableImage = fpGPA(gpu, (const XGL_CHAR *) "xglWsiX11CreatePresentableImage");
585 tab->WsiX11QueuePresent = fpGPA(gpu, (const XGL_CHAR *) "xglWsiX11QueuePresent");
586}
587
Jon Ashburnb55278a2014-10-17 15:09:07 -0600588static struct loader_icd * loader_get_icd(const XGL_BASE_LAYER_OBJECT *gpu, XGL_UINT *gpu_index)
589{
590 for (struct loader_icd * icd = loader.icds; icd; icd = icd->next) {
591 for (XGL_UINT i = 0; i < icd->gpu_count; i++)
Jon Ashburn183dfd02014-10-22 18:13:16 -0600592 if ((icd->gpus + i) == gpu || (icd->gpus +i)->baseObject == gpu->baseObject) {
Jon Ashburnb55278a2014-10-17 15:09:07 -0600593 *gpu_index = i;
594 return icd;
595 }
596 }
597 return NULL;
598}
599
Jon Ashburn183dfd02014-10-22 18:13:16 -0600600static bool loader_layers_activated(const struct loader_icd *icd, const XGL_UINT gpu_index)
Jon Ashburnb55278a2014-10-17 15:09:07 -0600601{
Jon Ashburn183dfd02014-10-22 18:13:16 -0600602 if (icd->layer_count[gpu_index])
603 return true;
604 else
605 return false;
Jon Ashburnb55278a2014-10-17 15:09:07 -0600606}
607
Jon Ashburnead95c52014-11-18 09:06:04 -0700608static void loader_init_layer_libs(struct loader_icd *icd, XGL_UINT gpu_index, struct layer_name_pair * pLayerNames, XGL_UINT count)
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600609{
Jon Ashburn183dfd02014-10-22 18:13:16 -0600610 if (!icd)
611 return;
Jon Ashburn815bddd2014-10-16 15:48:50 -0600612
Jon Ashburn183dfd02014-10-22 18:13:16 -0600613 struct loader_layers *obj;
614 bool foundLib;
615 for (XGL_UINT i = 0; i < count; i++) {
616 foundLib = false;
617 for (XGL_UINT j = 0; j < icd->layer_count[gpu_index]; j++) {
Jon Ashburnead95c52014-11-18 09:06:04 -0700618 if (icd->layer_libs[gpu_index][j].lib_handle && !strcmp(icd->layer_libs[gpu_index][j].name, (char *) pLayerNames[i].layer_name)) {
Jon Ashburn183dfd02014-10-22 18:13:16 -0600619 foundLib = true;
620 break;
621 }
622 }
623 if (!foundLib) {
624 obj = &(icd->layer_libs[gpu_index][i]);
Jon Ashburnead95c52014-11-18 09:06:04 -0700625 strncpy(obj->name, (char *) pLayerNames[i].layer_name, sizeof(obj->name) - 1);
626 obj->name[sizeof(obj->name) - 1] = '\0';
627 if ((obj->lib_handle = dlopen(pLayerNames[i].lib_name, RTLD_LAZY | RTLD_DEEPBIND)) == NULL) {
628 loader_log(XGL_DBG_MSG_ERROR, 0, "Failed to open layer library %s got error %d", pLayerNames[i].lib_name, dlerror());
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600629 continue;
630 } else {
Jon Ashburnead95c52014-11-18 09:06:04 -0700631 loader_log(XGL_DBG_MSG_UNKNOWN, 0, "Inserting layer %s from library %s", pLayerNames[i].layer_name, pLayerNames[i].lib_name);
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600632 }
Jon Ashburnead95c52014-11-18 09:06:04 -0700633 free(pLayerNames[i].layer_name);
Jon Ashburn183dfd02014-10-22 18:13:16 -0600634 icd->layer_count[gpu_index]++;
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600635 }
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600636 }
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600637}
638
Jon Ashburnead95c52014-11-18 09:06:04 -0700639static bool find_layer_name(struct loader_icd *icd, XGL_UINT gpu_index, const char * layer_name, const char **lib_name)
640{
641 void *handle;
642 EnumerateLayersType fpEnumerateLayers;
643 XGL_CHAR layer_buf[16][256];
644 XGL_CHAR * layers[16];
645
646 for (int i = 0; i < 16; i++)
647 layers[i] = &layer_buf[i][0];
648
649 for (unsigned int j = 0; j < loader.scanned_layer_count; j++) {
650 *lib_name = loader.scanned_layer_names[j];
651 if ((handle = dlopen(*lib_name, RTLD_LAZY)) == NULL)
652 continue;
653 if ((fpEnumerateLayers = dlsym(handle, "xglEnumerateLayers")) == NULL) {
654 //use default layer name based on library name libXGLLayer<name>.so
655 char * lib_str = malloc(strlen(*lib_name) + 1 + strlen(layer_name));
656 snprintf(lib_str, strlen(*lib_name) + strlen(layer_name), "libXGLLayer%s.so", layer_name);
657 dlclose(handle);
658 if (!strcmp(basename(*lib_name), lib_str)) {
659 free(lib_str);
660 return true;
661 }
662 else {
663 free(lib_str);
664 continue;
665 }
666 }
667 else {
668 XGL_SIZE cnt;
Jon Ashburn6847c2b2014-11-25 12:56:49 -0700669 fpEnumerateLayers(NULL, 16, 256, layers, &cnt, (XGL_VOID *) icd->gpus + gpu_index);
Jon Ashburnead95c52014-11-18 09:06:04 -0700670 for (unsigned int i = 0; i < cnt; i++) {
671 if (!strcmp((char *) layers[i], layer_name)) {
672 dlclose(handle);
673 return true;
674 }
675 }
676 }
677
678 dlclose(handle);
679 }
680
681 return false;
682}
683
684static XGL_UINT loader_get_layer_env(struct loader_icd *icd, XGL_UINT gpu_index, struct layer_name_pair *pLayerNames)
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600685{
Jon Ashburn183dfd02014-10-22 18:13:16 -0600686 const char *layerEnv;
687 XGL_UINT len, count = 0;
Jon Ashburnb4d00532014-10-22 21:15:26 -0600688 char *p, *pOrig, *next, *name;
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600689
Jon Ashburnead95c52014-11-18 09:06:04 -0700690 layerEnv = getenv("LIBXGL_LAYER_NAMES");
Jon Ashburn4fbcb032014-10-23 10:29:09 -0600691 if (!layerEnv)
692 return 0;
Jon Ashburn183dfd02014-10-22 18:13:16 -0600693 p = malloc(strlen(layerEnv) + 1);
694 if (!p)
695 return 0;
696 strcpy(p, layerEnv);
Jon Ashburnb4d00532014-10-22 21:15:26 -0600697 pOrig = p;
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600698
Jon Ashburn183dfd02014-10-22 18:13:16 -0600699 while (p && *p && count < MAX_LAYER_LIBRARIES) {
Jon Ashburnead95c52014-11-18 09:06:04 -0700700 const char *lib_name = NULL;
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600701 next = strchr(p, ':');
702 if (next == NULL) {
703 len = strlen(p);
704 next = p + len;
705 }
706 else {
707 len = next - p;
708 *(char *) next = '\0';
709 next++;
710 }
Jon Ashburn183dfd02014-10-22 18:13:16 -0600711 name = basename(p);
Jon Ashburnead95c52014-11-18 09:06:04 -0700712 if (!find_layer_name(icd, gpu_index, name, &lib_name)) {
Jon Ashburn183dfd02014-10-22 18:13:16 -0600713 p = next;
714 continue;
715 }
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600716
Jon Ashburnead95c52014-11-18 09:06:04 -0700717 len = strlen(name);
718 pLayerNames[count].layer_name = malloc(len + 1);
719 if (!pLayerNames[count].layer_name) {
Jon Ashburnb4d00532014-10-22 21:15:26 -0600720 free(pOrig);
Jon Ashburn183dfd02014-10-22 18:13:16 -0600721 return count;
Jon Ashburnb4d00532014-10-22 21:15:26 -0600722 }
Jon Ashburnead95c52014-11-18 09:06:04 -0700723 strncpy((char *) pLayerNames[count].layer_name, name, len);
724 pLayerNames[count].layer_name[len] = '\0';
725 pLayerNames[count].lib_name = lib_name;
Jon Ashburn183dfd02014-10-22 18:13:16 -0600726 count++;
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600727 p = next;
728
Jon Ashburn183dfd02014-10-22 18:13:16 -0600729 };
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600730
Jon Ashburnb4d00532014-10-22 21:15:26 -0600731 free(pOrig);
Jon Ashburn183dfd02014-10-22 18:13:16 -0600732 return count;
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600733}
734
Jon Ashburnead95c52014-11-18 09:06:04 -0700735static XGL_UINT loader_get_layer_libs(struct loader_icd *icd, XGL_UINT gpu_index, const XGL_DEVICE_CREATE_INFO* pCreateInfo, struct layer_name_pair **ppLayerNames)
Jon Ashburn183dfd02014-10-22 18:13:16 -0600736{
Jon Ashburnead95c52014-11-18 09:06:04 -0700737 static struct layer_name_pair layerNames[MAX_LAYER_LIBRARIES];
Jon Ashburn183dfd02014-10-22 18:13:16 -0600738
739 *ppLayerNames = &layerNames[0];
740 if (!pCreateInfo) {
Jon Ashburnead95c52014-11-18 09:06:04 -0700741 return loader_get_layer_env(icd, gpu_index, layerNames);
Jon Ashburn183dfd02014-10-22 18:13:16 -0600742 }
743
744 XGL_LAYER_CREATE_INFO *pCi = (XGL_LAYER_CREATE_INFO *) pCreateInfo->pNext;
745
746 while (pCi) {
747 if (pCi->sType == XGL_STRUCTURE_TYPE_LAYER_CREATE_INFO) {
748 const char *name;
749 XGL_UINT len;
Jon Ashburn183dfd02014-10-22 18:13:16 -0600750 for (XGL_UINT i = 0; i < pCi->layerCount; i++) {
Jon Ashburnead95c52014-11-18 09:06:04 -0700751 const char * lib_name = NULL;
Jon Ashburn183dfd02014-10-22 18:13:16 -0600752 name = (const char *) *(pCi->ppActiveLayerNames + i);
Jon Ashburnead95c52014-11-18 09:06:04 -0700753 if (!find_layer_name(icd, gpu_index, name, &lib_name))
754 return loader_get_layer_env(icd, gpu_index, layerNames);
755 len = strlen(name);
756 layerNames[i].layer_name = malloc(len + 1);
757 if (!layerNames[i].layer_name)
Jon Ashburn183dfd02014-10-22 18:13:16 -0600758 return i;
Jon Ashburnead95c52014-11-18 09:06:04 -0700759 strncpy((char *) layerNames[i].layer_name, name, len);
760 layerNames[i].layer_name[len] = '\0';
761 layerNames[i].lib_name = lib_name;
Jon Ashburn183dfd02014-10-22 18:13:16 -0600762 }
763 return pCi->layerCount;
764 }
765 pCi = pCi->pNext;
766 }
Jon Ashburnead95c52014-11-18 09:06:04 -0700767 return loader_get_layer_env(icd, gpu_index, layerNames);
Jon Ashburn183dfd02014-10-22 18:13:16 -0600768}
769
770static void loader_deactivate_layer()
771{
772 struct loader_icd *icd;
773 struct loader_layers *libs;
774
775 for (icd = loader.icds; icd; icd = icd->next) {
Jon Ashburn183dfd02014-10-22 18:13:16 -0600776 if (icd->gpus)
777 free(icd->gpus);
778 icd->gpus = NULL;
779 if (icd->loader_dispatch)
780 free(icd->loader_dispatch);
781 icd->loader_dispatch = NULL;
Jon Ashburn183dfd02014-10-22 18:13:16 -0600782 for (XGL_UINT j = 0; j < icd->gpu_count; j++) {
783 if (icd->layer_count[j] > 0) {
784 for (XGL_UINT i = 0; i < icd->layer_count[j]; i++) {
785 libs = &(icd->layer_libs[j][i]);
786 if (libs->lib_handle)
787 dlclose(libs->lib_handle);
788 libs->lib_handle = NULL;
789 }
Jon Ashburnb4d00532014-10-22 21:15:26 -0600790 if (icd->wrappedGpus[j])
791 free(icd->wrappedGpus[j]);
Jon Ashburn183dfd02014-10-22 18:13:16 -0600792 }
793 icd->layer_count[j] = 0;
794 }
795 icd->gpu_count = 0;
796 }
797}
798
Jon Ashburn10053332014-11-17 10:17:37 -0700799extern XGL_UINT loader_activate_layers(XGL_PHYSICAL_GPU gpu, const XGL_DEVICE_CREATE_INFO* pCreateInfo)
Jon Ashburn183dfd02014-10-22 18:13:16 -0600800{
801 XGL_UINT gpu_index;
802 XGL_UINT count;
Jon Ashburnead95c52014-11-18 09:06:04 -0700803 struct layer_name_pair *pLayerNames;
Jon Ashburn3e7c0802014-10-24 15:48:55 -0600804 struct loader_icd *icd = loader_get_icd((const XGL_BASE_LAYER_OBJECT *) gpu, &gpu_index);
Jon Ashburn183dfd02014-10-22 18:13:16 -0600805
806 if (!icd)
807 return 0;
808 assert(gpu_index < XGL_MAX_PHYSICAL_GPUS);
809
810 /* activate any layer libraries */
811 if (!loader_layers_activated(icd, gpu_index)) {
Jon Ashburn3e7c0802014-10-24 15:48:55 -0600812 XGL_BASE_LAYER_OBJECT *gpuObj = (XGL_BASE_LAYER_OBJECT *) gpu;
813 XGL_BASE_LAYER_OBJECT *nextGpuObj, *baseObj = gpuObj->baseObject;
Jon Ashburn183dfd02014-10-22 18:13:16 -0600814 GetProcAddrType nextGPA = xglGetProcAddr;
815
Jon Ashburnead95c52014-11-18 09:06:04 -0700816 count = loader_get_layer_libs(icd, gpu_index, pCreateInfo, &pLayerNames);
Jon Ashburn183dfd02014-10-22 18:13:16 -0600817 if (!count)
818 return 0;
Jon Ashburnead95c52014-11-18 09:06:04 -0700819 loader_init_layer_libs(icd, gpu_index, pLayerNames, count);
Jon Ashburn183dfd02014-10-22 18:13:16 -0600820
Jon Ashburnb4d00532014-10-22 21:15:26 -0600821 icd->wrappedGpus[gpu_index] = malloc(sizeof(XGL_BASE_LAYER_OBJECT) * icd->layer_count[gpu_index]);
822 if (! icd->wrappedGpus[gpu_index])
823 loader_log(XGL_DBG_MSG_ERROR, 0, "Failed to malloc Gpu objects for layer");
Jon Ashburn183dfd02014-10-22 18:13:16 -0600824 for (XGL_INT i = icd->layer_count[gpu_index] - 1; i >= 0; i--) {
Jon Ashburnb4d00532014-10-22 21:15:26 -0600825 nextGpuObj = (icd->wrappedGpus[gpu_index] + i);
Jon Ashburn183dfd02014-10-22 18:13:16 -0600826 nextGpuObj->pGPA = nextGPA;
Jon Ashburn3e7c0802014-10-24 15:48:55 -0600827 nextGpuObj->baseObject = baseObj;
Jon Ashburn183dfd02014-10-22 18:13:16 -0600828 nextGpuObj->nextObject = gpuObj;
829 gpuObj = nextGpuObj;
830
Jon Ashburn8d8dad02014-12-01 14:22:40 -0700831 char funcStr[256];
832 snprintf(funcStr, 256, "%sGetProcAddr",icd->layer_libs[gpu_index][i].name);
833 if ((nextGPA = dlsym(icd->layer_libs[gpu_index][i].lib_handle, funcStr)) == NULL)
834 nextGPA = dlsym(icd->layer_libs[gpu_index][i].lib_handle, "xglGetProcAddr");
Jon Ashburn183dfd02014-10-22 18:13:16 -0600835 if (!nextGPA) {
Jon Ashburnead95c52014-11-18 09:06:04 -0700836 loader_log(XGL_DBG_MSG_ERROR, 0, "Failed to find xglGetProcAddr in layer %s", icd->layer_libs[gpu_index][i].name);
Jon Ashburn183dfd02014-10-22 18:13:16 -0600837 continue;
838 }
839
Jon Ashburn3e7c0802014-10-24 15:48:55 -0600840 if (i == 0) {
Jon Ashburn183dfd02014-10-22 18:13:16 -0600841 loader_init_dispatch_table(icd->loader_dispatch + gpu_index, nextGPA, gpuObj);
Jon Ashburn3e7c0802014-10-24 15:48:55 -0600842 //Insert the new wrapped objects into the list with loader object at head
843 ((XGL_BASE_LAYER_OBJECT *) gpu)->nextObject = gpuObj;
844 ((XGL_BASE_LAYER_OBJECT *) gpu)->pGPA = nextGPA;
845 gpuObj = icd->wrappedGpus[gpu_index] + icd->layer_count[gpu_index] - 1;
846 gpuObj->nextObject = baseObj;
847 gpuObj->pGPA = icd->GetProcAddr;
848 }
Jon Ashburn183dfd02014-10-22 18:13:16 -0600849
850 }
Jon Ashburn183dfd02014-10-22 18:13:16 -0600851 }
852 else {
853 //make sure requested Layers matches currently activated Layers
Jon Ashburnead95c52014-11-18 09:06:04 -0700854 count = loader_get_layer_libs(icd, gpu_index, pCreateInfo, &pLayerNames);
Jon Ashburn183dfd02014-10-22 18:13:16 -0600855 for (XGL_UINT i = 0; i < count; i++) {
Jon Ashburnead95c52014-11-18 09:06:04 -0700856 if (strcmp(icd->layer_libs[gpu_index][i].name, pLayerNames[i].layer_name)) {
Jon Ashburn183dfd02014-10-22 18:13:16 -0600857 loader_log(XGL_DBG_MSG_ERROR, 0, "Layers activated != Layers requested");
858 break;
859 }
860 }
861 if (count != icd->layer_count[gpu_index]) {
Jon Ashburnead95c52014-11-18 09:06:04 -0700862 loader_log(XGL_DBG_MSG_ERROR, 0, "Number of Layers activated != number requested");
Jon Ashburn183dfd02014-10-22 18:13:16 -0600863 }
864 }
865 return icd->layer_count[gpu_index];
866}
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600867
Jon Ashburn21734942014-10-17 15:31:22 -0600868LOADER_EXPORT XGL_VOID * XGLAPI xglGetProcAddr(XGL_PHYSICAL_GPU gpu, const XGL_CHAR * pName) {
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600869
870 if (gpu == NULL)
871 return NULL;
Jon Ashburn8eecd422014-10-22 12:42:13 -0600872 XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
Jon Ashburn3e7c0802014-10-24 15:48:55 -0600873 XGL_LAYER_DISPATCH_TABLE * disp_table = * (XGL_LAYER_DISPATCH_TABLE **) gpuw->baseObject;
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600874
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600875 if (disp_table == NULL)
876 return NULL;
877
878 if (!strncmp("xglGetProcAddr", (const char *) pName, sizeof("xglGetProcAddr")))
Jon Ashburn3e7c0802014-10-24 15:48:55 -0600879 return disp_table->GetProcAddr;
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600880 else if (!strncmp("xglInitAndEnumerateGpus", (const char *) pName, sizeof("xglInitAndEnumerateGpus")))
881 return disp_table->InitAndEnumerateGpus;
882 else if (!strncmp("xglGetGpuInfo", (const char *) pName, sizeof ("xglGetGpuInfo")))
883 return disp_table->GetGpuInfo;
884 else if (!strncmp("xglCreateDevice", (const char *) pName, sizeof ("xglCreateDevice")))
885 return disp_table->CreateDevice;
886 else if (!strncmp("xglDestroyDevice", (const char *) pName, sizeof ("xglDestroyDevice")))
887 return disp_table->DestroyDevice;
888 else if (!strncmp("xglGetExtensionSupport", (const char *) pName, sizeof ("xglGetExtensionSupport")))
889 return disp_table->GetExtensionSupport;
Jon Ashburn96f28fc2014-10-15 15:30:23 -0600890 else if (!strncmp("xglEnumerateLayers", (const char *) pName, sizeof ("xglEnumerateLayers")))
891 return disp_table->EnumerateLayers;
Jon Ashburnd43f9b62014-10-14 19:15:22 -0600892 else if (!strncmp("xglGetDeviceQueue", (const char *) pName, sizeof ("xglGetDeviceQueue")))
893 return disp_table->GetDeviceQueue;
894 else if (!strncmp("xglQueueSubmit", (const char *) pName, sizeof ("xglQueueSubmit")))
895 return disp_table->QueueSubmit;
896 else if (!strncmp("xglQueueSetGlobalMemReferences", (const char *) pName, sizeof ("xglQueueSetGlobalMemReferences")))
897 return disp_table->QueueSetGlobalMemReferences;
898 else if (!strncmp("xglQueueWaitIdle", (const char *) pName, sizeof ("xglQueueWaitIdle")))
899 return disp_table->QueueWaitIdle;
900 else if (!strncmp("xglDeviceWaitIdle", (const char *) pName, sizeof ("xglDeviceWaitIdle")))
901 return disp_table->DeviceWaitIdle;
902 else if (!strncmp("xglGetMemoryHeapCount", (const char *) pName, sizeof ("xglGetMemoryHeapCount")))
903 return disp_table->GetMemoryHeapCount;
904 else if (!strncmp("xglGetMemoryHeapInfo", (const char *) pName, sizeof ("xglGetMemoryHeapInfo")))
905 return disp_table->GetMemoryHeapInfo;
906 else if (!strncmp("xglAllocMemory", (const char *) pName, sizeof ("xglAllocMemory")))
907 return disp_table->AllocMemory;
908 else if (!strncmp("xglFreeMemory", (const char *) pName, sizeof ("xglFreeMemory")))
909 return disp_table->FreeMemory;
910 else if (!strncmp("xglSetMemoryPriority", (const char *) pName, sizeof ("xglSetMemoryPriority")))
911 return disp_table->SetMemoryPriority;
912 else if (!strncmp("xglMapMemory", (const char *) pName, sizeof ("xglMapMemory")))
913 return disp_table->MapMemory;
914 else if (!strncmp("xglUnmapMemory", (const char *) pName, sizeof ("xglUnmapMemory")))
915 return disp_table->UnmapMemory;
916 else if (!strncmp("xglPinSystemMemory", (const char *) pName, sizeof ("xglPinSystemMemory")))
917 return disp_table->PinSystemMemory;
918 else if (!strncmp("xglRemapVirtualMemoryPages", (const char *) pName, sizeof ("xglRemapVirtualMemoryPages")))
919 return disp_table->RemapVirtualMemoryPages;
920 else if (!strncmp("xglGetMultiGpuCompatibility", (const char *) pName, sizeof ("xglGetMultiGpuCompatibility")))
921 return disp_table->GetMultiGpuCompatibility;
922 else if (!strncmp("xglOpenSharedMemory", (const char *) pName, sizeof ("xglOpenSharedMemory")))
923 return disp_table->OpenSharedMemory;
924 else if (!strncmp("xglOpenSharedQueueSemaphore", (const char *) pName, sizeof ("xglOpenSharedQueueSemaphore")))
925 return disp_table->OpenSharedQueueSemaphore;
926 else if (!strncmp("xglOpenPeerMemory", (const char *) pName, sizeof ("xglOpenPeerMemory")))
927 return disp_table->OpenPeerMemory;
928 else if (!strncmp("xglOpenPeerImage", (const char *) pName, sizeof ("xglOpenPeerImage")))
929 return disp_table->OpenPeerImage;
930 else if (!strncmp("xglDestroyObject", (const char *) pName, sizeof ("xglDestroyObject")))
931 return disp_table->DestroyObject;
932 else if (!strncmp("xglGetObjectInfo", (const char *) pName, sizeof ("xglGetObjectInfo")))
933 return disp_table->GetObjectInfo;
934 else if (!strncmp("xglBindObjectMemory", (const char *) pName, sizeof ("xglBindObjectMemory")))
935 return disp_table->BindObjectMemory;
936 else if (!strncmp("xglCreateFence", (const char *) pName, sizeof ("xgllCreateFence")))
937 return disp_table->CreateFence;
938 else if (!strncmp("xglGetFenceStatus", (const char *) pName, sizeof ("xglGetFenceStatus")))
939 return disp_table->GetFenceStatus;
940 else if (!strncmp("xglWaitForFences", (const char *) pName, sizeof ("xglWaitForFences")))
941 return disp_table->WaitForFences;
942 else if (!strncmp("xglCreateQueueSemaphore", (const char *) pName, sizeof ("xgllCreateQueueSemaphore")))
943 return disp_table->CreateQueueSemaphore;
944 else if (!strncmp("xglSignalQueueSemaphore", (const char *) pName, sizeof ("xglSignalQueueSemaphore")))
945 return disp_table->SignalQueueSemaphore;
946 else if (!strncmp("xglWaitQueueSemaphore", (const char *) pName, sizeof ("xglWaitQueueSemaphore")))
947 return disp_table->WaitQueueSemaphore;
948 else if (!strncmp("xglCreateEvent", (const char *) pName, sizeof ("xgllCreateEvent")))
949 return disp_table->CreateEvent;
950 else if (!strncmp("xglGetEventStatus", (const char *) pName, sizeof ("xglGetEventStatus")))
951 return disp_table->GetEventStatus;
952 else if (!strncmp("xglSetEvent", (const char *) pName, sizeof ("xglSetEvent")))
953 return disp_table->SetEvent;
954 else if (!strncmp("xglResetEvent", (const char *) pName, sizeof ("xgllResetEvent")))
955 return disp_table->ResetEvent;
956 else if (!strncmp("xglCreateQueryPool", (const char *) pName, sizeof ("xglCreateQueryPool")))
957 return disp_table->CreateQueryPool;
958 else if (!strncmp("xglGetQueryPoolResults", (const char *) pName, sizeof ("xglGetQueryPoolResults")))
959 return disp_table->GetQueryPoolResults;
960 else if (!strncmp("xglGetFormatInfo", (const char *) pName, sizeof ("xglGetFormatInfo")))
961 return disp_table->GetFormatInfo;
962 else if (!strncmp("xglCreateImage", (const char *) pName, sizeof ("xglCreateImage")))
963 return disp_table->CreateImage;
964 else if (!strncmp("xglGetImageSubresourceInfo", (const char *) pName, sizeof ("xglGetImageSubresourceInfo")))
965 return disp_table->GetImageSubresourceInfo;
966 else if (!strncmp("xglCreateImageView", (const char *) pName, sizeof ("xglCreateImageView")))
967 return disp_table->CreateImageView;
968 else if (!strncmp("xglCreateColorAttachmentView", (const char *) pName, sizeof ("xglCreateColorAttachmentView")))
969 return disp_table->CreateColorAttachmentView;
970 else if (!strncmp("xglCreateDepthStencilView", (const char *) pName, sizeof ("xglCreateDepthStencilView")))
971 return disp_table->CreateDepthStencilView;
972 else if (!strncmp("xglCreateShader", (const char *) pName, sizeof ("xglCreateShader")))
973 return disp_table->CreateShader;
974 else if (!strncmp("xglCreateGraphicsPipeline", (const char *) pName, sizeof ("xglCreateGraphicsPipeline")))
975 return disp_table->CreateGraphicsPipeline;
976 else if (!strncmp("xglCreateComputePipeline", (const char *) pName, sizeof ("xglCreateComputePipeline")))
977 return disp_table->CreateComputePipeline;
978 else if (!strncmp("xglStorePipeline", (const char *) pName, sizeof ("xglStorePipeline")))
979 return disp_table->StorePipeline;
980 else if (!strncmp("xglLoadPipeline", (const char *) pName, sizeof ("xglLoadPipeline")))
981 return disp_table->LoadPipeline;
982 else if (!strncmp("xglCreatePipelineDelta", (const char *) pName, sizeof ("xglCreatePipelineDelta")))
983 return disp_table->CreatePipelineDelta;
984 else if (!strncmp("xglCreateSampler", (const char *) pName, sizeof ("xglCreateSampler")))
985 return disp_table->CreateSampler;
986 else if (!strncmp("xglCreateDescriptorSet", (const char *) pName, sizeof ("xglCreateDescriptorSet")))
987 return disp_table->CreateDescriptorSet;
988 else if (!strncmp("xglBeginDescriptorSetUpdate", (const char *) pName, sizeof ("xglBeginDescriptorSetUpdate")))
989 return disp_table->BeginDescriptorSetUpdate;
990 else if (!strncmp("xglEndDescriptorSetUpdate", (const char *) pName, sizeof ("xglEndDescriptorSetUpdate")))
991 return disp_table->EndDescriptorSetUpdate;
992 else if (!strncmp("xglAttachSamplerDescriptors", (const char *) pName, sizeof ("xglAttachSamplerDescriptors")))
993 return disp_table->AttachSamplerDescriptors;
994 else if (!strncmp("xglAttachImageViewDescriptors", (const char *) pName, sizeof ("xglAttachImageViewDescriptors")))
995 return disp_table->AttachImageViewDescriptors;
996 else if (!strncmp("xglAttachMemoryViewDescriptors", (const char *) pName, sizeof ("xglAttachMemoryViewDescriptors")))
997 return disp_table->AttachMemoryViewDescriptors;
998 else if (!strncmp("xglAttachNestedDescriptors", (const char *) pName, sizeof ("xglAttachNestedDescriptors")))
999 return disp_table->AttachNestedDescriptors;
1000 else if (!strncmp("xglClearDescriptorSetSlots", (const char *) pName, sizeof ("xglClearDescriptorSetSlots")))
1001 return disp_table->ClearDescriptorSetSlots;
1002 else if (!strncmp("xglCreateViewportState", (const char *) pName, sizeof ("xglCreateViewportState")))
1003 return disp_table->CreateViewportState;
1004 else if (!strncmp("xglCreateRasterState", (const char *) pName, sizeof ("xglCreateRasterState")))
1005 return disp_table->CreateRasterState;
1006 else if (!strncmp("xglCreateMsaaState", (const char *) pName, sizeof ("xglCreateMsaaState")))
1007 return disp_table->CreateMsaaState;
1008 else if (!strncmp("xglCreateColorBlendState", (const char *) pName, sizeof ("xglCreateColorBlendState")))
1009 return disp_table->CreateColorBlendState;
1010 else if (!strncmp("xglCreateDepthStencilState", (const char *) pName, sizeof ("xglCreateDepthStencilState")))
1011 return disp_table->CreateDepthStencilState;
1012 else if (!strncmp("xglCreateCommandBuffer", (const char *) pName, sizeof ("xglCreateCommandBuffer")))
1013 return disp_table->CreateCommandBuffer;
1014 else if (!strncmp("xglBeginCommandBuffer", (const char *) pName, sizeof ("xglBeginCommandBuffer")))
1015 return disp_table->BeginCommandBuffer;
1016 else if (!strncmp("xglEndCommandBuffer", (const char *) pName, sizeof ("xglEndCommandBuffer")))
1017 return disp_table->EndCommandBuffer;
1018 else if (!strncmp("xglResetCommandBuffer", (const char *) pName, sizeof ("xglResetCommandBuffer")))
1019 return disp_table->ResetCommandBuffer;
1020 else if (!strncmp("xglCmdBindPipeline", (const char *) pName, sizeof ("xglCmdBindPipeline")))
1021 return disp_table->CmdBindPipeline;
1022 else if (!strncmp("xglCmdBindPipelineDelta", (const char *) pName, sizeof ("xglCmdBindPipelineDelta")))
1023 return disp_table->CmdBindPipelineDelta;
1024 else if (!strncmp("xglCmdBindStateObject", (const char *) pName, sizeof ("xglCmdBindStateObject")))
1025 return disp_table->CmdBindStateObject;
1026 else if (!strncmp("xglCmdBindDescriptorSet", (const char *) pName, sizeof ("xglCmdBindDescriptorSet")))
1027 return disp_table->CmdBindDescriptorSet;
1028 else if (!strncmp("xglCmdBindDynamicMemoryView", (const char *) pName, sizeof ("xglCmdBindDynamicMemoryView")))
1029 return disp_table->CmdBindDynamicMemoryView;
Chia-I Wu3b04af52014-11-08 10:48:20 +08001030 else if (!strncmp("xglCmdBindVertexData", (const char *) pName, sizeof ("xglCmdBindVertexData")))
1031 return disp_table->CmdBindVertexData;
Jon Ashburnd43f9b62014-10-14 19:15:22 -06001032 else if (!strncmp("xglCmdBindIndexData", (const char *) pName, sizeof ("xglCmdBindIndexData")))
1033 return disp_table->CmdBindIndexData;
1034 else if (!strncmp("xglCmdBindAttachments", (const char *) pName, sizeof ("xglCmdBindAttachments")))
1035 return disp_table->CmdBindAttachments;
1036 else if (!strncmp("xglCmdPrepareMemoryRegions", (const char *) pName, sizeof ("xglCmdPrepareMemoryRegions")))
1037 return disp_table->CmdPrepareMemoryRegions;
1038 else if (!strncmp("xglCmdPrepareImages", (const char *) pName, sizeof ("xglCmdPrepareImages")))
1039 return disp_table->CmdPrepareImages;
1040 else if (!strncmp("xglCmdDraw", (const char *) pName, sizeof ("xglCmdDraw")))
1041 return disp_table->CmdDraw;
1042 else if (!strncmp("xglCmdDrawIndexed", (const char *) pName, sizeof ("xglCmdDrawIndexed")))
1043 return disp_table->CmdDrawIndexed;
1044 else if (!strncmp("xglCmdDrawIndirect", (const char *) pName, sizeof ("xglCmdDrawIndirect")))
1045 return disp_table->CmdDrawIndirect;
1046 else if (!strncmp("xglCmdDrawIndexedIndirect", (const char *) pName, sizeof ("xglCmdDrawIndexedIndirect")))
1047 return disp_table->CmdDrawIndexedIndirect;
1048 else if (!strncmp("xglCmdDispatch", (const char *) pName, sizeof ("xglCmdDispatch")))
1049 return disp_table->CmdDispatch;
1050 else if (!strncmp("xglCmdDispatchIndirect", (const char *) pName, sizeof ("xglCmdDispatchIndirect")))
1051 return disp_table->CmdDispatchIndirect;
1052 else if (!strncmp("xglCmdCopyMemory", (const char *) pName, sizeof ("xglCmdCopyMemory")))
1053 return disp_table->CmdCopyMemory;
1054 else if (!strncmp("xglCmdCopyImage", (const char *) pName, sizeof ("xglCmdCopyImage")))
1055 return disp_table->CmdCopyImage;
1056 else if (!strncmp("xglCmdCopyMemoryToImage", (const char *) pName, sizeof ("xglCmdCopyMemoryToImage")))
1057 return disp_table->CmdCopyMemoryToImage;
1058 else if (!strncmp("xglCmdCopyImageToMemory", (const char *) pName, sizeof ("xglCmdCopyImageToMemory")))
1059 return disp_table->CmdCopyImageToMemory;
1060 else if (!strncmp("xglCmdCloneImageData", (const char *) pName, sizeof ("xglCmdCloneImageData")))
1061 return disp_table->CmdCloneImageData;
1062 else if (!strncmp("xglCmdUpdateMemory", (const char *) pName, sizeof ("xglCmdUpdateMemory")))
1063 return disp_table->CmdUpdateMemory;
1064 else if (!strncmp("xglCmdFillMemory", (const char *) pName, sizeof ("xglCmdFillMemory")))
1065 return disp_table->CmdFillMemory;
1066 else if (!strncmp("xglCmdClearColorImage", (const char *) pName, sizeof ("xglCmdClearColorImage")))
1067 return disp_table->CmdClearColorImage;
1068 else if (!strncmp("xglCmdClearColorImageRaw", (const char *) pName, sizeof ("xglCmdClearColorImageRaw")))
1069 return disp_table->CmdClearColorImageRaw;
1070 else if (!strncmp("xglCmdClearDepthStencil", (const char *) pName, sizeof ("xglCmdClearDepthStencil")))
1071 return disp_table->CmdClearDepthStencil;
1072 else if (!strncmp("xglCmdResolveImage", (const char *) pName, sizeof ("xglCmdResolveImage")))
1073 return disp_table->CmdResolveImage;
1074 else if (!strncmp("xglCmdSetEvent", (const char *) pName, sizeof ("xglCmdSetEvent")))
1075 return disp_table->CmdSetEvent;
1076 else if (!strncmp("xglCmdResetEvent", (const char *) pName, sizeof ("xglCmdResetEvent")))
1077 return disp_table->CmdResetEvent;
1078 else if (!strncmp("xglCmdMemoryAtomic", (const char *) pName, sizeof ("xglCmdMemoryAtomic")))
1079 return disp_table->CmdMemoryAtomic;
1080 else if (!strncmp("xglCmdBeginQuery", (const char *) pName, sizeof ("xglCmdBeginQuery")))
1081 return disp_table->CmdBeginQuery;
1082 else if (!strncmp("xglCmdEndQuery", (const char *) pName, sizeof ("xglCmdEndQuery")))
1083 return disp_table->CmdEndQuery;
1084 else if (!strncmp("xglCmdResetQueryPool", (const char *) pName, sizeof ("xglCmdResetQueryPool")))
1085 return disp_table->CmdResetQueryPool;
1086 else if (!strncmp("xglCmdWriteTimestamp", (const char *) pName, sizeof ("xglCmdWriteTimestamp")))
1087 return disp_table->CmdWriteTimestamp;
1088 else if (!strncmp("xglCmdInitAtomicCounters", (const char *) pName, sizeof ("xglCmdInitAtomicCounters")))
1089 return disp_table->CmdInitAtomicCounters;
1090 else if (!strncmp("xglCmdLoadAtomicCounters", (const char *) pName, sizeof ("xglCmdLoadAtomicCounters")))
1091 return disp_table->CmdLoadAtomicCounters;
1092 else if (!strncmp("xglCmdSaveAtomicCounters", (const char *) pName, sizeof ("xglCmdSaveAtomicCounters")))
1093 return disp_table->CmdSaveAtomicCounters;
1094 else if (!strncmp("xglDbgSetValidationLevel", (const char *) pName, sizeof ("xglDbgSetValidationLevel")))
1095 return disp_table->DbgSetValidationLevel;
1096 else if (!strncmp("xglDbgRegisterMsgCallback", (const char *) pName, sizeof ("xglDbgRegisterMsgCallback")))
1097 return disp_table->DbgRegisterMsgCallback;
1098 else if (!strncmp("xglDbgUnregisterMsgCallback", (const char *) pName, sizeof ("xglDbgUnregisterMsgCallback")))
1099 return disp_table->DbgUnregisterMsgCallback;
1100 else if (!strncmp("xglDbgSetMessageFilter", (const char *) pName, sizeof ("xglDbgSetMessageFilter")))
1101 return disp_table->DbgSetMessageFilter;
1102 else if (!strncmp("xglDbgSetObjectTag", (const char *) pName, sizeof ("xglDbgSetObjectTag")))
1103 return disp_table->DbgSetObjectTag;
1104 else if (!strncmp("xglDbgSetGlobalOption", (const char *) pName, sizeof ("xglDbgSetGlobalOption")))
1105 return disp_table->DbgSetGlobalOption;
1106 else if (!strncmp("xglDbgSetDeviceOption", (const char *) pName, sizeof ("xglDbgSetDeviceOption")))
1107 return disp_table->DbgSetDeviceOption;
1108 else if (!strncmp("xglCmdDbgMarkerBegin", (const char *) pName, sizeof ("xglCmdDbgMarkerBegin")))
1109 return disp_table->CmdDbgMarkerBegin;
1110 else if (!strncmp("xglCmdDbgMarkerEnd", (const char *) pName, sizeof ("xglCmdDbgMarkerEnd")))
1111 return disp_table->CmdDbgMarkerEnd;
1112 else if (!strncmp("xglWsiX11AssociateConnection", (const char *) pName, sizeof("xglWsiX11AssociateConnection")))
1113 return disp_table->WsiX11AssociateConnection;
1114 else if (!strncmp("xglWsiX11GetMSC", (const char *) pName, sizeof("xglWsiX11GetMSC")))
1115 return disp_table->WsiX11GetMSC;
1116 else if (!strncmp("xglWsiX11CreatePresentableImage", (const char *) pName, sizeof("xglWsiX11CreatePresentableImage")))
1117 return disp_table->WsiX11CreatePresentableImage;
1118 else if (!strncmp("xglWsiX11QueuePresent", (const char *) pName, sizeof("xglWsiX11QueuePresent")))
1119 return disp_table->WsiX11QueuePresent;
1120 else {
Jon Ashburn3e7c0802014-10-24 15:48:55 -06001121 if (disp_table->GetProcAddr == NULL)
Jon Ashburnd43f9b62014-10-14 19:15:22 -06001122 return NULL;
Jon Ashburn3e7c0802014-10-24 15:48:55 -06001123 return disp_table->GetProcAddr(gpuw->nextObject, pName);
Jon Ashburnd43f9b62014-10-14 19:15:22 -06001124 }
1125}
1126
Chia-I Wu468e3c32014-08-04 08:03:57 +08001127LOADER_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 +08001128{
1129 static pthread_once_t once = PTHREAD_ONCE_INIT;
Jon Ashburn815bddd2014-10-16 15:48:50 -06001130 struct loader_icd *icd;
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001131 XGL_UINT count = 0;
1132 XGL_RESULT res;
1133
Jon Ashburn815bddd2014-10-16 15:48:50 -06001134 // cleanup any prior layer initializations
Jon Ashburnb55278a2014-10-17 15:09:07 -06001135 loader_deactivate_layer();
Jon Ashburn815bddd2014-10-16 15:48:50 -06001136
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001137 pthread_once(&once, loader_icd_scan);
1138
1139 if (!loader.icds)
1140 return XGL_ERROR_UNAVAILABLE;
1141
1142 icd = loader.icds;
1143 while (icd) {
1144 XGL_PHYSICAL_GPU gpus[XGL_MAX_PHYSICAL_GPUS];
Jon Ashburnd43f9b62014-10-14 19:15:22 -06001145 XGL_BASE_LAYER_OBJECT * wrappedGpus;
1146 GetProcAddrType getProcAddr = icd->GetProcAddr;
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001147 XGL_UINT n, max = maxGpus - count;
1148
1149 if (max > XGL_MAX_PHYSICAL_GPUS) {
1150 max = XGL_MAX_PHYSICAL_GPUS;
1151 }
1152
1153 res = icd->InitAndEnumerateGpus(pAppInfo, pAllocCb, max, &n, gpus);
Chia-I Wu74916ed2014-08-06 12:17:04 +08001154 if (res == XGL_SUCCESS && n) {
Jon Ashburnd43f9b62014-10-14 19:15:22 -06001155 wrappedGpus = (XGL_BASE_LAYER_OBJECT*) malloc(n * sizeof(XGL_BASE_LAYER_OBJECT));
Jon Ashburn183dfd02014-10-22 18:13:16 -06001156 icd->gpus = wrappedGpus;
Jon Ashburnb55278a2014-10-17 15:09:07 -06001157 icd->gpu_count = n;
Jon Ashburn815bddd2014-10-16 15:48:50 -06001158 icd->loader_dispatch = (XGL_LAYER_DISPATCH_TABLE *) malloc(n * sizeof(XGL_LAYER_DISPATCH_TABLE));
Jon Ashburnd43f9b62014-10-14 19:15:22 -06001159 for (int i = 0; i < n; i++) {
1160 (wrappedGpus + i)->baseObject = gpus[i];
Jon Ashburn815bddd2014-10-16 15:48:50 -06001161 (wrappedGpus + i)->pGPA = getProcAddr;
Jon Ashburnd43f9b62014-10-14 19:15:22 -06001162 (wrappedGpus + i)->nextObject = gpus[i];
1163 memcpy(pGpus + count, &wrappedGpus, sizeof(*pGpus));
Jon Ashburn8eecd422014-10-22 12:42:13 -06001164 loader_init_dispatch_table(icd->loader_dispatch + i, getProcAddr, gpus[i]);
Jon Ashburnd43f9b62014-10-14 19:15:22 -06001165 const XGL_LAYER_DISPATCH_TABLE * *disp = (const XGL_LAYER_DISPATCH_TABLE * *) gpus[i];
Jon Ashburn815bddd2014-10-16 15:48:50 -06001166 *disp = icd->loader_dispatch + i;
Jon Ashburnd43f9b62014-10-14 19:15:22 -06001167 }
1168
Jon Ashburn99e996a2014-12-18 17:00:52 -07001169 if (loader_icd_set_global_options(icd) != XGL_SUCCESS ||
1170 loader_icd_register_msg_callbacks(icd) != XGL_SUCCESS) {
1171 loader_log(XGL_DBG_MSG_WARNING, 0,
1172 "ICD ignored: failed to migrate settings");
1173 loader_icd_destroy(icd);
1174 }
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001175 count += n;
1176
1177 if (count >= maxGpus) {
1178 break;
1179 }
1180 }
1181
1182 icd = icd->next;
1183 }
1184
Jon Ashburn99e996a2014-12-18 17:00:52 -07001185 /* we have nothing to log anymore */
1186 loader_msg_callback_clear();
1187
Jon Ashburnd43f9b62014-10-14 19:15:22 -06001188 /* get layer libraries */
Jon Ashburn183dfd02014-10-22 18:13:16 -06001189 if (!loader.layer_scanned)
Courtney Goeltzenleuchterbce445a2014-12-01 09:29:42 -07001190 layer_lib_scan(NULL);
Jon Ashburnd43f9b62014-10-14 19:15:22 -06001191
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001192 *pGpuCount = count;
1193
1194 return (count > 0) ? XGL_SUCCESS : res;
1195}
1196
Jon Ashburn6847c2b2014-11-25 12:56:49 -07001197LOADER_EXPORT XGL_RESULT XGLAPI xglEnumerateLayers(XGL_PHYSICAL_GPU gpu, XGL_SIZE maxLayerCount, XGL_SIZE maxStringSize, XGL_CHAR* const* pOutLayers, XGL_SIZE* pOutLayerCount, XGL_VOID* pReserved)
Jon Ashburn96f28fc2014-10-15 15:30:23 -06001198{
Jon Ashburnb9a54ac2014-12-02 13:03:09 -07001199 XGL_UINT gpu_index;
1200 XGL_UINT count = 0;
1201 char *lib_name;
1202 struct loader_icd *icd = loader_get_icd((const XGL_BASE_LAYER_OBJECT *) gpu, &gpu_index);
1203 void *handle;
1204 EnumerateLayersType fpEnumerateLayers;
1205 XGL_CHAR layer_buf[16][256];
1206 XGL_CHAR * layers[16];
Jon Ashburn96f28fc2014-10-15 15:30:23 -06001207
Jon Ashburnb9a54ac2014-12-02 13:03:09 -07001208 if (pOutLayerCount == NULL || pOutLayers == NULL)
Jon Ashburn96f28fc2014-10-15 15:30:23 -06001209 return XGL_ERROR_INVALID_POINTER;
1210
Jon Ashburnb9a54ac2014-12-02 13:03:09 -07001211 for (int i = 0; i < 16; i++)
1212 layers[i] = &layer_buf[i][0];
1213
1214 for (unsigned int j = 0; j < loader.scanned_layer_count && count < maxLayerCount; j++) {
1215 lib_name = loader.scanned_layer_names[j];
1216 if ((handle = dlopen(lib_name, RTLD_LAZY)) == NULL)
1217 continue;
1218 if ((fpEnumerateLayers = dlsym(handle, "xglEnumerateLayers")) == NULL) {
1219 //use default layer name based on library name libXGLLayer<name>.so
1220 char *pEnd, *cpyStr;
1221 int siz;
1222 dlclose(handle);
1223 lib_name = basename(lib_name);
1224 pEnd = strrchr(lib_name, '.');
1225 siz = pEnd - lib_name - strlen("libXGLLayer") + 1;
1226 if (pEnd == NULL || siz <= 0)
1227 continue;
1228 cpyStr = malloc(siz);
1229 if (cpyStr == NULL) {
1230 free(cpyStr);
1231 continue;
1232 }
1233 strncpy(cpyStr, lib_name + strlen("libXGLLayer"), siz);
1234 cpyStr[siz - 1] = '\0';
1235 if (siz > maxStringSize)
1236 siz = maxStringSize;
1237 strncpy((char *) (pOutLayers[count]), cpyStr, siz);
1238 pOutLayers[count][siz - 1] = '\0';
1239 count++;
1240 free(cpyStr);
1241 }
1242 else {
1243 XGL_SIZE cnt;
1244 XGL_UINT n;
1245 XGL_RESULT res;
1246 n = (maxStringSize < 256) ? maxStringSize : 256;
1247 res = fpEnumerateLayers(NULL, 16, n, layers, &cnt, (XGL_VOID *) icd->gpus + gpu_index);
1248 dlclose(handle);
1249 if (res != XGL_SUCCESS)
1250 continue;
1251 if (cnt + count > maxLayerCount)
1252 cnt = maxLayerCount - count;
1253 for (unsigned int i = count; i < cnt + count; i++) {
1254 strncpy((char *) (pOutLayers[i]), (char *) layers[i - count], n);
1255 if (n > 0)
1256 pOutLayers[i - count][n - 1] = '\0';
1257 }
1258 count += cnt;
1259 }
1260 }
1261
Jon Ashburn96f28fc2014-10-15 15:30:23 -06001262 *pOutLayerCount = count;
1263
Jon Ashburn96f28fc2014-10-15 15:30:23 -06001264 return XGL_SUCCESS;
1265}
1266
Chia-I Wu468e3c32014-08-04 08:03:57 +08001267LOADER_EXPORT XGL_RESULT XGLAPI xglDbgRegisterMsgCallback(XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback, XGL_VOID* pUserData)
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001268{
Jon Ashburn406a0fe2014-11-14 09:52:42 -07001269 const struct loader_icd *icd;
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001270 XGL_RESULT res;
Jon Ashburn406a0fe2014-11-14 09:52:42 -07001271 XGL_UINT gpu_idx;
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001272
1273 if (!loader.scanned) {
1274 return loader_msg_callback_add(pfnMsgCallback, pUserData);
1275 }
1276
Jon Ashburn406a0fe2014-11-14 09:52:42 -07001277 for (icd = loader.icds; icd; icd = icd->next) {
1278 for (XGL_UINT i = 0; i < icd->gpu_count; i++) {
1279 res = (icd->loader_dispatch + i)->DbgRegisterMsgCallback(pfnMsgCallback, pUserData);
1280 if (res != XGL_SUCCESS) {
1281 gpu_idx = i;
1282 break;
1283 }
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001284 }
Jon Ashburn406a0fe2014-11-14 09:52:42 -07001285 if (res != XGL_SUCCESS)
1286 break;
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001287 }
1288
1289 /* roll back on errors */
1290 if (icd) {
Jon Ashburn406a0fe2014-11-14 09:52:42 -07001291 for (const struct loader_icd * tmp = loader.icds; tmp != icd; tmp = tmp->next) {
1292 for (XGL_UINT i = 0; i < icd->gpu_count; i++)
1293 (tmp->loader_dispatch + i)->DbgUnregisterMsgCallback(pfnMsgCallback);
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001294 }
Jon Ashburn406a0fe2014-11-14 09:52:42 -07001295 /* and gpus on current icd */
1296 for (XGL_UINT i = 0; i < gpu_idx; i++)
1297 (icd->loader_dispatch + i)->DbgUnregisterMsgCallback(pfnMsgCallback);
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001298
1299 return res;
1300 }
1301
1302 return XGL_SUCCESS;
1303}
1304
Chia-I Wu468e3c32014-08-04 08:03:57 +08001305LOADER_EXPORT XGL_RESULT XGLAPI xglDbgUnregisterMsgCallback(XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback)
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001306{
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001307 XGL_RESULT res = XGL_SUCCESS;
1308
1309 if (!loader.scanned) {
1310 return loader_msg_callback_remove(pfnMsgCallback);
1311 }
1312
Jon Ashburn406a0fe2014-11-14 09:52:42 -07001313 for (const struct loader_icd * icd = loader.icds; icd; icd = icd->next) {
1314 for (XGL_UINT i = 0; i < icd->gpu_count; i++) {
1315 XGL_RESULT r = (icd->loader_dispatch + i)->DbgUnregisterMsgCallback(pfnMsgCallback);
1316 if (r != XGL_SUCCESS) {
1317 res = r;
1318 }
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001319 }
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001320 }
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001321 return res;
1322}
1323
Chia-I Wu468e3c32014-08-04 08:03:57 +08001324LOADER_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 +08001325{
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001326 XGL_RESULT res = XGL_SUCCESS;
1327
1328 if (!loader.scanned) {
1329 if (dataSize == 0)
1330 return XGL_ERROR_INVALID_VALUE;
1331
1332 switch (dbgOption) {
1333 case XGL_DBG_OPTION_DEBUG_ECHO_ENABLE:
1334 loader.debug_echo_enable = *((const bool *) pData);
1335 break;
1336 case XGL_DBG_OPTION_BREAK_ON_ERROR:
1337 loader.break_on_error = *((const bool *) pData);
1338 break;
1339 case XGL_DBG_OPTION_BREAK_ON_WARNING:
1340 loader.break_on_warning = *((const bool *) pData);
1341 break;
1342 default:
1343 res = XGL_ERROR_INVALID_VALUE;
1344 break;
1345 }
1346
1347 return res;
1348 }
1349
Jon Ashburn406a0fe2014-11-14 09:52:42 -07001350 for (const struct loader_icd * icd = loader.icds; icd; icd = icd->next) {
1351 for (XGL_UINT i = 0; i < icd->gpu_count; i++) {
1352 XGL_RESULT r = (icd->loader_dispatch + i)->DbgSetGlobalOption(dbgOption, dataSize, pData);
1353 /* unfortunately we cannot roll back */
1354 if (r != XGL_SUCCESS) {
1355 res = r;
1356 }
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001357 }
Chia-I Wu5f72d0f2014-08-01 11:21:23 +08001358 }
1359
1360 return res;
1361}