252cda36fe
Change-Id: Ic3aaa7194a45243cd3c7e0ed226e86ba4f0fbf2b
274 regels
7.8 KiB
C
274 regels
7.8 KiB
C
/* Modifications Copyright(C) 2022 Advanced Micro Devices, Inc.
|
|
* All rights reserved.
|
|
*/
|
|
|
|
/*
|
|
* Copyright (c) 2016-2020 The Khronos Group Inc.
|
|
*
|
|
* 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.
|
|
*
|
|
* OpenCL is a trademark of Apple Inc. used under license by Khronos.
|
|
*/
|
|
|
|
#include "icd.h"
|
|
#include "icd_dispatch.h"
|
|
#include "icd_envvars.h"
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
KHRicdVendor *khrIcdVendors = NULL;
|
|
|
|
// entrypoint to initialize the ICD and add all vendors
|
|
void khrIcdInitialize(void)
|
|
{
|
|
// enumerate vendors present on the system
|
|
khrIcdOsVendorsEnumerateOnce();
|
|
}
|
|
|
|
void khrIcdVendorAdd(const char *libraryName)
|
|
{
|
|
void *library = NULL;
|
|
cl_int result = CL_SUCCESS;
|
|
pfn_clGetExtensionFunctionAddress p_clGetExtensionFunctionAddress = NULL;
|
|
pfn_clIcdGetPlatformIDs p_clIcdGetPlatformIDs = NULL;
|
|
cl_uint i = 0;
|
|
cl_uint platformCount = 0;
|
|
cl_platform_id *platforms = NULL;
|
|
KHRicdVendor *vendorIterator = NULL;
|
|
|
|
// require that the library name be valid
|
|
if (!libraryName)
|
|
{
|
|
goto Done;
|
|
}
|
|
KHR_ICD_TRACE("attempting to add vendor %s...\n", libraryName);
|
|
|
|
// load its library and query its function pointers
|
|
library = khrIcdOsLibraryLoad(libraryName);
|
|
if (!library)
|
|
{
|
|
KHR_ICD_TRACE("failed to load library %s\n", libraryName);
|
|
goto Done;
|
|
}
|
|
|
|
// get the library's file name
|
|
const char *libName = libraryName;
|
|
const char *c;
|
|
for (c = libraryName; *c; ++c)
|
|
{
|
|
if ((*c == '\\') || (*c == '/'))
|
|
{
|
|
libName = c + 1;
|
|
}
|
|
}
|
|
|
|
// ensure that we haven't already loaded this vendor
|
|
for (vendorIterator = khrIcdVendors; vendorIterator; vendorIterator = vendorIterator->next)
|
|
{
|
|
if (vendorIterator->library == library)
|
|
{
|
|
KHR_ICD_TRACE("already loaded vendor %s, nothing to do here\n", libraryName);
|
|
goto Done;
|
|
}
|
|
if (!strcmp(vendorIterator->libName, libName))
|
|
{
|
|
KHR_ICD_TRACE("already loaded library %s, nothing to do here\n", libName);
|
|
goto Done;
|
|
}
|
|
}
|
|
|
|
// get the library's clGetExtensionFunctionAddress pointer
|
|
p_clGetExtensionFunctionAddress = (pfn_clGetExtensionFunctionAddress)(size_t)khrIcdOsLibraryGetFunctionAddress(library, "clGetExtensionFunctionAddress");
|
|
if (!p_clGetExtensionFunctionAddress)
|
|
{
|
|
KHR_ICD_TRACE("failed to get function address clGetExtensionFunctionAddress\n");
|
|
goto Done;
|
|
}
|
|
|
|
// use that function to get the clIcdGetPlatformIDsKHR function pointer
|
|
p_clIcdGetPlatformIDs = (pfn_clIcdGetPlatformIDs)(size_t)p_clGetExtensionFunctionAddress("clIcdGetPlatformIDsKHR");
|
|
if (!p_clIcdGetPlatformIDs)
|
|
{
|
|
KHR_ICD_TRACE("failed to get extension function address clIcdGetPlatformIDsKHR\n");
|
|
goto Done;
|
|
}
|
|
|
|
// query the number of platforms available and allocate space to store them
|
|
result = p_clIcdGetPlatformIDs(0, NULL, &platformCount);
|
|
if (CL_SUCCESS != result)
|
|
{
|
|
KHR_ICD_TRACE("failed clIcdGetPlatformIDs\n");
|
|
goto Done;
|
|
}
|
|
platforms = (cl_platform_id *)malloc(platformCount * sizeof(cl_platform_id) );
|
|
if (!platforms)
|
|
{
|
|
KHR_ICD_TRACE("failed to allocate memory\n");
|
|
goto Done;
|
|
}
|
|
memset(platforms, 0, platformCount * sizeof(cl_platform_id) );
|
|
result = p_clIcdGetPlatformIDs(platformCount, platforms, NULL);
|
|
if (CL_SUCCESS != result)
|
|
{
|
|
KHR_ICD_TRACE("failed clIcdGetPlatformIDs\n");
|
|
goto Done;
|
|
}
|
|
|
|
// for each platform, add it
|
|
for (i = 0; i < platformCount; ++i)
|
|
{
|
|
KHRicdVendor* vendor = NULL;
|
|
char *suffix;
|
|
size_t suffixSize;
|
|
|
|
// call clGetPlatformInfo on the returned platform to get the suffix
|
|
if (!platforms[i])
|
|
{
|
|
continue;
|
|
}
|
|
result = platforms[i]->dispatch->clGetPlatformInfo(
|
|
platforms[i],
|
|
CL_PLATFORM_ICD_SUFFIX_KHR,
|
|
0,
|
|
NULL,
|
|
&suffixSize);
|
|
if (CL_SUCCESS != result)
|
|
{
|
|
continue;
|
|
}
|
|
suffix = (char *)malloc(suffixSize);
|
|
if (!suffix)
|
|
{
|
|
continue;
|
|
}
|
|
result = platforms[i]->dispatch->clGetPlatformInfo(
|
|
platforms[i],
|
|
CL_PLATFORM_ICD_SUFFIX_KHR,
|
|
suffixSize,
|
|
suffix,
|
|
NULL);
|
|
if (CL_SUCCESS != result)
|
|
{
|
|
free(suffix);
|
|
continue;
|
|
}
|
|
|
|
// allocate a structure for the vendor
|
|
vendor = (KHRicdVendor*)malloc(sizeof(*vendor) );
|
|
if (!vendor)
|
|
{
|
|
free(suffix);
|
|
KHR_ICD_TRACE("failed to allocate memory\n");
|
|
continue;
|
|
}
|
|
memset(vendor, 0, sizeof(*vendor) );
|
|
|
|
// populate vendor data
|
|
vendor->library = khrIcdOsLibraryLoad(libraryName);
|
|
if (!vendor->library)
|
|
{
|
|
free(suffix);
|
|
free(vendor);
|
|
KHR_ICD_TRACE("failed get platform handle to library\n");
|
|
continue;
|
|
}
|
|
vendor->libName = (char *)malloc(strlen(libName) + 1);
|
|
strcpy(vendor->libName, libName);
|
|
vendor->clGetExtensionFunctionAddress = p_clGetExtensionFunctionAddress;
|
|
vendor->platform = platforms[i];
|
|
vendor->suffix = suffix;
|
|
|
|
// add this vendor to the list of vendors at the tail
|
|
{
|
|
KHRicdVendor **prevNextPointer = NULL;
|
|
for (prevNextPointer = &khrIcdVendors; *prevNextPointer; prevNextPointer = &( (*prevNextPointer)->next) );
|
|
*prevNextPointer = vendor;
|
|
}
|
|
|
|
KHR_ICD_TRACE("successfully added vendor %s with suffix %s\n", libraryName, suffix);
|
|
|
|
}
|
|
|
|
Done:
|
|
|
|
if (library)
|
|
{
|
|
khrIcdOsLibraryUnload(library);
|
|
}
|
|
if (platforms)
|
|
{
|
|
free(platforms);
|
|
}
|
|
}
|
|
|
|
// Get next file or dirname given a string list or registry key path.
|
|
// Note: the input string may be modified!
|
|
static char *loader_get_next_path(char *path) {
|
|
size_t len;
|
|
char *next;
|
|
|
|
if (path == NULL) return NULL;
|
|
next = strchr(path, PATH_SEPARATOR);
|
|
if (next == NULL) {
|
|
len = strlen(path);
|
|
next = path + len;
|
|
} else {
|
|
*next = '\0';
|
|
next++;
|
|
}
|
|
|
|
return next;
|
|
}
|
|
|
|
void khrIcdVendorsEnumerateEnv(void)
|
|
{
|
|
char* icdFilenames = khrIcd_secure_getenv("OCL_ICD_FILENAMES");
|
|
char* cur_file = NULL;
|
|
char* next_file = NULL;
|
|
if (icdFilenames)
|
|
{
|
|
KHR_ICD_TRACE("Found OCL_ICD_FILENAMES environment variable.\n");
|
|
|
|
next_file = icdFilenames;
|
|
while (NULL != next_file && *next_file != '\0') {
|
|
cur_file = next_file;
|
|
next_file = loader_get_next_path(cur_file);
|
|
|
|
khrIcdVendorAdd(cur_file);
|
|
}
|
|
|
|
khrIcd_free_getenv(icdFilenames);
|
|
}
|
|
}
|
|
|
|
void khrIcdContextPropertiesGetPlatform(const cl_context_properties *properties, cl_platform_id *outPlatform)
|
|
{
|
|
if (properties == NULL && khrIcdVendors != NULL)
|
|
{
|
|
*outPlatform = khrIcdVendors[0].platform;
|
|
}
|
|
else
|
|
{
|
|
const cl_context_properties *property = (cl_context_properties *)NULL;
|
|
*outPlatform = NULL;
|
|
for (property = properties; property && property[0]; property += 2)
|
|
{
|
|
if ((cl_context_properties)CL_CONTEXT_PLATFORM == property[0])
|
|
{
|
|
*outPlatform = (cl_platform_id)property[1];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|