pipe_loader_sw.c revision 46991ab9aac99c5ba55b735396f32447e75a6320
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_memory.h" 31#include "util/u_dl.h" 32#include "sw/dri/dri_sw_winsys.h" 33#include "sw/kms-dri/kms_dri_sw_winsys.h" 34#include "sw/null/null_sw_winsys.h" 35#include "sw/wrapper/wrapper_sw_winsys.h" 36#include "target-helpers/inline_sw_helper.h" 37#include "state_tracker/drisw_api.h" 38#include "state_tracker/sw_driver.h" 39 40struct pipe_loader_sw_device { 41 struct pipe_loader_device base; 42 const struct sw_driver_descriptor *dd; 43 struct util_dl_library *lib; 44 struct sw_winsys *ws; 45}; 46 47#define pipe_loader_sw_device(dev) ((struct pipe_loader_sw_device *)dev) 48 49static struct pipe_loader_ops pipe_loader_sw_ops; 50 51static bool 52pipe_loader_sw_probe_init_common(struct pipe_loader_sw_device *sdev) 53{ 54 sdev->base.type = PIPE_LOADER_DEVICE_SOFTWARE; 55 sdev->base.driver_name = "swrast"; 56 sdev->base.ops = &pipe_loader_sw_ops; 57 58 sdev->lib = pipe_loader_find_module(&sdev->base, PIPE_SEARCH_DIR); 59 if (!sdev->lib) 60 return false; 61 62 sdev->dd = (const struct sw_driver_descriptor *) 63 util_dl_get_proc_address(sdev->lib, "swrast_driver_descriptor"); 64 65 if (!sdev->dd){ 66 util_dl_close(sdev->lib); 67 sdev->lib = NULL; 68 return false; 69 } 70 71 return true; 72} 73 74static void 75pipe_loader_sw_probe_teardown_common(struct pipe_loader_sw_device *sdev) 76{ 77 if (sdev->lib) 78 util_dl_close(sdev->lib); 79} 80 81#ifdef HAVE_PIPE_LOADER_DRI 82bool 83pipe_loader_sw_probe_dri(struct pipe_loader_device **devs, struct drisw_loader_funcs *drisw_lf) 84{ 85 struct pipe_loader_sw_device *sdev = CALLOC_STRUCT(pipe_loader_sw_device); 86 int i; 87 88 if (!sdev) 89 return false; 90 91 if (!pipe_loader_sw_probe_init_common(sdev)) 92 goto fail; 93 94 for (i = 0; sdev->dd->winsys; i++) { 95 if (strcmp(sdev->dd->winsys[i].name, "dri") == 0) { 96 sdev->ws = sdev->dd->winsys[i].create_winsys(drisw_lf); 97 break; 98 } 99 } 100 if (!sdev->ws) 101 goto fail; 102 103 *devs = &sdev->base; 104 return true; 105 106fail: 107 pipe_loader_sw_probe_teardown_common(sdev); 108 FREE(sdev); 109 return false; 110} 111#endif 112 113#ifdef HAVE_PIPE_LOADER_KMS 114bool 115pipe_loader_sw_probe_kms(struct pipe_loader_device **devs, int fd) 116{ 117 struct pipe_loader_sw_device *sdev = CALLOC_STRUCT(pipe_loader_sw_device); 118 int i; 119 120 if (!sdev) 121 return false; 122 123 if (!pipe_loader_sw_probe_init_common(sdev)) 124 goto fail; 125 126 for (i = 0; sdev->dd->winsys; i++) { 127 if (strcmp(sdev->dd->winsys[i].name, "kms_dri") == 0) { 128 sdev->ws = sdev->dd->winsys[i].create_winsys(fd); 129 break; 130 } 131 } 132 if (!sdev->ws) 133 goto fail; 134 135 *devs = &sdev->base; 136 return true; 137 138fail: 139 pipe_loader_sw_probe_teardown_common(sdev); 140 FREE(sdev); 141 return false; 142} 143#endif 144 145bool 146pipe_loader_sw_probe_null(struct pipe_loader_device **devs) 147{ 148 struct pipe_loader_sw_device *sdev = CALLOC_STRUCT(pipe_loader_sw_device); 149 int i; 150 151 if (!sdev) 152 return false; 153 154 if (!pipe_loader_sw_probe_init_common(sdev)) 155 goto fail; 156 157 for (i = 0; sdev->dd->winsys; i++) { 158 if (strcmp(sdev->dd->winsys[i].name, "null") == 0) { 159 sdev->ws = sdev->dd->winsys[i].create_winsys(); 160 break; 161 } 162 } 163 if (!sdev->ws) 164 goto fail; 165 166 *devs = &sdev->base; 167 return true; 168 169fail: 170 pipe_loader_sw_probe_teardown_common(sdev); 171 FREE(sdev); 172 return false; 173} 174 175int 176pipe_loader_sw_probe(struct pipe_loader_device **devs, int ndev) 177{ 178 int i = 1; 179 180 if (i < ndev) { 181 if (!pipe_loader_sw_probe_null(devs)) { 182 i--; 183 } 184 } 185 186 return i; 187} 188 189boolean 190pipe_loader_sw_probe_wrapped(struct pipe_loader_device **dev, 191 struct pipe_screen *screen) 192{ 193 struct pipe_loader_sw_device *sdev = CALLOC_STRUCT(pipe_loader_sw_device); 194 int i; 195 196 if (!sdev) 197 return false; 198 199 if (!pipe_loader_sw_probe_init_common(sdev)) 200 goto fail; 201 202 for (i = 0; sdev->dd->winsys; i++) { 203 if (strcmp(sdev->dd->winsys[i].name, "wrapped") == 0) { 204 sdev->ws = sdev->dd->winsys[i].create_winsys(screen); 205 break; 206 } 207 } 208 if (!sdev->ws) 209 goto fail; 210 211 *dev = &sdev->base; 212 return true; 213 214fail: 215 pipe_loader_sw_probe_teardown_common(sdev); 216 FREE(sdev); 217 return false; 218} 219 220static void 221pipe_loader_sw_release(struct pipe_loader_device **dev) 222{ 223 struct pipe_loader_sw_device *sdev = pipe_loader_sw_device(*dev); 224 225 if (sdev->lib) 226 util_dl_close(sdev->lib); 227 228 FREE(sdev); 229 *dev = NULL; 230} 231 232static const struct drm_conf_ret * 233pipe_loader_sw_configuration(struct pipe_loader_device *dev, 234 enum drm_conf conf) 235{ 236 return NULL; 237} 238 239static struct pipe_screen * 240pipe_loader_sw_create_screen(struct pipe_loader_device *dev) 241{ 242 struct pipe_loader_sw_device *sdev = pipe_loader_sw_device(dev); 243 struct pipe_screen *screen; 244 245 screen = sdev->dd->create_screen(sdev->ws); 246 if (!screen) 247 sdev->ws->destroy(sdev->ws); 248 249 return screen; 250} 251 252static struct pipe_loader_ops pipe_loader_sw_ops = { 253 .create_screen = pipe_loader_sw_create_screen, 254 .configuration = pipe_loader_sw_configuration, 255 .release = pipe_loader_sw_release 256}; 257