From 8c2e7fd8460750543367053b1be9368cc38e1d6a Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Fri, 10 Jan 2014 23:36:16 +0000 Subject: [PATCH] loader: introduce the loader util lib MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit All the various window system integration layers duplicate roughly the same code for figuring out device and driver name, pci-id's, etc. Which is sad. So extract it out into a loader util lib. v2 (Emil) * Separate the introduction of libloader from the code de-duplication. * Strip out non-pci devices support. * Add scons + Android build system support. * Add VISIBILITY_CFLAGS to avoid exporting the loader funcs. v3 (Emil) * PIPE_OS_ANDROID is undefined at this scope, use ANDROID * Make sure we define _EGL_NO_DRM when building only swrast Signed-off-by: Rob Clark Signed-off-by: Emil Velikov Reviewed-by: Rob Clark Reviewed-by: Kristian Høgsberg Reviewed-by: Ian Romanick --- Android.mk | 1 + configure.ac | 1 + include/pci_ids/pci_id_driver_map.h | 24 +- src/Makefile.am | 2 +- src/SConscript | 1 + src/egl/drivers/dri2/Android.mk | 1 + src/egl/drivers/dri2/Makefile.am | 1 + src/gallium/auxiliary/pipe-loader/Makefile.am | 1 + src/gallium/state_trackers/egl/Makefile.am | 1 + src/gallium/state_trackers/egl/SConscript | 1 + src/gallium/targets/egl-static/Android.mk | 1 + src/gallium/targets/egl-static/Makefile.am | 1 + src/gallium/targets/egl-static/SConscript | 1 + src/gbm/Makefile.am | 6 +- src/glx/Makefile.am | 1 + src/glx/SConscript | 1 + src/loader/Android.mk | 48 +++ src/loader/Makefile.am | 37 +++ src/loader/Makefile.sources | 2 + src/loader/SConscript | 28 ++ src/loader/loader.c | 304 ++++++++++++++++++ src/loader/loader.h | 57 ++++ 22 files changed, 506 insertions(+), 15 deletions(-) create mode 100644 src/loader/Android.mk create mode 100644 src/loader/Makefile.am create mode 100644 src/loader/Makefile.sources create mode 100644 src/loader/SConscript create mode 100644 src/loader/loader.c create mode 100644 src/loader/loader.h diff --git a/Android.mk b/Android.mk index c3c1f08f01d..05ed62f5941 100644 --- a/Android.mk +++ b/Android.mk @@ -78,6 +78,7 @@ endif ifneq ($(strip $(MESA_GPU_DRIVERS)),) SUBDIRS := \ + src/loader \ src/mapi \ src/glsl \ src/mesa \ diff --git a/configure.ac b/configure.ac index 4da6c51d36b..9ca6704a3e1 100644 --- a/configure.ac +++ b/configure.ac @@ -2059,6 +2059,7 @@ AC_CONFIG_FILES([Makefile src/glx/Makefile src/glx/tests/Makefile src/gtest/Makefile + src/loader/Makefile src/mapi/Makefile src/mapi/es1api/Makefile src/mapi/es1api/glesv1_cm.pc diff --git a/include/pci_ids/pci_id_driver_map.h b/include/pci_ids/pci_id_driver_map.h index 8a97c6f311f..2e88451e018 100644 --- a/include/pci_ids/pci_id_driver_map.h +++ b/include/pci_ids/pci_id_driver_map.h @@ -2,6 +2,7 @@ #define _PCI_ID_DRIVER_MAP_H_ #include +#include "loader.h" #ifndef ARRAY_SIZE #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) @@ -19,7 +20,6 @@ static const int i965_chip_ids[] = { #undef CHIPSET }; -#ifndef DRIVER_MAP_GALLIUM_ONLY static const int r100_chip_ids[] = { #define CHIPSET(chip, name, family) chip, #include "pci_ids/radeon_pci_ids.h" @@ -31,7 +31,6 @@ static const int r200_chip_ids[] = { #include "pci_ids/r200_pci_ids.h" #undef CHIPSET }; -#endif static const int r300_chip_ids[] = { #define CHIPSET(chip, name, family) chip, @@ -62,18 +61,17 @@ static const struct { const char *driver; const int *chip_ids; int num_chips_ids; + unsigned driver_types; } driver_map[] = { - { 0x8086, "i915", i915_chip_ids, ARRAY_SIZE(i915_chip_ids) }, - { 0x8086, "i965", i965_chip_ids, ARRAY_SIZE(i965_chip_ids) }, -#ifndef DRIVER_MAP_GALLIUM_ONLY - { 0x1002, "radeon", r100_chip_ids, ARRAY_SIZE(r100_chip_ids) }, - { 0x1002, "r200", r200_chip_ids, ARRAY_SIZE(r200_chip_ids) }, -#endif - { 0x1002, "r300", r300_chip_ids, ARRAY_SIZE(r300_chip_ids) }, - { 0x1002, "r600", r600_chip_ids, ARRAY_SIZE(r600_chip_ids) }, - { 0x1002, "radeonsi", radeonsi_chip_ids, ARRAY_SIZE(radeonsi_chip_ids) }, - { 0x10de, "nouveau", NULL, -1 }, - { 0x15ad, "vmwgfx", vmwgfx_chip_ids, ARRAY_SIZE(vmwgfx_chip_ids) }, + { 0x8086, "i915", i915_chip_ids, ARRAY_SIZE(i915_chip_ids), _LOADER_DRI | _LOADER_GALLIUM }, + { 0x8086, "i965", i965_chip_ids, ARRAY_SIZE(i965_chip_ids), _LOADER_DRI | _LOADER_GALLIUM }, + { 0x1002, "radeon", r100_chip_ids, ARRAY_SIZE(r100_chip_ids), _LOADER_DRI }, + { 0x1002, "r200", r200_chip_ids, ARRAY_SIZE(r200_chip_ids), _LOADER_DRI }, + { 0x1002, "r300", r300_chip_ids, ARRAY_SIZE(r300_chip_ids), _LOADER_GALLIUM }, + { 0x1002, "r600", r600_chip_ids, ARRAY_SIZE(r600_chip_ids), _LOADER_GALLIUM }, + { 0x1002, "radeonsi", radeonsi_chip_ids, ARRAY_SIZE(radeonsi_chip_ids), _LOADER_GALLIUM}, + { 0x10de, "nouveau", NULL, -1, _LOADER_GALLIUM }, + { 0x15ad, "vmwgfx", vmwgfx_chip_ids, ARRAY_SIZE(vmwgfx_chip_ids), _LOADER_GALLIUM }, { 0x0000, NULL, NULL, 0 }, }; diff --git a/src/Makefile.am b/src/Makefile.am index 76280a0c02e..5b2549d9d9e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,7 +19,7 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. -SUBDIRS = gtest mapi +SUBDIRS = gtest loader mapi if NEED_OPENGL_COMMON SUBDIRS += glsl mesa diff --git a/src/SConscript b/src/SConscript index a24aceaea1b..93a490dca86 100644 --- a/src/SConscript +++ b/src/SConscript @@ -11,6 +11,7 @@ if env['hostonly']: # compilation Return() +SConscript('loader/SConscript') # When env['gles'] is set, the targets defined in mapi/glapi/SConscript are not # used. libgl-xlib and libgl-gdi adapt themselves to use the targets defined diff --git a/src/egl/drivers/dri2/Android.mk b/src/egl/drivers/dri2/Android.mk index 090a0e157c1..4af8581f68b 100644 --- a/src/egl/drivers/dri2/Android.mk +++ b/src/egl/drivers/dri2/Android.mk @@ -39,6 +39,7 @@ LOCAL_CFLAGS := \ LOCAL_C_INCLUDES := \ $(MESA_TOP)/src/mapi \ $(MESA_TOP)/src/egl/main \ + $(MESA_TOP)/src/loader \ $(DRM_GRALLOC_TOP) \ $(DRM_TOP) \ $(DRM_TOP)/include/drm diff --git a/src/egl/drivers/dri2/Makefile.am b/src/egl/drivers/dri2/Makefile.am index 823ef5e369a..7e8ed788bdf 100644 --- a/src/egl/drivers/dri2/Makefile.am +++ b/src/egl/drivers/dri2/Makefile.am @@ -22,6 +22,7 @@ AM_CFLAGS = \ -I$(top_srcdir)/include \ -I$(top_srcdir)/src/egl/main \ + -I$(top_srcdir)/src/loader \ -I$(top_srcdir)/src/gbm/main \ -I$(top_srcdir)/src/gbm/backends/dri \ -I$(top_srcdir)/src/egl/wayland/wayland-egl \ diff --git a/src/gallium/auxiliary/pipe-loader/Makefile.am b/src/gallium/auxiliary/pipe-loader/Makefile.am index 9a8094fee7c..54034472ca0 100644 --- a/src/gallium/auxiliary/pipe-loader/Makefile.am +++ b/src/gallium/auxiliary/pipe-loader/Makefile.am @@ -3,6 +3,7 @@ AUTOMAKE_OPTIONS = subdir-objects AM_CPPFLAGS = $(DEFINES) \ $(GALLIUM_PIPE_LOADER_DEFINES) \ -I$(top_srcdir)/include \ + -I$(top_srcdir)/src/loader \ -I$(top_srcdir)/src/gallium/include \ -I$(top_srcdir)/src/gallium/auxiliary \ -I$(top_srcdir)/src/gallium/winsys diff --git a/src/gallium/state_trackers/egl/Makefile.am b/src/gallium/state_trackers/egl/Makefile.am index c069c29c8c9..459fabc8692 100644 --- a/src/gallium/state_trackers/egl/Makefile.am +++ b/src/gallium/state_trackers/egl/Makefile.am @@ -66,6 +66,7 @@ libegl_la_SOURCES += $(drm_FILES) AM_CFLAGS += \ $(LIBDRM_CFLAGS) AM_CPPFLAGS += \ + -I$(top_srcdir)/src/loader \ -I$(top_srcdir)/src/gallium/winsys \ -I$(top_srcdir)/src/gbm/main \ -I$(top_srcdir)/src/gallium/state_trackers/gbm \ diff --git a/src/gallium/state_trackers/egl/SConscript b/src/gallium/state_trackers/egl/SConscript index bd0ee02d202..2a5db64b999 100644 --- a/src/gallium/state_trackers/egl/SConscript +++ b/src/gallium/state_trackers/egl/SConscript @@ -33,6 +33,7 @@ else: # XXX: Disabled as it depends on gbm, which is not yet built with scons env.Append(CPPDEFINES = ['HAVE_DRM_BACKEND']) env.Append(CPPPATH = [ + '#/src/loader', '#/src/gbm/main', '#/src/gallium/state_trackers/gbm', ]) diff --git a/src/gallium/targets/egl-static/Android.mk b/src/gallium/targets/egl-static/Android.mk index 06975dbd5d9..88df6d12205 100644 --- a/src/gallium/targets/egl-static/Android.mk +++ b/src/gallium/targets/egl-static/Android.mk @@ -39,6 +39,7 @@ LOCAL_C_INCLUDES := \ $(GALLIUM_TOP)/state_trackers/vega \ $(GALLIUM_TOP)/state_trackers/egl \ $(MESA_TOP)/src/egl/main \ + $(MESA_TOP)/src/loader \ $(MESA_TOP)/src/mesa # swrast diff --git a/src/gallium/targets/egl-static/Makefile.am b/src/gallium/targets/egl-static/Makefile.am index fdd5a1d067a..ebffd0ecfbb 100644 --- a/src/gallium/targets/egl-static/Makefile.am +++ b/src/gallium/targets/egl-static/Makefile.am @@ -36,6 +36,7 @@ AM_CFLAGS = $(PTHREAD_CFLAGS) AM_CPPFLAGS = \ $(GALLIUM_CFLAGS) \ -I$(top_srcdir)/include \ + -I$(top_srcdir)/src/loader \ -I$(top_srcdir)/src/gallium/drivers \ -I$(top_srcdir)/src/gallium/winsys \ -I$(top_srcdir)/src/gallium/include \ diff --git a/src/gallium/targets/egl-static/SConscript b/src/gallium/targets/egl-static/SConscript index b4ccc5b805a..56e12e838f5 100644 --- a/src/gallium/targets/egl-static/SConscript +++ b/src/gallium/targets/egl-static/SConscript @@ -7,6 +7,7 @@ env = env.Clone() env.Append(CPPPATH = [ '#/include', + '#/src/loader', '#/src/egl/main', '#/src/gallium/auxiliary', '#/src/gallium/drivers', diff --git a/src/gbm/Makefile.am b/src/gbm/Makefile.am index 9b3fb0d90cd..5ae7a682474 100644 --- a/src/gbm/Makefile.am +++ b/src/gbm/Makefile.am @@ -7,6 +7,7 @@ AM_CFLAGS = \ -D_OS_UNIX=1 \ -DMODULEDIR='"$(libdir)/gbm"' \ -I$(top_srcdir)/include \ + -I$(top_srcdir)/src/loader \ -I$(top_srcdir)/src/gbm/main \ $(LIBUDEV_CFLAGS) \ $(LIBKMS_CFLAGS) \ @@ -21,7 +22,10 @@ libgbm_la_SOURCES = \ main/backend.c \ main/common.c libgbm_la_LDFLAGS = -version-info 1:0 -libgbm_la_LIBADD = $(LIBUDEV_LIBS) $(LIBKMS_LIBS) $(DLOPEN_LIBS) +libgbm_la_LIBADD = \ + $(LIBUDEV_LIBS) \ + $(LIBKMS_LIBS) \ + $(DLOPEN_LIBS) if HAVE_EGL_PLATFORM_WAYLAND AM_CPPFLAGS = -DHAVE_WAYLAND_PLATFORM diff --git a/src/glx/Makefile.am b/src/glx/Makefile.am index 0aec2aa3daa..6d81471b63f 100644 --- a/src/glx/Makefile.am +++ b/src/glx/Makefile.am @@ -35,6 +35,7 @@ endif AM_CFLAGS = \ -I$(top_srcdir)/include \ -I$(top_srcdir)/include/GL/internal \ + -I$(top_srcdir)/src/loader \ -I$(top_srcdir)/src/mapi \ -I$(top_srcdir)/src/mapi/glapi \ -I$(top_builddir)/src/mapi \ diff --git a/src/glx/SConscript b/src/glx/SConscript index 890f9983efd..309a648cc56 100644 --- a/src/glx/SConscript +++ b/src/glx/SConscript @@ -11,6 +11,7 @@ env.Prepend(CPPPATH = [ '.', # the build//glx/ directory '#include', '#include/GL/internal', + '#src/loader', '#src/mesa', '#src/mapi', '#src/mapi/glapi', diff --git a/src/loader/Android.mk b/src/loader/Android.mk new file mode 100644 index 00000000000..01699dcc533 --- /dev/null +++ b/src/loader/Android.mk @@ -0,0 +1,48 @@ +# Mesa 3-D graphics library +# +# Copyright (C) 2014 Emil Velikov +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. + +LOCAL_PATH := $(call my-dir) + +include $(LOCAL_PATH)/Makefile.sources + +# --------------------------------------- +# Build libloader +# --------------------------------------- + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + $(LOADER_C_FILES) + +# swrast only +ifeq ($(MESA_GPU_DRIVERS),swrast) + LOCAL_CFLAGS += -D_EGL_NO_DRM +else +LOCAL_C_INCLUDES += \ + $(DRM_TOP)/include/drm \ + $(DRM_TOP) +endif + +LOCAL_MODULE := libloader + +include $(MESA_COMMON_MK) +include $(BUILD_STATIC_LIBRARY) diff --git a/src/loader/Makefile.am b/src/loader/Makefile.am new file mode 100644 index 00000000000..a118fef1d9c --- /dev/null +++ b/src/loader/Makefile.am @@ -0,0 +1,37 @@ +# Copyright © 2012 Intel Corporation +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. + +include Makefile.sources + +noinst_LTLIBRARIES = libloader.la + +libloader_la_CPPFLAGS = \ + $(DEFINES) \ + -I$(top_srcdir)/include \ + $(VISIBILITY_CFLAGS) \ + $(LIBDRM_CFLAGS) \ + $(LIBUDEV_CFLAGS) + +libloader_la_LIBADD = \ + $(LIBDRM_LIBS) \ + $(LIBUDEV_LIBS) + +libloader_la_SOURCES = $(LOADER_C_FILES) diff --git a/src/loader/Makefile.sources b/src/loader/Makefile.sources new file mode 100644 index 00000000000..51a64ea6ac2 --- /dev/null +++ b/src/loader/Makefile.sources @@ -0,0 +1,2 @@ +LOADER_C_FILES := \ + loader.c \ No newline at end of file diff --git a/src/loader/SConscript b/src/loader/SConscript new file mode 100644 index 00000000000..454e3284491 --- /dev/null +++ b/src/loader/SConscript @@ -0,0 +1,28 @@ +Import('*') + +if not env['drm']: + Return() + +env = env.Clone() + +env.Prepend(CPPPATH = [ + '.', + '#include' +]) + +env.PkgUseModules('DRM') + +if env['udev']: + env.PkgUseModules('UDEV') + env.Append(CPPDEFINES = ['HAVE_LIBUDEV']) + +# parse Makefile.sources +sources = env.ParseSourceList('Makefile.sources', 'LOADER_C_FILES') + +libloader = env.ConvenienceLibrary( + target = 'libloader', + source = sources, +) + +env.Alias('libloader', libloader) +Export('libloader') diff --git a/src/loader/loader.c b/src/loader/loader.c new file mode 100644 index 00000000000..2f9cfa7c9f9 --- /dev/null +++ b/src/loader/loader.c @@ -0,0 +1,304 @@ +/* + * Copyright (C) 2013 Rob Clark + * + * This code is derived from the following files. + * + * * src/glx/dri3_common.c + * Copyright © 2013 Keith Packard + * + * * src/egl/drivers/dri2/common.c + * * src/gbm/backends/dri/driver_name.c + * Copyright © 2011 Intel Corporation + * + * Authors: + * Kristian Høgsberg + * Benjamin Franzke + * + * * src/gallium/targets/egl-static/egl.c + * Copyright (C) 2010-2011 LunarG Inc. + * + * Authors: + * Chia-I Wu + * + * * src/gallium/state_trackers/egl/drm/native_drm.c + * Copyright (C) 2010 Chia-I Wu + * + * * src/egl/drivers/dri2/platform_android.c + * + * Copyright (C) 2010-2011 Chia-I Wu + * Copyright (C) 2010-2011 LunarG Inc. + * + * Based on platform_x11, which has + * + * Copyright © 2011 Intel Corporation + * + * * src/gallium/auxiliary/pipe-loader/pipe_loader_drm.c + * Copyright 2011 Intel Corporation + * Copyright 2012 Francisco Jerez + * All Rights Reserved. + * + * Authors: + * Kristian Høgsberg + * Benjamin Franzke + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Authors: + * Rob Clark + */ + +#include +#include +#include +#include "loader.h" + +#include + +#define __IS_LOADER +#include "pci_ids/pci_id_driver_map.h" + +static void default_logger(int level, const char *fmt, ...) +{ + if (level >= _LOADER_WARNING) { + va_list args; + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + fprintf(stderr, "\n"); + } +} + +static void (*log)(int level, const char *fmt, ...) = default_logger; + +#ifdef HAVE_LIBUDEV +#include + +static inline struct udev_device * +udev_device_new_from_fd(struct udev *udev, int fd) +{ + struct udev_device *device; + struct stat buf; + + if (fstat(fd, &buf) < 0) { + log(_LOADER_WARNING, "MESA-LOADER: failed to stat fd %d", fd); + return NULL; + } + + device = udev_device_new_from_devnum(udev, 'c', buf.st_rdev); + if (device == NULL) { + log(_LOADER_WARNING, + "MESA-LOADER: could not create udev device for fd %d", fd); + return NULL; + } + + return device; +} + +int +loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id) +{ + struct udev *udev = NULL; + struct udev_device *device = NULL, *parent; + struct stat buf; + const char *pci_id; + + *chip_id = -1; + + udev = udev_new(); + device = udev_device_new_from_fd(udev, fd); + if (!device) + goto out; + + parent = udev_device_get_parent(device); + if (parent == NULL) { + log(_LOADER_WARNING, "MESA-LOADER: could not get parent device"); + goto out; + } + + pci_id = udev_device_get_property_value(parent, "PCI_ID"); + if (pci_id == NULL || + sscanf(pci_id, "%x:%x", vendor_id, chip_id) != 2) { + log(_LOADER_WARNING, "MESA-LOADER: malformed or no PCI ID"); + *chip_id = -1; + goto out; + } + +out: + if (device) + udev_device_unref(device); + if (udev) + udev_unref(udev); + + return (*chip_id >= 0); +} + +#elif defined(ANDROID) && !defined(_EGL_NO_DRM) + +/* for i915 */ +#include +/* for radeon */ +#include + +int +loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id) +{ + drmVersionPtr version; + + *chip_id = -1; + + version = drmGetVersion(fd); + if (!version) { + log(_LOADER_WARNING, "MESA-LOADER: invalid drm fd"); + return FALSE; + } + if (!version->name) { + log(_LOADER_WARNING, "MESA-LOADER: unable to determine the driver name"); + drmFreeVersion(version); + return FALSE; + } + + if (strcmp(version->name, "i915") == 0) { + struct drm_i915_getparam gp; + int ret; + + *vendor_id = 0x8086; + + memset(&gp, 0, sizeof(gp)); + gp.param = I915_PARAM_CHIPSET_ID; + gp.value = chip_id; + ret = drmCommandWriteRead(fd, DRM_I915_GETPARAM, &gp, sizeof(gp)); + if (ret) { + log(_LOADER_WARNING, "MESA-LOADER: failed to get param for i915"); + *chip_id = -1; + } + } + else if (strcmp(version->name, "radeon") == 0) { + struct drm_radeon_info info; + int ret; + + *vendor_id = 0x1002; + + memset(&info, 0, sizeof(info)); + info.request = RADEON_INFO_DEVICE_ID; + info.value = (unsigned long) chip_id; + ret = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)); + if (ret) { + log(_LOADER_WARNING, "MESA-LOADER: failed to get info for radeon"); + *chip_id = -1; + } + } + else if (strcmp(version->name, "nouveau") == 0) { + *vendor_id = 0x10de; + /* not used */ + *chip_id = 0; + } + else if (strcmp(version->name, "vmwgfx") == 0) { + *vendor_id = 0x15ad; + /* assume SVGA II */ + *chip_id = 0x0405; + } + + drmFreeVersion(version); + + return (*chip_id >= 0); +} + +#else + +int +loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id) +{ + return 0; +} + +#endif + + +char * +loader_get_device_name_for_fd(int fd) +{ + char *device_name = NULL; +#ifdef HAVE_LIBUDEV + struct udev *udev; + struct udev_device *device; + const char *const_device_name; + + udev = udev_new(); + device = udev_device_new_from_fd(udev, fd); + if (device == NULL) + return NULL; + + const_device_name = udev_device_get_devnode(device); + if (!const_device_name) + goto out; + device_name = strdup(const_device_name); + +out: + udev_device_unref(device); + udev_unref(udev); +#endif + return device_name; +} + +char * +loader_get_driver_for_fd(int fd, unsigned driver_types) +{ + int vendor_id, chip_id, i, j; + char *driver = NULL; + + if (!driver_types) + driver_types = _LOADER_GALLIUM | _LOADER_DRI; + + if (!loader_get_pci_id_for_fd(fd, &vendor_id, &chip_id)) { + log(_LOADER_WARNING, "failed to get driver name for fd %d", fd); + return NULL; + } + + for (i = 0; driver_map[i].driver; i++) { + if (vendor_id != driver_map[i].vendor_id) + continue; + + if (!(driver_types & driver_map[i].driver_types)) + continue; + + if (driver_map[i].num_chips_ids == -1) { + driver = strdup(driver_map[i].driver); + goto out; + } + + for (j = 0; j < driver_map[i].num_chips_ids; j++) + if (driver_map[i].chip_ids[j] == chip_id) { + driver = strdup(driver_map[i].driver); + goto out; + } + } + +out: + log(driver ? _LOADER_INFO : _LOADER_WARNING, + "pci id for fd %d: %04x:%04x, driver %s", + fd, vendor_id, chip_id, driver); + return driver; +} + +void +loader_set_logger(void (*logger)(int level, const char *fmt, ...)) +{ + log = logger; +} diff --git a/src/loader/loader.h b/src/loader/loader.h new file mode 100644 index 00000000000..dfd77baad0e --- /dev/null +++ b/src/loader/loader.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2013 Rob Clark + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Authors: + * Rob Clark + */ + +#ifndef LOADER_H +#define LOADER_H + +/* Helpers to figure out driver and device name, eg. from pci-id, etc. */ + +#define _LOADER_DRI (1 << 0) +#define _LOADER_GALLIUM (1 << 1) + +int +loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id); + +char * +loader_get_driver_for_fd(int fd, unsigned driver_types); + +char * +loader_get_device_name_for_fd(int fd); + + +/* for logging.. keep this aligned with egllog.h so we can just use + * _eglLog directly. + */ + +#define _LOADER_FATAL 0 /* unrecoverable error */ +#define _LOADER_WARNING 1 /* recoverable error/problem */ +#define _LOADER_INFO 2 /* just useful info */ +#define _LOADER_DEBUG 3 /* useful info for debugging */ + +void +loader_set_logger(void (*logger)(int level, const char *fmt, ...)); + +#endif /* LOADER_H */ -- 2.30.2