mirror of
https://gitee.com/openharmony/third_party_mesa3d
synced 2024-11-23 07:19:50 +00:00
commit
fc4325e87a
129
include/ohos_log.h
Normal file
129
include/ohos_log.h
Normal file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef DISP_COMMON_H
|
||||
#define DISP_COMMON_H
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include "hilog/log.h"
|
||||
#ifdef HDF_LOG_TAG
|
||||
#undef HDF_LOG_TAG
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define FENCE_TIMEOUT 3000
|
||||
|
||||
#undef LOG_TAG
|
||||
#undef LOG_DOMAIN
|
||||
#define LOG_TAG "DISP"
|
||||
#define LOG_DOMAIN 0xD001400
|
||||
|
||||
#ifndef DISPLAY_UNUSED
|
||||
#define DISPLAY_UNUSED(x) ((void)(x))
|
||||
#endif
|
||||
|
||||
#define DISP_FILENAME (strrchr(__FILE__, '/') ? (strrchr(__FILE__, '/') + 1) : __FILE__)
|
||||
|
||||
#ifndef DISPLAY_DEBUG_ENABLE
|
||||
#define DISPLAY_DEBUG_ENABLE 1
|
||||
#endif
|
||||
|
||||
#ifndef DISPLAY_LOGD
|
||||
#define DISPLAY_LOGD(format, ...) \
|
||||
do { \
|
||||
if (DISPLAY_DEBUG_ENABLE) { \
|
||||
HILOG_DEBUG(LOG_CORE, "[%{public}s@%{public}s:%{public}d] " format "\n", \
|
||||
__FUNCTION__, DISP_FILENAME, __LINE__, \
|
||||
##__VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef DISPLAY_LOGI
|
||||
#define DISPLAY_LOGI(format, ...) \
|
||||
do { \
|
||||
HILOG_INFO(LOG_CORE, "[%{public}s@%{public}s:%{public}d] " format "\n", __FUNCTION__, DISP_FILENAME, __LINE__, \
|
||||
##__VA_ARGS__); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef DISPLAY_LOGW
|
||||
#define DISPLAY_LOGW(format, ...) \
|
||||
do { \
|
||||
HILOG_WARN(LOG_CORE, "[%{public}s@%{public}s:%{public}d] " format "\n", __FUNCTION__, DISP_FILENAME, __LINE__, \
|
||||
##__VA_ARGS__); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef DISPLAY_LOGE
|
||||
#define DISPLAY_LOGE(format, ...) \
|
||||
do { \
|
||||
HILOG_ERROR(LOG_CORE, \
|
||||
"\033[0;32;31m" \
|
||||
"[%{public}s@%{public}s:%{public}d] " format "\033[m" \
|
||||
"\n", \
|
||||
__FUNCTION__, DISP_FILENAME, __LINE__, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef CHECK_NULLPOINTER_RETURN_VALUE
|
||||
#define CHECK_NULLPOINTER_RETURN_VALUE(pointer, ret) \
|
||||
do { \
|
||||
if ((pointer) == NULL) { \
|
||||
DISPLAY_LOGE("pointer is null and return ret\n"); \
|
||||
return (ret); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef CHECK_NULLPOINTER_RETURN
|
||||
#define CHECK_NULLPOINTER_RETURN(pointer) \
|
||||
do { \
|
||||
if ((pointer) == NULL) { \
|
||||
DISPLAY_LOGE("pointer is null and return\n"); \
|
||||
return; \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef DISPLAY_CHK_RETURN
|
||||
#define DISPLAY_CHK_RETURN(val, ret, ...) \
|
||||
do { \
|
||||
if (val) { \
|
||||
__VA_ARGS__; \
|
||||
return (ret); \
|
||||
} \
|
||||
} while (0)extern "C" {
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef DISPLAY_CHK_RETURN_NOT_VALUE
|
||||
#define DISPLAY_CHK_RETURN_NOT_VALUE(val, ...) \
|
||||
do { \
|
||||
if (val) { \
|
||||
__VA_ARGS__; \
|
||||
return; \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DISP_COMMON_H */
|
@ -964,6 +964,7 @@ if with_platform_ohos
|
||||
pre_args += '-DHAVE_OHOS_PLATFORM'
|
||||
dep_ohos = [
|
||||
dependency('libsurface'),
|
||||
dependency('libhilog'),
|
||||
]
|
||||
c_args += '-I../ohos'
|
||||
endif
|
||||
@ -1607,6 +1608,10 @@ foreach d : _libdrm_checks
|
||||
endif
|
||||
endforeach
|
||||
|
||||
dep_hilog = dependency(
|
||||
'libhilog'
|
||||
)
|
||||
|
||||
with_gallium_drisw_kms = false
|
||||
dep_libdrm = dependency(
|
||||
'libdrm', version : '>=' + _drm_ver,
|
||||
|
105
ohos/BUILD.gn
105
ohos/BUILD.gn
@ -10,6 +10,8 @@
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
|
||||
import("//build/config/clang/clang.gni")
|
||||
|
||||
# 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
|
||||
@ -18,52 +20,89 @@
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
import("//build/ohos.gni")
|
||||
import("//build/config/clang/clang.gni")
|
||||
import("dependency_inputs.gni")
|
||||
mesa3d_libs_dir = "$root_build_dir/packages/phone/mesa3d"
|
||||
|
||||
mesa3d_gallium_symlinks = ["panfrost_dri.so"]
|
||||
mesa3d_gallium_symlinks = [ "panfrost_dri.so" ]
|
||||
|
||||
mesa3d_all_lib_items = [
|
||||
["libEGL.so.1.0.0", ["libEGL.so", "libEGL.so.1"]],
|
||||
["libgbm.so.1.0.0", ["libgbm.so", "libgbm.so.1"]],
|
||||
["libglapi.so.0.0.0", ["libglapi.so", "libglapi.so.0"]],
|
||||
["libGLESv1_CM.so.1.1.0", ["libGLESv1_CM.so", "libGLESv1_CM.so.1"]],
|
||||
["libGLESv2.so.2.0.0", ["libGLESv2.so", "libGLESv2.so.2", "libGLESv3.so"]],
|
||||
["libgallium_dri.so", mesa3d_gallium_symlinks]
|
||||
[
|
||||
"libEGL.so.1.0.0",
|
||||
[
|
||||
"libEGL.so",
|
||||
"libEGL.so.1",
|
||||
"libEGL_impl.so",
|
||||
],
|
||||
],
|
||||
[
|
||||
"libgbm.so.1.0.0",
|
||||
[
|
||||
"libgbm.so",
|
||||
"libgbm.so.1",
|
||||
],
|
||||
],
|
||||
[
|
||||
"libglapi.so.0.0.0",
|
||||
[
|
||||
"libglapi.so",
|
||||
"libglapi.so.0",
|
||||
],
|
||||
],
|
||||
[
|
||||
"libGLESv1_CM.so.1.1.0",
|
||||
[
|
||||
"libGLESv1_CM.so",
|
||||
"libGLESv1_CM.so.1",
|
||||
"libGLESv1_impl.so",
|
||||
],
|
||||
],
|
||||
[
|
||||
"libGLESv2.so.2.0.0",
|
||||
[
|
||||
"libGLESv2.so",
|
||||
"libGLESv2.so.2",
|
||||
"libGLESv3.so",
|
||||
"libGLESv2_impl.so",
|
||||
"libGLESv3_impl.so",
|
||||
],
|
||||
],
|
||||
[
|
||||
"libgallium_dri.so",
|
||||
mesa3d_gallium_symlinks,
|
||||
],
|
||||
]
|
||||
|
||||
action("mesa3d_build") {
|
||||
inputs = deps_inputs
|
||||
script = "build_mesa3d.py"
|
||||
deps = [
|
||||
"//foundation/graphic/graphic_2d:libsurface",
|
||||
"//third_party/expat:expat",
|
||||
]
|
||||
outputs = []
|
||||
foreach(item, mesa3d_all_lib_items) {
|
||||
name = item[0]
|
||||
outputs += [ "$mesa3d_libs_dir/$name" ]
|
||||
}
|
||||
args = [ rebase_path(root_build_dir) ]
|
||||
inputs = deps_inputs
|
||||
script = "build_mesa3d.py"
|
||||
deps = [
|
||||
"//foundation/graphic/graphic_2d:libsurface",
|
||||
"//third_party/expat:expat",
|
||||
]
|
||||
outputs = []
|
||||
foreach(item, mesa3d_all_lib_items) {
|
||||
name = item[0]
|
||||
outputs += [ "$mesa3d_libs_dir/$name" ]
|
||||
}
|
||||
args = [ rebase_path(root_build_dir) ]
|
||||
}
|
||||
|
||||
mesa3d_all_lib_deps = []
|
||||
|
||||
foreach(item, mesa3d_all_lib_items) {
|
||||
name = item[0]
|
||||
ohos_prebuilt_shared_library(name) {
|
||||
source = "$mesa3d_libs_dir/$name"
|
||||
deps = [ ":mesa3d_build" ]
|
||||
symlink_target_name = item[1]
|
||||
install_enable = true
|
||||
install_images = [ system_base_dir ]
|
||||
subsystem_name = "rockchip_products"
|
||||
part_name = "rockchip_products"
|
||||
}
|
||||
mesa3d_all_lib_deps += [ ":$name" ]
|
||||
name = item[0]
|
||||
ohos_prebuilt_shared_library(name) {
|
||||
source = "$mesa3d_libs_dir/$name"
|
||||
deps = [ ":mesa3d_build" ]
|
||||
symlink_target_name = item[1]
|
||||
install_enable = true
|
||||
install_images = [ system_base_dir ]
|
||||
subsystem_name = "rockchip_products"
|
||||
part_name = "rockchip_products"
|
||||
}
|
||||
mesa3d_all_lib_deps += [ ":$name" ]
|
||||
}
|
||||
|
||||
group("mesa3d_all_libs"){
|
||||
deps = mesa3d_all_lib_deps
|
||||
group("mesa3d_all_libs") {
|
||||
deps = mesa3d_all_lib_deps
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
ohos_project_dir=ohos_project_directory_stub
|
||||
libdir=${ohos_project_dir}/out/ohos-arm-release/graphic/graphic_standard/
|
||||
libdir=${ohos_project_dir}/out/ohos-arm-release/thirdparty/libdrm/
|
||||
includedir=${ohos_project_dir}/third_party/libdrm
|
||||
|
||||
Name: libdrm
|
||||
|
@ -1,8 +1,9 @@
|
||||
ohos_project_dir=ohos_project_directory_stub
|
||||
libdir=${ohos_project_dir}/out/ohos-arm-release/hiviewdfx/hilog_native
|
||||
includedir=${ohos_project_dir}/foundation/graphic/standard/rosen/include/backstore/nativewindow
|
||||
includedir=${ohos_project_dir}/base/hiviewdfx/hilog/interfaces/native/innerkits/include
|
||||
|
||||
Name: libhilog
|
||||
Version: 2.4.1
|
||||
Description: libhilog
|
||||
Libs: -L${libdir} -lhilog
|
||||
Cflags: -I${includedir}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -27,14 +27,12 @@
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
/**
|
||||
* Logging facility for debug/info messages.
|
||||
* _EGL_FATAL messages are printed to stderr
|
||||
* The EGL_LOG_LEVEL var controls the output of other warning/info/debug msgs.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -55,29 +53,32 @@
|
||||
|
||||
#endif /* HAVE_ANDROID_PLATFORM */
|
||||
|
||||
#ifdef HAVE_OHOS_PLATFORM
|
||||
#include "hilog/log.h"
|
||||
#include "ohos_log.h"
|
||||
#endif
|
||||
|
||||
#define MAXSTRING 1000
|
||||
#define FALLBACK_LOG_LEVEL _EGL_WARNING
|
||||
|
||||
|
||||
static struct {
|
||||
mtx_t mutex;
|
||||
mtx_t mutex;
|
||||
|
||||
EGLBoolean initialized;
|
||||
EGLint level;
|
||||
EGLBoolean initialized;
|
||||
EGLint level;
|
||||
} logging = {
|
||||
.mutex = _MTX_INITIALIZER_NP,
|
||||
.initialized = EGL_FALSE,
|
||||
.level = FALLBACK_LOG_LEVEL,
|
||||
.mutex = _MTX_INITIALIZER_NP,
|
||||
.initialized = EGL_FALSE,
|
||||
.level = FALLBACK_LOG_LEVEL,
|
||||
};
|
||||
|
||||
static const char *level_strings[] = {
|
||||
[_EGL_FATAL] = "fatal",
|
||||
[_EGL_WARNING] = "warning",
|
||||
[_EGL_INFO] = "info",
|
||||
[_EGL_DEBUG] = "debug",
|
||||
[_EGL_FATAL] = "fatal",
|
||||
[_EGL_WARNING] = "warning",
|
||||
[_EGL_INFO] = "info",
|
||||
[_EGL_DEBUG] = "debug",
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The default logger. It prints the message to stderr.
|
||||
*/
|
||||
@ -85,85 +86,83 @@ static void
|
||||
_eglDefaultLogger(EGLint level, const char *msg)
|
||||
{
|
||||
#ifdef HAVE_ANDROID_PLATFORM
|
||||
static const int egl2alog[] = {
|
||||
[_EGL_FATAL] = ANDROID_LOG_ERROR,
|
||||
[_EGL_WARNING] = ANDROID_LOG_WARN,
|
||||
[_EGL_INFO] = ANDROID_LOG_INFO,
|
||||
[_EGL_DEBUG] = ANDROID_LOG_DEBUG,
|
||||
};
|
||||
LOG_PRI(egl2alog[level], LOG_TAG, "%s", msg);
|
||||
static const int egl2alog[] = {
|
||||
[_EGL_FATAL] = ANDROID_LOG_ERROR,
|
||||
[_EGL_WARNING] = ANDROID_LOG_WARN,
|
||||
[_EGL_INFO] = ANDROID_LOG_INFO,
|
||||
[_EGL_DEBUG] = ANDROID_LOG_DEBUG,
|
||||
};
|
||||
LOG_PRI(egl2alog[level], LOG_TAG, "%s", msg);
|
||||
#else
|
||||
fprintf(stderr, "libEGL %s: %s\n", level_strings[level], msg);
|
||||
fprintf(stderr, "libEGL %s: %s\n", level_strings[level], msg);
|
||||
DISPLAY_LOGE("libEGL %{public}s: %{public}s\n", level_strings[level], msg);
|
||||
#endif /* HAVE_ANDROID_PLATFORM */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the logging facility.
|
||||
*/
|
||||
static void
|
||||
_eglInitLogger(void)
|
||||
{
|
||||
const char *log_env;
|
||||
EGLint i, level = -1;
|
||||
const char *log_env;
|
||||
EGLint i, level = -1;
|
||||
|
||||
if (logging.initialized)
|
||||
return;
|
||||
if (logging.initialized)
|
||||
return;
|
||||
|
||||
log_env = getenv("EGL_LOG_LEVEL");
|
||||
if (log_env) {
|
||||
for (i = 0; i < ARRAY_SIZE(level_strings); i++) {
|
||||
if (strcasecmp(log_env, level_strings[i]) == 0) {
|
||||
level = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
log_env = getenv("EGL_LOG_LEVEL");
|
||||
if (log_env) {
|
||||
for (i = 0; i < ARRAY_SIZE(level_strings); i++) {
|
||||
if (strcasecmp(log_env, level_strings[i]) == 0) {
|
||||
level = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logging.level = (level >= 0) ? level : FALLBACK_LOG_LEVEL;
|
||||
logging.initialized = EGL_TRUE;
|
||||
logging.level = (level >= 0) ? level : FALLBACK_LOG_LEVEL;
|
||||
logging.initialized = EGL_TRUE;
|
||||
|
||||
/* it is fine to call _eglLog now */
|
||||
if (log_env && level < 0) {
|
||||
_eglLog(_EGL_WARNING,
|
||||
"Unrecognized EGL_LOG_LEVEL environment variable value. "
|
||||
"Expected one of \"fatal\", \"warning\", \"info\", \"debug\". "
|
||||
"Got \"%s\". Falling back to \"%s\".",
|
||||
log_env, level_strings[FALLBACK_LOG_LEVEL]);
|
||||
}
|
||||
/* it is fine to call _eglLog now */
|
||||
if (log_env && level < 0) {
|
||||
_eglLog(_EGL_WARNING,
|
||||
"Unrecognized EGL_LOG_LEVEL environment variable value. "
|
||||
"Expected one of \"fatal\", \"warning\", \"info\", \"debug\". "
|
||||
"Got \"%s\". Falling back to \"%s\".",
|
||||
log_env, level_strings[FALLBACK_LOG_LEVEL]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Log a message with message logger.
|
||||
* \param level one of _EGL_FATAL, _EGL_WARNING, _EGL_INFO, _EGL_DEBUG.
|
||||
*/
|
||||
void
|
||||
_eglLog(EGLint level, const char *fmtStr, ...)
|
||||
void _eglLog(EGLint level, const char *fmtStr, ...)
|
||||
{
|
||||
va_list args;
|
||||
char msg[MAXSTRING];
|
||||
int ret;
|
||||
va_list args;
|
||||
char msg[MAXSTRING];
|
||||
int ret;
|
||||
DISPLAY_LOGD();
|
||||
/* one-time initialization; a little race here is fine */
|
||||
/*
|
||||
if (!logging.initialized)
|
||||
_eglInitLogger();
|
||||
if (level > logging.level || level < 0)
|
||||
return;
|
||||
*/
|
||||
mtx_lock(&logging.mutex);
|
||||
|
||||
/* one-time initialization; a little race here is fine */
|
||||
/*
|
||||
if (!logging.initialized)
|
||||
_eglInitLogger();
|
||||
if (level > logging.level || level < 0)
|
||||
return;
|
||||
*/
|
||||
mtx_lock(&logging.mutex);
|
||||
va_start(args, fmtStr);
|
||||
ret = vsnprintf(msg, MAXSTRING, fmtStr, args);
|
||||
if (ret < 0 || ret >= MAXSTRING)
|
||||
strcpy(msg, "<message truncated>");
|
||||
va_end(args);
|
||||
|
||||
va_start(args, fmtStr);
|
||||
ret = vsnprintf(msg, MAXSTRING, fmtStr, args);
|
||||
if (ret < 0 || ret >= MAXSTRING)
|
||||
strcpy(msg, "<message truncated>");
|
||||
va_end(args);
|
||||
_eglDefaultLogger(level, msg);
|
||||
|
||||
_eglDefaultLogger(level, msg);
|
||||
mtx_unlock(&logging.mutex);
|
||||
|
||||
mtx_unlock(&logging.mutex);
|
||||
|
||||
if (level == _EGL_FATAL)
|
||||
exit(1); /* or abort()? */
|
||||
if (level == _EGL_FATAL)
|
||||
exit(1); /* or abort()? */
|
||||
}
|
||||
|
@ -67,318 +67,372 @@
|
||||
#define PATH_MAX 4096
|
||||
#endif
|
||||
|
||||
#include "ohos_log.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);
|
||||
}
|
||||
const int MAX_BUFFER_LEN = 1024;
|
||||
char log_string[MAX_BUFFER_LEN];
|
||||
if (level <= _LOADER_WARNING) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vfprintf(stderr, fmt, args);
|
||||
sprintf_s(log_string, MAX_BUFFER_LEN, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
DISPLAY_LOGI();
|
||||
}
|
||||
|
||||
static loader_logger *log_ = default_logger;
|
||||
|
||||
int
|
||||
loader_open_device(const char *device_name)
|
||||
static void ohos_logger(int level, const char *fmt, ...)
|
||||
{
|
||||
int fd;
|
||||
const int MAX_BUFFER_LEN = 1024;
|
||||
char log_string[MAX_BUFFER_LEN];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
(void)sprintf_s(log_string, MAX_BUFFER_LEN, fmt, args);
|
||||
va_end(args);
|
||||
switch (level) {
|
||||
case _LOADER_WARNING:
|
||||
DISPLAY_LOGW("%{public}s", log_string);
|
||||
break;
|
||||
case _LOADER_DEBUG:
|
||||
DISPLAY_LOGD("%{public}s", log_string);
|
||||
break;
|
||||
case _LOADER_FATAL:
|
||||
DISPLAY_LOGE("%{public}s", log_string);
|
||||
break;
|
||||
case _LOADER_INFO:
|
||||
DISPLAY_LOGI("%{public}s", log_string);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
DISPLAY_LOGI();
|
||||
}
|
||||
|
||||
static loader_logger *log_ = ohos_logger;
|
||||
|
||||
int loader_open_device(const char *device_name)
|
||||
{
|
||||
log_(_LOADER_WARNING, "loader_open_device %s", device_name);
|
||||
int fd;
|
||||
#ifdef O_CLOEXEC
|
||||
fd = open(device_name, O_RDWR | O_CLOEXEC);
|
||||
if (fd == -1 && errno == EINVAL)
|
||||
fd = open(device_name, O_RDWR | O_CLOEXEC);
|
||||
#endif
|
||||
{
|
||||
fd = open(device_name, O_RDWR);
|
||||
if (fd != -1)
|
||||
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
|
||||
}
|
||||
if (fd == -1 && errno == EACCES) {
|
||||
log_(_LOADER_WARNING, "failed to open %s: %s\n",
|
||||
device_name, strerror(errno));
|
||||
}
|
||||
return fd;
|
||||
if (fd == -1 && errno == EINVAL) {
|
||||
fd = open(device_name, O_RDWR);
|
||||
if (fd != -1) {
|
||||
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
|
||||
}
|
||||
}
|
||||
if (fd == -1 && errno == EACCES) {
|
||||
log_(_LOADER_WARNING, "failed to open %s: %s\n",
|
||||
device_name, strerror(errno));
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
static char *loader_get_kernel_driver_name(int fd)
|
||||
{
|
||||
#if HAVE_LIBDRM
|
||||
char *driver;
|
||||
drmVersionPtr version = drmGetVersion(fd);
|
||||
char *driver;
|
||||
drmVersionPtr version = drmGetVersion(fd);
|
||||
|
||||
if (!version) {
|
||||
log_(_LOADER_WARNING, "failed to get driver name for fd %d\n", fd);
|
||||
return NULL;
|
||||
}
|
||||
if (!version) {
|
||||
log_(_LOADER_WARNING, "failed to get driver name for fd %d\n", fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
driver = strndup(version->name, version->name_len);
|
||||
log_(driver ? _LOADER_DEBUG : _LOADER_WARNING, "using driver %s for %d\n",
|
||||
driver, fd);
|
||||
driver = strndup(version->name, version->name_len);
|
||||
log_(driver ? _LOADER_DEBUG : _LOADER_WARNING, "using driver %s for %d\n",
|
||||
driver, fd);
|
||||
|
||||
drmFreeVersion(version);
|
||||
return driver;
|
||||
drmFreeVersion(version);
|
||||
return driver;
|
||||
#else
|
||||
return NULL;
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
is_kernel_i915(int fd)
|
||||
bool is_kernel_i915(int fd)
|
||||
{
|
||||
char *kernel_driver = loader_get_kernel_driver_name(fd);
|
||||
bool is_i915 = kernel_driver && strcmp(kernel_driver, "i915") == 0;
|
||||
char *kernel_driver = loader_get_kernel_driver_name(fd);
|
||||
bool is_i915 = kernel_driver && strcmp(kernel_driver, "i915") == 0;
|
||||
|
||||
free(kernel_driver);
|
||||
return is_i915;
|
||||
free(kernel_driver);
|
||||
return is_i915;
|
||||
}
|
||||
|
||||
#if defined(HAVE_LIBDRM)
|
||||
int
|
||||
loader_open_render_node(const char *name)
|
||||
int loader_open_render_node(const char *name)
|
||||
{
|
||||
drmDevicePtr devices[MAX_DRM_DEVICES], device;
|
||||
int i, num_devices, fd = -1;
|
||||
drmDevicePtr devices[MAX_DRM_DEVICES], device;
|
||||
int i, num_devices, fd = -1;
|
||||
|
||||
num_devices = drmGetDevices2(0, devices, MAX_DRM_DEVICES);
|
||||
if (num_devices <= 0)
|
||||
return -ENOENT;
|
||||
num_devices = drmGetDevices2(0, devices, MAX_DRM_DEVICES);
|
||||
if (num_devices <= 0) {
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_devices; i++) {
|
||||
device = devices[i];
|
||||
for (i = 0; i < num_devices; i++) {
|
||||
device = devices[i];
|
||||
|
||||
if ((device->available_nodes & (1 << DRM_NODE_RENDER)) &&
|
||||
(device->bustype == DRM_BUS_PLATFORM)) {
|
||||
drmVersionPtr version;
|
||||
if ((device->available_nodes & (1 << DRM_NODE_RENDER)) &&
|
||||
(device->bustype == DRM_BUS_PLATFORM)) {
|
||||
drmVersionPtr version;
|
||||
|
||||
fd = loader_open_device(device->nodes[DRM_NODE_RENDER]);
|
||||
if (fd < 0)
|
||||
continue;
|
||||
fd = loader_open_device(device->nodes[DRM_NODE_RENDER]);
|
||||
if (fd < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
version = drmGetVersion(fd);
|
||||
if (!version) {
|
||||
close(fd);
|
||||
continue;
|
||||
}
|
||||
version = drmGetVersion(fd);
|
||||
if (!version) {
|
||||
close(fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(version->name, name) != 0) {
|
||||
drmFreeVersion(version);
|
||||
close(fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(version->name, name) != 0) {
|
||||
drmFreeVersion(version);
|
||||
close(fd);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
drmFreeDevices(devices, num_devices);
|
||||
|
||||
drmFreeVersion(version);
|
||||
break;
|
||||
}
|
||||
}
|
||||
drmFreeDevices(devices, num_devices);
|
||||
if (i == num_devices) {
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (i == num_devices)
|
||||
return -ENOENT;
|
||||
|
||||
return fd;
|
||||
return fd;
|
||||
}
|
||||
|
||||
#ifdef USE_DRICONF
|
||||
static const driOptionDescription __driConfigOptionsLoader[] = {
|
||||
DRI_CONF_SECTION_INITIALIZATION
|
||||
DRI_CONF_DEVICE_ID_PATH_TAG()
|
||||
DRI_CONF_DRI_DRIVER()
|
||||
DRI_CONF_SECTION_END
|
||||
};
|
||||
DRI_CONF_DRI_DRIVER()
|
||||
DRI_CONF_SECTION_END};
|
||||
|
||||
static char *loader_get_dri_config_driver(int fd)
|
||||
{
|
||||
driOptionCache defaultInitOptions;
|
||||
driOptionCache userInitOptions;
|
||||
char *dri_driver = NULL;
|
||||
char *kernel_driver = loader_get_kernel_driver_name(fd);
|
||||
driOptionCache defaultInitOptions;
|
||||
driOptionCache userInitOptions;
|
||||
char *dri_driver = NULL;
|
||||
char *kernel_driver = loader_get_kernel_driver_name(fd);
|
||||
|
||||
driParseOptionInfo(&defaultInitOptions, __driConfigOptionsLoader,
|
||||
ARRAY_SIZE(__driConfigOptionsLoader));
|
||||
driParseConfigFiles(&userInitOptions, &defaultInitOptions, 0,
|
||||
"loader", kernel_driver, NULL, NULL, 0, NULL, 0);
|
||||
if (driCheckOption(&userInitOptions, "dri_driver", DRI_STRING)) {
|
||||
char *opt = driQueryOptionstr(&userInitOptions, "dri_driver");
|
||||
/* not an empty string */
|
||||
if (*opt)
|
||||
dri_driver = strdup(opt);
|
||||
}
|
||||
driDestroyOptionCache(&userInitOptions);
|
||||
driDestroyOptionInfo(&defaultInitOptions);
|
||||
driParseOptionInfo(&defaultInitOptions, __driConfigOptionsLoader,
|
||||
ARRAY_SIZE(__driConfigOptionsLoader));
|
||||
driParseConfigFiles(&userInitOptions, &defaultInitOptions, 0,
|
||||
"loader", kernel_driver, NULL, NULL, 0, NULL, 0);
|
||||
if (driCheckOption(&userInitOptions, "dri_driver", DRI_STRING)) {
|
||||
char *opt = driQueryOptionstr(&userInitOptions, "dri_driver");
|
||||
/* not an empty string */
|
||||
if (*opt) {
|
||||
dri_driver = strdup(opt);
|
||||
}
|
||||
}
|
||||
driDestroyOptionCache(&userInitOptions);
|
||||
driDestroyOptionInfo(&defaultInitOptions);
|
||||
|
||||
free(kernel_driver);
|
||||
return dri_driver;
|
||||
free(kernel_driver);
|
||||
return dri_driver;
|
||||
}
|
||||
|
||||
static char *loader_get_dri_config_device_id(void)
|
||||
{
|
||||
driOptionCache defaultInitOptions;
|
||||
driOptionCache userInitOptions;
|
||||
char *prime = NULL;
|
||||
driOptionCache defaultInitOptions;
|
||||
driOptionCache userInitOptions;
|
||||
char *prime = NULL;
|
||||
|
||||
driParseOptionInfo(&defaultInitOptions, __driConfigOptionsLoader,
|
||||
ARRAY_SIZE(__driConfigOptionsLoader));
|
||||
driParseConfigFiles(&userInitOptions, &defaultInitOptions, 0,
|
||||
"loader", NULL, NULL, NULL, 0, NULL, 0);
|
||||
if (driCheckOption(&userInitOptions, "device_id", DRI_STRING))
|
||||
prime = strdup(driQueryOptionstr(&userInitOptions, "device_id"));
|
||||
driDestroyOptionCache(&userInitOptions);
|
||||
driDestroyOptionInfo(&defaultInitOptions);
|
||||
driParseOptionInfo(&defaultInitOptions, __driConfigOptionsLoader,
|
||||
ARRAY_SIZE(__driConfigOptionsLoader));
|
||||
driParseConfigFiles(&userInitOptions, &defaultInitOptions, 0,
|
||||
"loader", NULL, NULL, NULL, 0, NULL, 0);
|
||||
if (driCheckOption(&userInitOptions, "device_id", DRI_STRING)) {
|
||||
prime = strdup(driQueryOptionstr(&userInitOptions, "device_id"));
|
||||
}
|
||||
driDestroyOptionCache(&userInitOptions);
|
||||
driDestroyOptionInfo(&defaultInitOptions);
|
||||
|
||||
return prime;
|
||||
return prime;
|
||||
}
|
||||
#endif
|
||||
|
||||
static char *drm_construct_id_path_tag(drmDevicePtr device)
|
||||
{
|
||||
char *tag = NULL;
|
||||
char *tag = NULL;
|
||||
|
||||
if (device->bustype == DRM_BUS_PCI) {
|
||||
if (asprintf(&tag, "pci-%04x_%02x_%02x_%1u",
|
||||
device->businfo.pci->domain,
|
||||
device->businfo.pci->bus,
|
||||
device->businfo.pci->dev,
|
||||
device->businfo.pci->func) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
} else if (device->bustype == DRM_BUS_PLATFORM ||
|
||||
device->bustype == DRM_BUS_HOST1X) {
|
||||
char *fullname, *name, *address;
|
||||
if (device->bustype == DRM_BUS_PCI) {
|
||||
if (asprintf(&tag, "pci-%04x_%02x_%02x_%1u",
|
||||
device->businfo.pci->domain,
|
||||
device->businfo.pci->bus,
|
||||
device->businfo.pci->dev,
|
||||
device->businfo.pci->func) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
} else if (device->bustype == DRM_BUS_PLATFORM ||
|
||||
device->bustype == DRM_BUS_HOST1X) {
|
||||
char *fullname, *name, *address;
|
||||
|
||||
if (device->bustype == DRM_BUS_PLATFORM)
|
||||
fullname = device->businfo.platform->fullname;
|
||||
else
|
||||
fullname = device->businfo.host1x->fullname;
|
||||
if (device->bustype == DRM_BUS_PLATFORM) {
|
||||
fullname = device->businfo.platform->fullname;
|
||||
} else {
|
||||
fullname = device->businfo.host1x->fullname;
|
||||
}
|
||||
|
||||
name = strrchr(fullname, '/');
|
||||
if (!name)
|
||||
name = strdup(fullname);
|
||||
else
|
||||
name = strdup(name + 1);
|
||||
name = strrchr(fullname, '/');
|
||||
if (!name) {
|
||||
name = strdup(fullname);
|
||||
} else {
|
||||
name = strdup(name + 1);
|
||||
}
|
||||
|
||||
address = strchr(name, '@');
|
||||
if (address) {
|
||||
*address++ = '\0';
|
||||
address = strchr(name, '@');
|
||||
if (address) {
|
||||
*address++ = '\0';
|
||||
|
||||
if (asprintf(&tag, "platform-%s_%s", address, name) < 0)
|
||||
tag = NULL;
|
||||
} else {
|
||||
if (asprintf(&tag, "platform-%s", name) < 0)
|
||||
tag = NULL;
|
||||
}
|
||||
if (asprintf(&tag, "platform-%s_%s", address, name) < 0) {
|
||||
tag = NULL;
|
||||
}
|
||||
} else {
|
||||
if (asprintf(&tag, "platform-%s", name) < 0) {
|
||||
tag = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
free(name);
|
||||
}
|
||||
return tag;
|
||||
free(name);
|
||||
}
|
||||
return tag;
|
||||
}
|
||||
|
||||
static bool drm_device_matches_tag(drmDevicePtr device, const char *prime_tag)
|
||||
{
|
||||
char *tag = drm_construct_id_path_tag(device);
|
||||
int ret;
|
||||
char *tag = drm_construct_id_path_tag(device);
|
||||
int ret;
|
||||
|
||||
if (tag == NULL)
|
||||
return false;
|
||||
if (tag == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = strcmp(tag, prime_tag);
|
||||
ret = strcmp(tag, prime_tag);
|
||||
|
||||
free(tag);
|
||||
return ret == 0;
|
||||
free(tag);
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
static char *drm_get_id_path_tag_for_fd(int fd)
|
||||
{
|
||||
drmDevicePtr device;
|
||||
char *tag;
|
||||
drmDevicePtr device;
|
||||
char *tag;
|
||||
|
||||
if (drmGetDevice2(fd, 0, &device) != 0)
|
||||
return NULL;
|
||||
if (drmGetDevice2(fd, 0, &device) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tag = drm_construct_id_path_tag(device);
|
||||
drmFreeDevice(&device);
|
||||
return tag;
|
||||
tag = drm_construct_id_path_tag(device);
|
||||
drmFreeDevice(&device);
|
||||
return tag;
|
||||
}
|
||||
|
||||
int loader_get_user_preferred_fd(int default_fd, bool *different_device)
|
||||
int loader_get_user_preferred_fd(int default_fd,
|
||||
bool *different_device)
|
||||
{
|
||||
const char *dri_prime = getenv("DRI_PRIME");
|
||||
char *default_tag, *prime = NULL;
|
||||
drmDevicePtr devices[MAX_DRM_DEVICES];
|
||||
int i, num_devices, fd = -1;
|
||||
const char *dri_prime = getenv("DRI_PRIME");
|
||||
char *default_tag, *prime = NULL;
|
||||
drmDevicePtr devices[MAX_DRM_DEVICES];
|
||||
int i, num_devices, fd = -1;
|
||||
|
||||
if (dri_prime)
|
||||
prime = strdup(dri_prime);
|
||||
#ifdef USE_DRICONF
|
||||
else
|
||||
prime = loader_get_dri_config_device_id();
|
||||
if (dri_prime) {
|
||||
prime = strdup(dri_prime);
|
||||
} else {
|
||||
prime = loader_get_dri_config_device_id();
|
||||
}
|
||||
#else
|
||||
if (dri_prime) {
|
||||
prime = strdup(dri_prime);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (prime == NULL) {
|
||||
*different_device = false;
|
||||
return default_fd;
|
||||
}
|
||||
if (prime == NULL) {
|
||||
*different_device = false;
|
||||
return default_fd;
|
||||
}
|
||||
|
||||
default_tag = drm_get_id_path_tag_for_fd(default_fd);
|
||||
if (default_tag == NULL)
|
||||
goto err;
|
||||
default_tag = drm_get_id_path_tag_for_fd(default_fd);
|
||||
if (default_tag == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
num_devices = drmGetDevices2(0, devices, MAX_DRM_DEVICES);
|
||||
if (num_devices <= 0)
|
||||
goto err;
|
||||
num_devices = drmGetDevices2(0, devices, MAX_DRM_DEVICES);
|
||||
if (num_devices <= 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_devices; i++) {
|
||||
if (!(devices[i]->available_nodes & 1 << DRM_NODE_RENDER))
|
||||
continue;
|
||||
|
||||
/* two formats of DRI_PRIME are supported:
|
||||
* "1": choose any other card than the card used by default.
|
||||
* id_path_tag: (for example "pci-0000_02_00_0") choose the card
|
||||
* with this id_path_tag.
|
||||
*/
|
||||
if (!strcmp(prime,"1")) {
|
||||
if (drm_device_matches_tag(devices[i], default_tag))
|
||||
for (i = 0; i < num_devices; i++) {
|
||||
if (!(devices[i]->available_nodes & 1 << DRM_NODE_RENDER)) {
|
||||
continue;
|
||||
} else {
|
||||
if (!drm_device_matches_tag(devices[i], prime))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
fd = loader_open_device(devices[i]->nodes[DRM_NODE_RENDER]);
|
||||
break;
|
||||
}
|
||||
drmFreeDevices(devices, num_devices);
|
||||
/* two formats of DRI_PRIME are supported:
|
||||
* "1": choose any other card than the card used by default.
|
||||
* id_path_tag: (for example "pci-0000_02_00_0") choose the card
|
||||
* with this id_path_tag.
|
||||
*/
|
||||
if (!strcmp(prime, "1")) {
|
||||
if (drm_device_matches_tag(devices[i], default_tag)) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (!drm_device_matches_tag(devices[i], prime)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == num_devices)
|
||||
goto err;
|
||||
fd = loader_open_device(devices[i]->nodes[DRM_NODE_RENDER]);
|
||||
break;
|
||||
}
|
||||
drmFreeDevices(devices, num_devices);
|
||||
|
||||
if (fd < 0)
|
||||
goto err;
|
||||
if (i == num_devices) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
close(default_fd);
|
||||
if (fd < 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
*different_device = !!strcmp(default_tag, prime);
|
||||
close(default_fd);
|
||||
|
||||
free(default_tag);
|
||||
free(prime);
|
||||
return fd;
|
||||
*different_device = !!strcmp(default_tag, prime);
|
||||
|
||||
err:
|
||||
*different_device = false;
|
||||
free(default_tag);
|
||||
free(prime);
|
||||
return fd;
|
||||
|
||||
free(default_tag);
|
||||
free(prime);
|
||||
return default_fd;
|
||||
err:
|
||||
*different_device = false;
|
||||
|
||||
free(default_tag);
|
||||
free(prime);
|
||||
return default_fd;
|
||||
}
|
||||
#else
|
||||
int
|
||||
loader_open_render_node(const char *name)
|
||||
int loader_open_render_node(const char *name)
|
||||
{
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int loader_get_user_preferred_fd(int default_fd, bool *different_device)
|
||||
int loader_get_user_preferred_fd(int default_fd,
|
||||
bool *different_device)
|
||||
{
|
||||
*different_device = false;
|
||||
return default_fd;
|
||||
*different_device = false;
|
||||
return default_fd;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -387,133 +441,138 @@ int loader_get_user_preferred_fd(int default_fd, bool *different_device)
|
||||
static bool
|
||||
drm_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id)
|
||||
{
|
||||
drmDevicePtr device;
|
||||
drmDevicePtr device;
|
||||
|
||||
if (drmGetDevice2(fd, 0, &device) != 0) {
|
||||
log_(_LOADER_WARNING, "MESA-LOADER: failed to retrieve device information\n");
|
||||
return false;
|
||||
}
|
||||
if (drmGetDevice2(fd, 0, &device) != 0) {
|
||||
log_(_LOADER_WARNING, "MESA-LOADER: failed to retrieve device information\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (device->bustype != DRM_BUS_PCI) {
|
||||
drmFreeDevice(&device);
|
||||
log_(_LOADER_DEBUG, "MESA-LOADER: device is not located on the PCI bus\n");
|
||||
return false;
|
||||
}
|
||||
if (device->bustype != DRM_BUS_PCI) {
|
||||
drmFreeDevice(&device);
|
||||
log_(_LOADER_DEBUG, "MESA-LOADER: device is not located on the PCI bus\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
*vendor_id = device->deviceinfo.pci->vendor_id;
|
||||
*chip_id = device->deviceinfo.pci->device_id;
|
||||
drmFreeDevice(&device);
|
||||
return true;
|
||||
*vendor_id = device->deviceinfo.pci->vendor_id;
|
||||
*chip_id = device->deviceinfo.pci->device_id;
|
||||
drmFreeDevice(&device);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool
|
||||
loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id)
|
||||
bool loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id)
|
||||
{
|
||||
#if HAVE_LIBDRM
|
||||
return drm_get_pci_id_for_fd(fd, vendor_id, chip_id);
|
||||
return drm_get_pci_id_for_fd(fd, vendor_id, chip_id);
|
||||
#endif
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
char *
|
||||
loader_get_device_name_for_fd(int fd)
|
||||
{
|
||||
char *result = NULL;
|
||||
char *result = NULL;
|
||||
|
||||
#if HAVE_LIBDRM
|
||||
result = drmGetDeviceNameFromFd2(fd);
|
||||
result = drmGetDeviceNameFromFd2(fd);
|
||||
#endif
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
static char *
|
||||
loader_get_pci_driver(int fd)
|
||||
{
|
||||
int vendor_id, chip_id, i, j;
|
||||
char *driver = NULL;
|
||||
int vendor_id, chip_id, i, j;
|
||||
char *driver = NULL;
|
||||
|
||||
if (!loader_get_pci_id_for_fd(fd, &vendor_id, &chip_id))
|
||||
return NULL;
|
||||
if (!loader_get_pci_id_for_fd(fd, &vendor_id, &chip_id)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(driver_map); i++) {
|
||||
if (vendor_id != driver_map[i].vendor_id)
|
||||
continue;
|
||||
for (i = 0; i < ARRAY_SIZE(driver_map); i++) {
|
||||
if (vendor_id != driver_map[i].vendor_id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (driver_map[i].predicate && !driver_map[i].predicate(fd))
|
||||
continue;
|
||||
if (driver_map[i].predicate && !driver_map[i].predicate(fd)) {
|
||||
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) {
|
||||
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_DEBUG : _LOADER_WARNING,
|
||||
log_(driver ? _LOADER_DEBUG : _LOADER_WARNING,
|
||||
"pci id for fd %d: %04x:%04x, driver %s\n",
|
||||
fd, vendor_id, chip_id, driver);
|
||||
return driver;
|
||||
return driver;
|
||||
}
|
||||
|
||||
char *
|
||||
loader_get_driver_for_fd(int fd)
|
||||
{
|
||||
char *driver;
|
||||
char *driver;
|
||||
|
||||
/* Allow an environment variable to force choosing a different driver
|
||||
* binary. If that driver binary can't survive on this FD, that's the
|
||||
* user's problem, but this allows vc4 simulator to run on an i965 host,
|
||||
* and may be useful for some touch testing of i915 on an i965 host.
|
||||
*/
|
||||
if (geteuid() == getuid()) {
|
||||
driver = getenv("MESA_LOADER_DRIVER_OVERRIDE");
|
||||
if (driver)
|
||||
return strdup(driver);
|
||||
}
|
||||
/* Allow an environment variable to force choosing a different driver
|
||||
* binary. If that driver binary can't survive on this FD, that's the
|
||||
* user's problem, but this allows vc4 simulator to run on an i965 host,
|
||||
* and may be useful for some touch testing of i915 on an i965 host.
|
||||
*/
|
||||
if (geteuid() == getuid()) {
|
||||
driver = getenv("MESA_LOADER_DRIVER_OVERRIDE");
|
||||
if (driver) {
|
||||
return strdup(driver);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(HAVE_LIBDRM) && defined(USE_DRICONF)
|
||||
driver = loader_get_dri_config_driver(fd);
|
||||
if (driver)
|
||||
return driver;
|
||||
driver = loader_get_dri_config_driver(fd);
|
||||
if (driver) {
|
||||
return driver;
|
||||
}
|
||||
#endif
|
||||
|
||||
driver = loader_get_pci_driver(fd);
|
||||
if (!driver)
|
||||
driver = loader_get_kernel_driver_name(fd);
|
||||
driver = loader_get_pci_driver(fd);
|
||||
if (!driver) {
|
||||
driver = loader_get_kernel_driver_name(fd);
|
||||
}
|
||||
|
||||
return driver;
|
||||
return driver;
|
||||
}
|
||||
|
||||
void
|
||||
loader_set_logger(loader_logger *logger)
|
||||
void loader_set_logger(loader_logger *logger)
|
||||
{
|
||||
log_ = logger;
|
||||
log_ = logger;
|
||||
}
|
||||
|
||||
char *
|
||||
loader_get_extensions_name(const char *driver_name)
|
||||
{
|
||||
char *name = NULL;
|
||||
char *name = NULL;
|
||||
|
||||
if (asprintf(&name, "%s_%s", __DRI_DRIVER_GET_EXTENSIONS, driver_name) < 0)
|
||||
return NULL;
|
||||
if (asprintf(&name, "%s_%s", __DRI_DRIVER_GET_EXTENSIONS, driver_name) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const size_t len = strlen(name);
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
if (name[i] == '-')
|
||||
name[i] = '_';
|
||||
}
|
||||
const size_t len = strlen(name);
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
if (name[i] == '-') {
|
||||
name[i] = '_';
|
||||
}
|
||||
}
|
||||
|
||||
return name;
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -534,62 +593,66 @@ loader_open_driver_lib(const char *driver_name,
|
||||
const char *default_search_path,
|
||||
bool warn_on_fail)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
const char *search_paths, *next, *end;
|
||||
char path[PATH_MAX];
|
||||
const char *search_paths, *next, *end;
|
||||
|
||||
search_paths = NULL;
|
||||
if (geteuid() == getuid() && search_path_vars) {
|
||||
for (int i = 0; search_path_vars[i] != NULL; i++) {
|
||||
search_paths = getenv(search_path_vars[i]);
|
||||
if (search_paths)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (search_paths == NULL)
|
||||
search_paths = default_search_path;
|
||||
search_paths = NULL;
|
||||
if (geteuid() == getuid() && search_path_vars) {
|
||||
for (int i = 0; search_path_vars[i] != NULL; i++) {
|
||||
search_paths = getenv(search_path_vars[i]);
|
||||
if (search_paths) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (search_paths == NULL) {
|
||||
search_paths = default_search_path;
|
||||
}
|
||||
|
||||
void *driver = NULL;
|
||||
const char *dl_error = NULL;
|
||||
end = search_paths + strlen(search_paths);
|
||||
for (const char *p = search_paths; p < end; p = next + 1) {
|
||||
int len;
|
||||
next = strchr(p, ':');
|
||||
if (next == NULL)
|
||||
next = end;
|
||||
void *driver = NULL;
|
||||
const char *dl_error = NULL;
|
||||
end = search_paths + strlen(search_paths);
|
||||
for (const char *p = search_paths; p < end; p = next + 1) {
|
||||
int len;
|
||||
next = strchr(p, ':');
|
||||
if (next == NULL) {
|
||||
next = end;
|
||||
}
|
||||
|
||||
len = next - p;
|
||||
len = next - p;
|
||||
#if USE_ELF_TLS
|
||||
snprintf(path, sizeof(path), "%.*s/tls/%s%s.so", len,
|
||||
p, driver_name, lib_suffix);
|
||||
driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
|
||||
snprintf(path, sizeof(path), "%.*s/tls/%s%s.so", len,
|
||||
p, driver_name, lib_suffix);
|
||||
driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
|
||||
#endif
|
||||
if (driver == NULL) {
|
||||
snprintf(path, sizeof(path), "%.*s/%s%s.so", len,
|
||||
p, driver_name, lib_suffix);
|
||||
driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
|
||||
if (driver == NULL) {
|
||||
dl_error = dlerror();
|
||||
log_(_LOADER_DEBUG, "MESA-LOADER: failed to open %s: %s\n",
|
||||
path, dl_error);
|
||||
}
|
||||
}
|
||||
/* not need continue to loop all paths once the driver is found */
|
||||
if (driver != NULL)
|
||||
break;
|
||||
}
|
||||
if (driver == NULL) {
|
||||
snprintf(path, sizeof(path), "%.*s/%s%s.so", len,
|
||||
p, driver_name, lib_suffix);
|
||||
driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
|
||||
if (driver == NULL) {
|
||||
dl_error = dlerror();
|
||||
log_(_LOADER_DEBUG, "MESA-LOADER: failed to open %s: %s\n",
|
||||
path, dl_error);
|
||||
}
|
||||
}
|
||||
/* not need continue to loop all paths once the driver is found */
|
||||
if (driver != NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (driver == NULL) {
|
||||
if (warn_on_fail) {
|
||||
log_(_LOADER_WARNING,
|
||||
"MESA-LOADER: failed to open %s: %s (search paths %s, suffix %s)\n",
|
||||
driver_name, dl_error, search_paths, lib_suffix);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
if (driver == NULL) {
|
||||
if (warn_on_fail) {
|
||||
log_(_LOADER_WARNING,
|
||||
"MESA-LOADER: failed to open %s: %s (search paths %s, suffix %s)\n",
|
||||
driver_name, dl_error, search_paths, lib_suffix);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
log_(_LOADER_DEBUG, "MESA-LOADER: dlopen(%s)\n", path);
|
||||
log_(_LOADER_DEBUG, "MESA-LOADER: dlopen(%s)\n", path);
|
||||
|
||||
return driver;
|
||||
return driver;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -606,37 +669,39 @@ loader_open_driver(const char *driver_name,
|
||||
void **out_driver_handle,
|
||||
const char **search_path_vars)
|
||||
{
|
||||
char *get_extensions_name;
|
||||
const struct __DRIextensionRec **extensions = NULL;
|
||||
const struct __DRIextensionRec **(*get_extensions)(void);
|
||||
void *driver = loader_open_driver_lib(driver_name, "_dri", search_path_vars,
|
||||
DEFAULT_DRIVER_DIR, true);
|
||||
char *get_extensions_name;
|
||||
const struct __DRIextensionRec **extensions = NULL;
|
||||
const struct __DRIextensionRec **(*get_extensions)(void);
|
||||
void *driver = loader_open_driver_lib(driver_name, "_dri", search_path_vars,
|
||||
DEFAULT_DRIVER_DIR, true);
|
||||
|
||||
if (!driver)
|
||||
goto failed;
|
||||
if (!driver) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
get_extensions_name = loader_get_extensions_name(driver_name);
|
||||
if (get_extensions_name) {
|
||||
get_extensions = dlsym(driver, get_extensions_name);
|
||||
if (get_extensions) {
|
||||
extensions = get_extensions();
|
||||
} else {
|
||||
log_(_LOADER_DEBUG, "MESA-LOADER: driver does not expose %s(): %s\n",
|
||||
get_extensions_name, dlerror());
|
||||
}
|
||||
free(get_extensions_name);
|
||||
}
|
||||
get_extensions_name = loader_get_extensions_name(driver_name);
|
||||
if (get_extensions_name) {
|
||||
get_extensions = dlsym(driver, get_extensions_name);
|
||||
if (get_extensions) {
|
||||
extensions = get_extensions();
|
||||
} else {
|
||||
log_(_LOADER_DEBUG, "MESA-LOADER: driver does not expose %s(): %s\n",
|
||||
get_extensions_name, dlerror());
|
||||
}
|
||||
free(get_extensions_name);
|
||||
}
|
||||
|
||||
if (!extensions)
|
||||
extensions = dlsym(driver, __DRI_DRIVER_EXTENSIONS);
|
||||
if (extensions == NULL) {
|
||||
log_(_LOADER_WARNING,
|
||||
"MESA-LOADER: driver exports no extensions (%s)\n", dlerror());
|
||||
dlclose(driver);
|
||||
driver = NULL;
|
||||
}
|
||||
if (!extensions) {
|
||||
extensions = dlsym(driver, __DRI_DRIVER_EXTENSIONS);
|
||||
}
|
||||
if (extensions == NULL) {
|
||||
log_(_LOADER_WARNING,
|
||||
"MESA-LOADER: driver exports no extensions (%s)\n", dlerror());
|
||||
dlclose(driver);
|
||||
driver = NULL;
|
||||
}
|
||||
|
||||
failed:
|
||||
*out_driver_handle = driver;
|
||||
return extensions;
|
||||
*out_driver_handle = driver;
|
||||
return extensions;
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ struct __DRIextensionRec;
|
||||
/* Helpers to figure out driver and device name, eg. from pci-id, etc. */
|
||||
|
||||
int
|
||||
loader_open_device(const char *);
|
||||
loader_open_device(const char *device_name);
|
||||
|
||||
int
|
||||
loader_open_render_node(const char *name);
|
||||
|
@ -55,6 +55,6 @@ libloader = static_library(
|
||||
c_args : loader_c_args,
|
||||
gnu_symbol_visibility : 'hidden',
|
||||
include_directories : [inc_include, inc_src, inc_util],
|
||||
dependencies : [dep_libdrm, dep_thread],
|
||||
dependencies : [dep_libdrm, dep_thread, dep_hilog],
|
||||
build_by_default : false,
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user