Edit

kc3-lang/angle/src/libOpenCL/dispatch.cpp

Branch :

  • Show log

    Commit

  • Author : Jamie Madill
    Date : 2021-07-16 13:24:34
    Hash : 48da1c35
    Message : Vulkan: Prefer the local vulkan loader over the system one. Load the Vulkan loader ourselves and give vkGetInstanceProcAddr to volk. This allows us to always prefer loading from the current module directory instead of using the platform-specific ordering. Refactor angle::Library loading to use ModuleDir instead of ApplicationDir. CL originally authored by Geoff Lang. Bug: chromium:1219969 Change-Id: I21d1926e90fd66e1c23cea7323991ae55f3d22d4 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3035444 Reviewed-by: Jonah Ryan-Davis <jonahr@google.com> Reviewed-by: Tim Van Patten <timvp@google.com> Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>

  • src/libOpenCL/dispatch.cpp
  • //
    // Copyright 2021 The ANGLE Project Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.
    //
    // dispatch.cpp: Implements a function to fetch the ANGLE OpenCL dispatch table.
    
    #include "libOpenCL/dispatch.h"
    
    #include "anglebase/no_destructor.h"
    #include "common/debug.h"
    #include "common/system_utils.h"
    
    #include <memory>
    
    #ifdef _WIN32
    #    include <windows.h>
    #endif
    
    namespace cl
    {
    
    namespace
    {
    
    std::unique_ptr<angle::Library> &EntryPointsLib()
    {
        static angle::base::NoDestructor<std::unique_ptr<angle::Library>> sEntryPointsLib;
        return *sEntryPointsLib;
    }
    
    IcdDispatch CreateDispatch()
    {
        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::ModuleDir));
        if (EntryPointsLib() && EntryPointsLib()->getNative() != nullptr)
        {
            EntryPointsLib()->getAs("gCLIcdDispatchTable", &clIcdDispatch);
            if (clIcdDispatch == nullptr)
            {
                INFO() << "Found system's instead of ANGLE's GLESv2 library";
            }
        }
        else
        {
            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;
    }
    
    }  // anonymous namespace
    
    const IcdDispatch &GetDispatch()
    {
        static const IcdDispatch sDispatch(CreateDispatch());
        return sDispatch;
    }
    
    }  // namespace cl