From 4aa683775c4ee55594196c79def7a75103d75e4c Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Tue, 13 Sep 2022 08:27:13 -0800 Subject: [PATCH] Rewrite CLOn12 loader in C (#179) * Rewrite CLOn12 loader in C * Remove additional now-unneeded extern "C" guards for khrEnableTrace * Fix trace message Co-authored-by: Ben Ashbaugh Co-authored-by: Ben Ashbaugh --- CMakeLists.txt | 3 +- loader/icd.h | 8 +- loader/windows/icd_windows_apppackage.c | 99 ++++++++++++ loader/windows/icd_windows_apppackage.cpp | 176 ---------------------- loader/windows/icd_windows_apppackage.h | 3 - 5 files changed, 101 insertions(+), 188 deletions(-) create mode 100644 loader/windows/icd_windows_apppackage.c delete mode 100644 loader/windows/icd_windows_apppackage.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 06c87bfe..c8d5e0e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,7 +69,6 @@ set (OPENCL_ICD_LOADER_SOURCES loader/icd_platform.h) if (WIN32) - enable_language (CXX) list (APPEND OPENCL_ICD_LOADER_SOURCES loader/windows/adapter.h loader/windows/icd_windows.c @@ -79,7 +78,7 @@ if (WIN32) loader/windows/icd_windows_envvars.c loader/windows/icd_windows_hkr.c loader/windows/icd_windows_hkr.h - loader/windows/icd_windows_apppackage.cpp + loader/windows/icd_windows_apppackage.c loader/windows/icd_windows_apppackage.h loader/windows/OpenCL.def loader/windows/OpenCL.rc) diff --git a/loader/icd.h b/loader/icd.h index dba42aa3..0c9861a9 100644 --- a/loader/icd.h +++ b/loader/icd.h @@ -85,13 +85,7 @@ struct KHRicdVendorRec // the global state extern KHRicdVendor * khrIcdVendors; -#ifdef __cplusplus -extern "C" { -#endif - extern int khrEnableTrace; -#ifdef __cplusplus -} -#endif +extern int khrEnableTrace; #if defined(CL_ENABLE_LAYERS) /* diff --git a/loader/windows/icd_windows_apppackage.c b/loader/windows/icd_windows_apppackage.c new file mode 100644 index 00000000..da08438f --- /dev/null +++ b/loader/windows/icd_windows_apppackage.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2017-2019 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 +#include "icd_windows_apppackage.h" + +#ifdef OPENCL_ICD_LOADER_DISABLE_OPENCLON12 + +bool khrIcdOsVendorsEnumerateAppPackage(void) +{ + KHR_ICD_TRACE("OpenCLOn12 is disabled\n"); + return false; +} + +#else + +#include + +bool khrIcdOsVendorsEnumerateAppPackage(void) +{ + UINT32 numPackages = 0, bufferLength = 0; + PCWSTR familyName = L"Microsoft.D3DMappingLayers_8wekyb3d8bbwe"; + if (ERROR_INSUFFICIENT_BUFFER != GetPackagesByPackageFamily(familyName, + &numPackages, NULL, + &bufferLength, NULL) || + numPackages == 0 || bufferLength == 0) + { + KHR_ICD_TRACE("Failed to find mapping layers packages by family name\n"); + return false; + } + + bool ret = false; + WCHAR *buffer = malloc(sizeof(WCHAR) * bufferLength); + PWSTR *packages = malloc(sizeof(PWSTR) * numPackages); + if (!buffer || !packages) + { + KHR_ICD_TRACE("Failed to allocate memory for package names\n"); + goto cleanup; + } + + if (ERROR_SUCCESS != GetPackagesByPackageFamily(familyName, + &numPackages, packages, + &bufferLength, buffer)) + { + KHR_ICD_TRACE("Failed to get mapping layers package full names\n"); + goto cleanup; + } + + UINT32 pathLength = 0; + WCHAR path[MAX_PATH]; + if (ERROR_INSUFFICIENT_BUFFER != GetPackagePathByFullName(packages[0], &pathLength, NULL) || + pathLength > MAX_PATH || + ERROR_SUCCESS != GetPackagePathByFullName(packages[0], &pathLength, path)) + { + KHR_ICD_TRACE("Failed to get mapping layers package path length\n"); + goto cleanup; + } + +#if defined(_M_AMD64) +#define PLATFORM_PATH L"x64" +#elif defined(_M_ARM) +#define PLATFORM_PATH L"arm" +#elif defined(_M_ARM64) +#define PLATFORM_PATH L"arm64" +#elif defined(_M_IX86) +#define PLATFORM_PATH L"x86" +#endif + + wchar_t dllPath[MAX_PATH]; + wcscpy_s(dllPath, MAX_PATH, path); + wcscat_s(dllPath, MAX_PATH, L"\\" PLATFORM_PATH L"\\OpenCLOn12.dll"); + + char narrowDllPath[MAX_PATH]; + WideCharToMultiByte(CP_ACP, 0, dllPath, -1, narrowDllPath, MAX_PATH, NULL, NULL); + + ret = adapterAdd(narrowDllPath, ZeroLuid); + +cleanup: + free(buffer); + free(packages); + return ret; +} + +#endif diff --git a/loader/windows/icd_windows_apppackage.cpp b/loader/windows/icd_windows_apppackage.cpp deleted file mode 100644 index b305c5db..00000000 --- a/loader/windows/icd_windows_apppackage.cpp +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (c) 2017-2019 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_windows.h" - -#ifdef OPENCL_ICD_LOADER_DISABLE_OPENCLON12 - -extern "C" bool khrIcdOsVendorsEnumerateAppPackage() -{ - KHR_ICD_TRACE("OpenCLOn12 is disabled\n"); - return false; -} - -#else - -#include "icd_windows_apppackage.h" - -#include -#include -#include - -#include -#include - -template -struct ScopeExit { - ScopeExit(F&& f) : f(std::forward(f)) {} - ~ScopeExit() { f(); } - F f; -}; - -template -inline ScopeExit MakeScopeExit(F&& f) { - return ScopeExit(std::forward(f)); -}; - -using namespace Microsoft::WRL; -using namespace Microsoft::WRL::Wrappers; - -extern "C" bool khrIcdOsVendorsEnumerateAppPackage() -{ - HRESULT hrInit = Windows::Foundation::Initialize(RO_INIT_MULTITHREADED); - if (hrInit == RPC_E_CHANGED_MODE) - { - hrInit = Windows::Foundation::Initialize(RO_INIT_SINGLETHREADED); - } - if (FAILED(hrInit)) - { - KHR_ICD_TRACE("Failed to init WinRT\n"); - return false; - } - auto Cleanup = MakeScopeExit([]() - { - Windows::Foundation::Uninitialize(); - }); - - using ABI::Windows::Management::Deployment::IPackageManager; - ComPtr packageManager; - if (FAILED(Windows::Foundation::ActivateInstance( - HStringReference(RuntimeClass_Windows_Management_Deployment_PackageManager).Get(), - &packageManager))) - { - KHR_ICD_TRACE("Failed to get package manager\n"); - return false; - } - - using IPackageCollection = ABI::Windows::Foundation::Collections::__FIIterable_1_Windows__CApplicationModel__CPackage_t; - ComPtr collection; - if (FAILED(packageManager->FindPackagesByUserSecurityIdPackageFamilyName( - HStringReference(L"").Get(), - HStringReference(L"Microsoft.D3DMappingLayers_8wekyb3d8bbwe").Get(), - &collection))) - { - KHR_ICD_TRACE("Failed to find mapping layers package\n"); - return false; - } - - using IPackageIterator = ABI::Windows::Foundation::Collections::IIterator< - ABI::Windows::ApplicationModel::Package*>; - ComPtr iter; - if (FAILED(collection->First(&iter))) - { - KHR_ICD_TRACE("Failed to get package collection iterator\n"); - return false; - } - - while ([&iter]() - { - boolean hasCurrent = false; - return SUCCEEDED(iter->get_HasCurrent(&hasCurrent)) && hasCurrent; - }()) - { - using ABI::Windows::ApplicationModel::IPackage; - ComPtr package; - if (FAILED(iter->get_Current(&package))) - { - KHR_ICD_TRACE("Failed to get package\n"); - boolean hasCurrent = false; - (void)iter->MoveNext(&hasCurrent); - continue; - } - - boolean hasCurrent = false; - (void)iter->MoveNext(&hasCurrent); - - using ABI::Windows::Storage::IStorageFolder; - ComPtr folder; - if (FAILED(package->get_InstalledLocation(&folder))) - { - KHR_ICD_TRACE("Failed to get package install folder\n"); - continue; - } - - using ABI::Windows::Storage::IStorageItem; - ComPtr item; - if (FAILED(folder.As(&item))) - { - KHR_ICD_TRACE("Failed to convert folder to storage item\n"); - continue; - } - - HString path; - if (FAILED(item->get_Path(path.GetAddressOf()))) - { - KHR_ICD_TRACE("Failed to get path\n"); - continue; - } - - UINT pathSize = 0; - auto rawPath = path.GetRawBuffer(&pathSize); - if (pathSize == 0 || rawPath == nullptr) - { - KHR_ICD_TRACE("Failed to get path\n"); - continue; - } - -#if defined(_M_AMD64) -#define PLATFORM_PATH L"x64" -#elif defined(_M_ARM) -#define PLATFORM_PATH L"arm" -#elif defined(_M_ARM64) -#define PLATFORM_PATH L"arm64" -#elif defined(_M_IX86) -#define PLATFORM_PATH L"x86" -#endif - - wchar_t dllPath[MAX_PATH]; - wcscpy_s(dllPath, rawPath); - wcscat_s(dllPath, L"\\" PLATFORM_PATH L"\\OpenCLOn12.dll"); - - std::wstring_convert> convert; - std::string narrowDllPath = convert.to_bytes(dllPath); - - adapterAdd(narrowDllPath.c_str(), {}); - return true; - } - return false; -} - -#endif diff --git a/loader/windows/icd_windows_apppackage.h b/loader/windows/icd_windows_apppackage.h index d4c55da3..5419ad45 100644 --- a/loader/windows/icd_windows_apppackage.h +++ b/loader/windows/icd_windows_apppackage.h @@ -19,7 +19,4 @@ #include #include "icd_windows.h" -#ifdef __cplusplus -extern "C" -#endif bool khrIcdOsVendorsEnumerateAppPackage(void);