Path: blob/21.2-virgl/src/gallium/auxiliary/pipe-loader/pipe_loader_sw.c
4561 views
/**************************************************************************1*2* Copyright 2012 Francisco Jerez3* All Rights Reserved.4*5* Permission is hereby granted, free of charge, to any person obtaining a6* copy of this software and associated documentation files (the7* "Software"), to deal in the Software without restriction, including8* without limitation the rights to use, copy, modify, merge, publish,9* distribute, sub license, and/or sell copies of the Software, and to10* permit persons to whom the Software is furnished to do so, subject to11* the following conditions:12*13* The above copyright notice and this permission notice (including the14* next paragraph) shall be included in all copies or substantial portions15* of the Software.16*17* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS18* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.20* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR21* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,22* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE23* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.24*25**************************************************************************/2627#ifdef HAVE_PIPE_LOADER_KMS28#include <fcntl.h>29#endif3031#include "pipe_loader_priv.h"3233#include "util/os_file.h"34#include "util/u_memory.h"35#include "util/u_dl.h"36#include "sw/dri/dri_sw_winsys.h"37#include "sw/kms-dri/kms_dri_sw_winsys.h"38#include "sw/null/null_sw_winsys.h"39#include "sw/wrapper/wrapper_sw_winsys.h"40#include "target-helpers/sw_helper_public.h"41#include "target-helpers/inline_debug_helper.h"42#include "frontend/drisw_api.h"43#include "frontend/sw_driver.h"44#include "frontend/sw_winsys.h"454647struct pipe_loader_sw_device {48struct pipe_loader_device base;49const struct sw_driver_descriptor *dd;50#ifndef GALLIUM_STATIC_TARGETS51struct util_dl_library *lib;52#endif53struct sw_winsys *ws;54int fd;55};5657#define pipe_loader_sw_device(dev) ((struct pipe_loader_sw_device *)dev)5859static const struct pipe_loader_ops pipe_loader_sw_ops;6061#ifdef GALLIUM_STATIC_TARGETS62static const struct sw_driver_descriptor driver_descriptors = {63.create_screen = sw_screen_create_vk,64.winsys = {65#ifdef HAVE_PIPE_LOADER_DRI66{67.name = "dri",68.create_winsys = dri_create_sw_winsys,69},70#endif71#ifdef HAVE_PIPE_LOADER_KMS72{73.name = "kms_dri",74.create_winsys = kms_dri_create_winsys,75},76#endif77#ifndef __ANDROID__78{79.name = "null",80.create_winsys = null_sw_create,81},82{83.name = "wrapped",84.create_winsys = wrapper_sw_winsys_wrap_pipe_screen,85},86#endif87{ 0 },88}89};90#endif9192static bool93pipe_loader_sw_probe_init_common(struct pipe_loader_sw_device *sdev)94{95sdev->base.type = PIPE_LOADER_DEVICE_SOFTWARE;96sdev->base.driver_name = "swrast";97sdev->base.ops = &pipe_loader_sw_ops;98sdev->fd = -1;99100#ifdef GALLIUM_STATIC_TARGETS101sdev->dd = &driver_descriptors;102if (!sdev->dd)103return false;104#else105const char *search_dir = getenv("GALLIUM_PIPE_SEARCH_DIR");106if (search_dir == NULL)107search_dir = PIPE_SEARCH_DIR;108109sdev->lib = pipe_loader_find_module("swrast", search_dir);110if (!sdev->lib)111return false;112113sdev->dd = (const struct sw_driver_descriptor *)114util_dl_get_proc_address(sdev->lib, "swrast_driver_descriptor");115116if (!sdev->dd){117util_dl_close(sdev->lib);118sdev->lib = NULL;119return false;120}121#endif122123return true;124}125126static void127pipe_loader_sw_probe_teardown_common(struct pipe_loader_sw_device *sdev)128{129#ifndef GALLIUM_STATIC_TARGETS130if (sdev->lib)131util_dl_close(sdev->lib);132#endif133}134135#ifdef HAVE_PIPE_LOADER_DRI136bool137pipe_loader_sw_probe_dri(struct pipe_loader_device **devs, const struct drisw_loader_funcs *drisw_lf)138{139struct pipe_loader_sw_device *sdev = CALLOC_STRUCT(pipe_loader_sw_device);140int i;141142if (!sdev)143return false;144145if (!pipe_loader_sw_probe_init_common(sdev))146goto fail;147148for (i = 0; sdev->dd->winsys[i].name; i++) {149if (strcmp(sdev->dd->winsys[i].name, "dri") == 0) {150sdev->ws = sdev->dd->winsys[i].create_winsys(drisw_lf);151break;152}153}154if (!sdev->ws)155goto fail;156157*devs = &sdev->base;158return true;159160fail:161pipe_loader_sw_probe_teardown_common(sdev);162FREE(sdev);163return false;164}165#endif166167#ifdef HAVE_PIPE_LOADER_KMS168bool169pipe_loader_sw_probe_kms(struct pipe_loader_device **devs, int fd)170{171struct pipe_loader_sw_device *sdev = CALLOC_STRUCT(pipe_loader_sw_device);172int i;173174if (!sdev)175return false;176177if (!pipe_loader_sw_probe_init_common(sdev))178goto fail;179180if (fd < 0 || (sdev->fd = os_dupfd_cloexec(fd)) < 0)181goto fail;182183for (i = 0; sdev->dd->winsys[i].name; i++) {184if (strcmp(sdev->dd->winsys[i].name, "kms_dri") == 0) {185sdev->ws = sdev->dd->winsys[i].create_winsys(sdev->fd);186break;187}188}189if (!sdev->ws)190goto fail;191192*devs = &sdev->base;193return true;194195fail:196pipe_loader_sw_probe_teardown_common(sdev);197if (sdev->fd != -1)198close(sdev->fd);199FREE(sdev);200return false;201}202#endif203204bool205pipe_loader_sw_probe_null(struct pipe_loader_device **devs)206{207struct pipe_loader_sw_device *sdev = CALLOC_STRUCT(pipe_loader_sw_device);208int i;209210if (!sdev)211return false;212213if (!pipe_loader_sw_probe_init_common(sdev))214goto fail;215216for (i = 0; sdev->dd->winsys[i].name; i++) {217if (strcmp(sdev->dd->winsys[i].name, "null") == 0) {218sdev->ws = sdev->dd->winsys[i].create_winsys();219break;220}221}222if (!sdev->ws)223goto fail;224225*devs = &sdev->base;226return true;227228fail:229pipe_loader_sw_probe_teardown_common(sdev);230FREE(sdev);231return false;232}233234int235pipe_loader_sw_probe(struct pipe_loader_device **devs, int ndev)236{237int i = 1;238239if (i <= ndev) {240if (!pipe_loader_sw_probe_null(devs)) {241i--;242}243}244245return i;246}247248boolean249pipe_loader_sw_probe_wrapped(struct pipe_loader_device **dev,250struct pipe_screen *screen)251{252struct pipe_loader_sw_device *sdev = CALLOC_STRUCT(pipe_loader_sw_device);253int i;254255if (!sdev)256return false;257258if (!pipe_loader_sw_probe_init_common(sdev))259goto fail;260261for (i = 0; sdev->dd->winsys[i].name; i++) {262if (strcmp(sdev->dd->winsys[i].name, "wrapped") == 0) {263sdev->ws = sdev->dd->winsys[i].create_winsys(screen);264break;265}266}267if (!sdev->ws)268goto fail;269270*dev = &sdev->base;271return true;272273fail:274pipe_loader_sw_probe_teardown_common(sdev);275FREE(sdev);276return false;277}278279static void280pipe_loader_sw_release(struct pipe_loader_device **dev)281{282UNUSED struct pipe_loader_sw_device *sdev =283pipe_loader_sw_device(*dev);284285#ifndef GALLIUM_STATIC_TARGETS286if (sdev->lib)287util_dl_close(sdev->lib);288#endif289290#ifdef HAVE_PIPE_LOADER_KMS291if (sdev->fd != -1)292close(sdev->fd);293#endif294295pipe_loader_base_release(dev);296}297298static const struct driOptionDescription *299pipe_loader_sw_get_driconf(struct pipe_loader_device *dev, unsigned *count)300{301*count = 0;302return NULL;303}304305static struct pipe_screen *306pipe_loader_sw_create_screen(struct pipe_loader_device *dev,307const struct pipe_screen_config *config, bool sw_vk)308{309struct pipe_loader_sw_device *sdev = pipe_loader_sw_device(dev);310struct pipe_screen *screen;311312screen = sdev->dd->create_screen(sdev->ws, sw_vk);313if (!screen)314sdev->ws->destroy(sdev->ws);315316return screen ? debug_screen_wrap(screen) : NULL;317}318319static const struct pipe_loader_ops pipe_loader_sw_ops = {320.create_screen = pipe_loader_sw_create_screen,321.get_driconf = pipe_loader_sw_get_driconf,322.release = pipe_loader_sw_release323};324325326