Commit 7107a0f3 by John Plate Committed by Commit Bot

CL: Load OpenCL without search path modification

Make it possible to load libGLESv2 and OpenCL_ANGLE without adding ANGLE's binary directory to the search path. Bug: angleproject:5904 Change-Id: Ie810466b39e1101e4da5b9fd199d26683b129281 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2897250 Commit-Queue: John Plate <jplate@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCody Northrop <cnorthrop@google.com>
parent c2fd3388
......@@ -16,6 +16,7 @@
#include "anglebase/no_destructor.h"
#include "common/angle_version.h"
#include "common/system_utils.h"
extern "C" {
#include "icd.h"
......@@ -391,16 +392,27 @@ void CLPlatformCL::Initialize(const cl_icd_dispatch &dispatch, bool isIcd)
return;
}
// The absolute path to ANGLE's OpenCL library is needed and it is assumed here that
// it is in the same directory as the shared library which contains this CL back end.
std::string libPath = angle::GetModuleDirectory();
if (!libPath.empty() && libPath.back() != angle::GetPathSeparator())
{
libPath += angle::GetPathSeparator();
}
libPath += ANGLE_OPENCL_LIB_NAME;
libPath += '.';
libPath += angle::GetSharedLibraryExtension();
// Our OpenCL entry points are not reentrant, so we have to prevent khrIcdInitialize()
// from querying ANGLE's OpenCL library. We store a dummy entry with the library in the
// khrIcdVendors list, because the ICD Loader skips the libraries which are already in
// the list as it assumes they were already enumerated.
static angle::base::NoDestructor<KHRicdVendor> sVendorAngle({});
sVendorAngle->library = khrIcdOsLibraryLoad(ANGLE_OPENCL_LIB_NAME);
sVendorAngle->library = khrIcdOsLibraryLoad(libPath.c_str());
khrIcdVendors = sVendorAngle.get();
if (khrIcdVendors->library == nullptr)
{
WARN() << "Unable to load library \"" ANGLE_OPENCL_LIB_NAME "\"";
WARN() << "Unable to load library \"" << libPath << "\"";
return;
}
......
......@@ -9,17 +9,25 @@ import("../../gni/angle.gni")
assert(angle_enable_cl)
cl_library_name = "OpenCL_ANGLE"
if (is_win || is_linux) {
glesv2_path =
rebase_path(get_label_info("$angle_root:libGLESv2", "root_out_dir"))
}
config("opencl_library_name") {
if (is_win) {
defines = [ "ANGLE_OPENCL_LIB_NAME=\"" + cl_library_name + "\"" ]
} else {
defines = [ "ANGLE_OPENCL_LIB_NAME=\"lib" + cl_library_name + ".so\"" ]
defines = [ "ANGLE_OPENCL_LIB_NAME=\"lib" + cl_library_name + "\"" ]
}
}
angle_shared_library(cl_library_name) {
defines = [ "LIBCL_IMPLEMENTATION" ]
if (is_win) {
defines += [ "ANGLE_GLESV2_LIBRARY_PATH=\"" +
string_replace(glesv2_path, "/", "\\\\") + "\"" ]
}
sources = [
"dispatch.cpp",
......@@ -39,8 +47,11 @@ angle_shared_library(cl_library_name) {
if (is_linux) {
inputs = [ "libOpenCL_autogen.map" ]
ldflags = [ "-Wl,--version-script=" +
rebase_path("libOpenCL_autogen.map", root_build_dir) ]
ldflags = [
"-Wl,--version-script=" +
rebase_path("libOpenCL_autogen.map", root_build_dir),
"-Wl,-rpath=" + glesv2_path,
]
}
}
......
......@@ -8,11 +8,15 @@
#include "libOpenCL/dispatch.h"
#include "anglebase/no_destructor.h"
#include "common/debug.h"
#include "common/system_utils.h"
#include <iostream>
#include <memory>
#ifdef _WIN32
# include <windows.h>
#endif
namespace cl
{
......@@ -27,30 +31,69 @@ std::unique_ptr<angle::Library> &EntryPointsLib()
IcdDispatch CreateDispatch()
{
IcdDispatch dispatch;
const cl_icd_dispatch *clIcdDispatch = nullptr;
const char *error = nullptr;
// Try to find ANGLE's GLESv2 library in the consistent way, which might fail
// if the current library or a link to it is not in ANGLE's binary directory
EntryPointsLib().reset(
angle::OpenSharedLibrary(ANGLE_GLESV2_LIBRARY_NAME, angle::SearchType::ApplicationDir));
if (EntryPointsLib())
if (EntryPointsLib() && EntryPointsLib()->getNative() != nullptr)
{
auto clIcdDispatch = reinterpret_cast<const cl_icd_dispatch *>(
EntryPointsLib()->getSymbol("gCLIcdDispatchTable"));
if (clIcdDispatch != nullptr)
{
static_cast<cl_icd_dispatch &>(dispatch) = *clIcdDispatch;
dispatch.clIcdGetPlatformIDsKHR = reinterpret_cast<clIcdGetPlatformIDsKHR_fn>(
clIcdDispatch->clGetExtensionFunctionAddress("clIcdGetPlatformIDsKHR"));
}
else
EntryPointsLib()->getAs("gCLIcdDispatchTable", &clIcdDispatch);
if (clIcdDispatch == nullptr)
{
std::cerr << "Error loading CL dispatch table." << std::endl;
INFO() << "Found system's instead of ANGLE's GLESv2 library";
}
}
else
{
std::cerr << "Error opening GLESv2 library." << std::endl;
error = "Not able to find GLESv2 library";
}
// If not found try to find ANGLE's GLESv2 library in build path
if (clIcdDispatch == nullptr)
{
#ifdef _WIN32
// On Windows the build path 'ANGLE_GLESV2_LIBRARY_PATH' is provided by the build system
const char path[] = ANGLE_GLESV2_LIBRARY_PATH "\\" ANGLE_GLESV2_LIBRARY_NAME ".dll";
// This function allows to load further dependent libraries from the same directory
HMODULE handle = LoadLibraryExA(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
if (handle != nullptr)
{
clIcdDispatch = reinterpret_cast<const cl_icd_dispatch *>(
GetProcAddress(handle, "gCLIcdDispatchTable"));
if (clIcdDispatch == nullptr)
{
error = "Error loading CL dispatch table.";
}
}
#else
// On posix-compatible systems this will also search in the rpath, which is the build path
EntryPointsLib().reset(
angle::OpenSharedLibrary(ANGLE_GLESV2_LIBRARY_NAME, angle::SearchType::SystemDir));
if (EntryPointsLib() && EntryPointsLib()->getNative() != nullptr)
{
EntryPointsLib()->getAs("gCLIcdDispatchTable", &clIcdDispatch);
if (clIcdDispatch == nullptr)
{
INFO() << "Found system's instead of ANGLE's GLESv2 library";
}
}
#endif
}
IcdDispatch dispatch;
if (clIcdDispatch != nullptr)
{
static_cast<cl_icd_dispatch &>(dispatch) = *clIcdDispatch;
dispatch.clIcdGetPlatformIDsKHR = reinterpret_cast<clIcdGetPlatformIDsKHR_fn>(
clIcdDispatch->clGetExtensionFunctionAddress("clIcdGetPlatformIDsKHR"));
}
else if (error != nullptr)
{
ERR() << error;
}
return dispatch;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment