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 <ben.ashbaugh@intel.com>
Co-authored-by: Ben Ashbaugh <ben.ashbaugh@intel.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 06c87bf..c8d5e0e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -69,7 +69,6 @@
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 @@
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 dba42aa..0c9861a 100644
--- a/loader/icd.h
+++ b/loader/icd.h
@@ -85,13 +85,7 @@
// 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 0000000..da08438
--- /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 <icd.h>
+#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 <AppModel.h>
+
+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 b305c5d..0000000
--- 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 <windows.management.deployment.h>
-#include <wrl/client.h>
-#include <wrl/wrappers/corewrappers.h>
-
-#include <locale>
-#include <codecvt>
-
-template <typename F>
-struct ScopeExit {
- ScopeExit(F&& f) : f(std::forward<F>(f)) {}
- ~ScopeExit() { f(); }
- F f;
-};
-
-template <typename F>
-inline ScopeExit<F> MakeScopeExit(F&& f) {
- return ScopeExit<F>(std::forward<F>(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<IPackageManager> 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<IPackageCollection> 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<IPackageIterator> 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<IPackage> 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<IStorageFolder> folder;
- if (FAILED(package->get_InstalledLocation(&folder)))
- {
- KHR_ICD_TRACE("Failed to get package install folder\n");
- continue;
- }
-
- using ABI::Windows::Storage::IStorageItem;
- ComPtr<IStorageItem> 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<std::codecvt_utf8<wchar_t>> 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 d4c55da..5419ad4 100644
--- a/loader/windows/icd_windows_apppackage.h
+++ b/loader/windows/icd_windows_apppackage.h
@@ -19,7 +19,4 @@
#include <stdbool.h>
#include "icd_windows.h"
-#ifdef __cplusplus
-extern "C"
-#endif
bool khrIcdOsVendorsEnumerateAppPackage(void);