pipe_loader.c revision 361fc4cb
1/************************************************************************** 2 * 3 * Copyright 2012 Francisco Jerez 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28#include "pipe_loader_priv.h" 29 30#include "util/u_inlines.h" 31#include "util/u_memory.h" 32#include "util/u_string.h" 33#include "util/u_dl.h" 34#include "util/u_file.h" 35#include "util/xmlconfig.h" 36#include "util/xmlpool.h" 37 38#include <string.h> 39 40#ifdef _MSC_VER 41#include <stdlib.h> 42#define PATH_MAX _MAX_PATH 43#endif 44 45#define MODULE_PREFIX "pipe_" 46 47static int (*backends[])(struct pipe_loader_device **, int) = { 48#ifdef HAVE_LIBDRM 49 &pipe_loader_drm_probe, 50#endif 51 &pipe_loader_sw_probe 52}; 53 54const char gallium_driinfo_xml[] = 55 DRI_CONF_BEGIN 56#include "driinfo_gallium.h" 57 DRI_CONF_END 58; 59 60int 61pipe_loader_probe(struct pipe_loader_device **devs, int ndev) 62{ 63 int i, n = 0; 64 65 for (i = 0; i < ARRAY_SIZE(backends); i++) 66 n += backends[i](&devs[n], MAX2(0, ndev - n)); 67 68 return n; 69} 70 71void 72pipe_loader_release(struct pipe_loader_device **devs, int ndev) 73{ 74 int i; 75 76 for (i = 0; i < ndev; i++) 77 devs[i]->ops->release(&devs[i]); 78} 79 80void 81pipe_loader_base_release(struct pipe_loader_device **dev) 82{ 83 driDestroyOptionCache(&(*dev)->option_cache); 84 driDestroyOptionInfo(&(*dev)->option_info); 85 86 FREE(*dev); 87 *dev = NULL; 88} 89 90void 91pipe_loader_load_options(struct pipe_loader_device *dev) 92{ 93 if (dev->option_info.info) 94 return; 95 96 const char *xml_options = dev->ops->get_driconf_xml(dev); 97 if (!xml_options) 98 xml_options = gallium_driinfo_xml; 99 100 driParseOptionInfo(&dev->option_info, xml_options); 101 driParseConfigFiles(&dev->option_cache, &dev->option_info, 0, 102 dev->driver_name, NULL); 103} 104 105char * 106pipe_loader_get_driinfo_xml(const char *driver_name) 107{ 108#ifdef HAVE_LIBDRM 109 char *xml = pipe_loader_drm_get_driinfo_xml(driver_name); 110#else 111 char *xml = NULL; 112#endif 113 114 if (!xml) 115 xml = strdup(gallium_driinfo_xml); 116 117 return xml; 118} 119 120struct pipe_screen * 121pipe_loader_create_screen(struct pipe_loader_device *dev) 122{ 123 struct pipe_screen_config config; 124 125 pipe_loader_load_options(dev); 126 config.options = &dev->option_cache; 127 128 return dev->ops->create_screen(dev, &config); 129} 130 131struct util_dl_library * 132pipe_loader_find_module(const char *driver_name, 133 const char *library_paths) 134{ 135 struct util_dl_library *lib; 136 const char *next; 137 char path[PATH_MAX]; 138 int len, ret; 139 140 for (next = library_paths; *next; library_paths = next + 1) { 141 next = util_strchrnul(library_paths, ':'); 142 len = next - library_paths; 143 144 if (len) 145 ret = util_snprintf(path, sizeof(path), "%.*s/%s%s%s", 146 len, library_paths, 147 MODULE_PREFIX, driver_name, UTIL_DL_EXT); 148 else 149 ret = util_snprintf(path, sizeof(path), "%s%s%s", 150 MODULE_PREFIX, driver_name, UTIL_DL_EXT); 151 152 if (ret > 0 && ret < sizeof(path) && u_file_access(path, 0) != -1) { 153 lib = util_dl_open(path); 154 if (lib) { 155 return lib; 156 } 157 fprintf(stderr, "ERROR: Failed to load pipe driver at `%s': %s\n", 158 path, util_dl_error()); 159 } 160 } 161 162 return NULL; 163} 164