Skip to content

Commit

Permalink
Add support for OpenCLOn12 ICD (#103)
Browse files Browse the repository at this point in the history
* Add search for OpenCLOn12 mapping layer package.

* Use altered search path for ICD loading.

* Update version to 2.2.7
  • Loading branch information
jenatali committed Apr 16, 2020
1 parent 6d0b214 commit 47f05fa
Show file tree
Hide file tree
Showing 5 changed files with 205 additions and 3 deletions.
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ 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.h
loader/windows/OpenCL.def
loader/windows/OpenCL.rc)
# Only add the DXSDK include directory if the environment variable is
Expand All @@ -78,7 +80,7 @@ add_library (OpenCL ${OPENCL_ICD_LOADER_SOURCES})
set_target_properties (OpenCL PROPERTIES VERSION "1.2" SOVERSION "1")

if (WIN32)
target_link_libraries (OpenCL cfgmgr32.lib)
target_link_libraries (OpenCL cfgmgr32.lib RuntimeObject.lib)

option (OPENCL_ICD_LOADER_REQUIRE_WDK "Build with D3DKMT support, which requires the Windows WDK." ON)
if (OPENCL_ICD_LOADER_REQUIRE_WDK)
Expand Down
2 changes: 1 addition & 1 deletion loader/windows/OpenCL.rc
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

#define OPENCL_ICD_LOADER_VERSION_MAJOR 2
#define OPENCL_ICD_LOADER_VERSION_MINOR 2
#define OPENCL_ICD_LOADER_VERSION_REV 6
#define OPENCL_ICD_LOADER_VERSION_REV 7

#ifdef RC_INVOKED

Expand Down
10 changes: 9 additions & 1 deletion loader/windows/icd_windows.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "icd_windows.h"
#include "icd_windows_hkr.h"
#include "icd_windows_dxgk.h"
#include "icd_windows_apppackage.h"
#include <stdio.h>
#include <windows.h>
#include <winreg.h>
Expand Down Expand Up @@ -123,6 +124,8 @@ BOOL CALLBACK khrIcdOsVendorsEnumerate(PINIT_ONCE InitOnce, PVOID Parameter, PVO
KHR_ICD_TRACE("Failed to enumerate HKR entries, continuing\n");
}
}

status |= khrIcdOsVendorsEnumerateAppPackage();

KHR_ICD_TRACE("Opening key HKLM\\%s...\n", platformsName);
result = RegOpenKeyExA(
Expand Down Expand Up @@ -253,7 +256,12 @@ void khrIcdOsVendorsEnumerateOnce()
// dynamically load a library. returns NULL on failure
void *khrIcdOsLibraryLoad(const char *libraryName)
{
return (void *)LoadLibraryA(libraryName);
HMODULE hTemp = LoadLibraryExA(libraryName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
if (!hTemp && GetLastError() == ERROR_INVALID_PARAMETER)
{
hTemp = LoadLibraryExA(libraryName, NULL, 0);
}
return (void*)hTemp;
}

// get a function pointer from a loaded library. returns NULL on failure.
Expand Down
167 changes: 167 additions & 0 deletions loader/windows/icd_windows_apppackage.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
/*
* 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.
*/

extern "C"
{
#include "icd.h"
#include "icd_windows.h"
}

#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;
}
25 changes: 25 additions & 0 deletions loader/windows/icd_windows_apppackage.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* 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 <stdbool.h>
#include "icd_windows.h"

#ifdef __cplusplus
extern "C"
#endif
bool khrIcdOsVendorsEnumerateAppPackage(void);

2 comments on commit 47f05fa

@hydra3333
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello.
Something broke within the last 10 days. It used to work.
Cross-compiling under ubuntu 18.04.3 for target Win10x64.

[14:17:54][DEBUG] Running 'ninja -j 4 ' in '/home/u/Desktop/_working/workdir/x86_64/OpenCL-ICD-Loader_git'
[1/4] Building CXX object CMakeFiles/OpenCL.dir/loader/windows/icd_windows_apppackage.cpp.obj
FAILED: CMakeFiles/OpenCL.dir/loader/windows/icd_windows_apppackage.cpp.obj 
/home/u/Desktop/_working/workdir/toolchain/x86_64-w64-mingw32/bin/x86_64-w64-mingw32-g++ --sysroot=/home/u/Desktop/_working/workdir/toolchain/x86_64-w64-mingw32  -DCL_TARGET_OPENCL_VERSION=220 -DOpenCL_EXPORTS -Iinc -I. -Iloader -O3  -fstack-protector-all  -D_FORTIFY_SOURCE=2 -O3 -DNDEBUG -MD -MT CMakeFiles/OpenCL.dir/loader/windows/icd_windows_apppackage.cpp.obj -MF CMakeFiles/OpenCL.dir/loader/windows/icd_windows_apppackage.cpp.obj.d -o CMakeFiles/OpenCL.dir/loader/windows/icd_windows_apppackage.cpp.obj -c loader/windows/icd_windows_apppackage.cpp
loader/windows/icd_windows_apppackage.cpp:27:10: fatal error: windows.management.deployment.h: No such file or directory
   27 | #include <windows.management.deployment.h>
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
[2/4] Building C object CMakeFiles/OpenCL.dir/loader/windows/icd_windows_envvars.c.obj
[3/4] Building C object CMakeFiles/OpenCL.dir/loader/windows/icd_windows_hkr.c.obj
FAILED: CMakeFiles/OpenCL.dir/loader/windows/icd_windows_hkr.c.obj 
/home/u/Desktop/_working/workdir/toolchain/x86_64-w64-mingw32/bin/x86_64-w64-mingw32-gcc --sysroot=/home/u/Desktop/_working/workdir/toolchain/x86_64-w64-mingw32 -DCL_TARGET_OPENCL_VERSION=220 -DOpenCL_EXPORTS -Iinc -I. -Iloader -O3  -fstack-protector-all  -D_FORTIFY_SOURCE=2 -O3 -DNDEBUG -MD -MT CMakeFiles/OpenCL.dir/loader/windows/icd_windows_hkr.c.obj -MF CMakeFiles/OpenCL.dir/loader/windows/icd_windows_hkr.c.obj.d -o CMakeFiles/OpenCL.dir/loader/windows/icd_windows_hkr.c.obj   -c loader/windows/icd_windows_hkr.c
loader/windows/icd_windows_hkr.c: In function 'khrIcdOsVendorsEnumerateHKR':
loader/windows/icd_windows_hkr.c:217:21: error: 'CM_GETIDLIST_FILTER_CLASS' undeclared (first use in this function); did you mean 'CM_GETIDLIST_FILTER_BITS'?
  217 |     ULONG ulFlags = CM_GETIDLIST_FILTER_CLASS |
      |                     ^~~~~~~~~~~~~~~~~~~~~~~~~
      |                     CM_GETIDLIST_FILTER_BITS
loader/windows/icd_windows_hkr.c:217:21: note: each undeclared identifier is reported only once for each function it appears in
loader/windows/icd_windows_hkr.c:218:21: error: 'CM_GETIDLIST_FILTER_PRESENT' undeclared (first use in this function); did you mean 'CM_GETIDLIST_FILTER_BITS'?
  218 |                     CM_GETIDLIST_FILTER_PRESENT;
      |                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                     CM_GETIDLIST_FILTER_BITS
loader/windows/icd_windows_hkr.c:343:22: error: 'DEVPKEY_Device_ClassGuid' undeclared (first use in this function)
  343 |                     &DEVPKEY_Device_ClassGuid,
      |                      ^~~~~~~~~~~~~~~~~~~~~~~~
ninja: build stopped: subcommand failed.

@hydra3333
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh dear.

If we copy windows.management.deployment.h" and use that in the cross-compile build process,
we soon discover that it contains other includes which are also missing files.
eg AsyncInfo.h

ICD_LOADER now has specific dependencies for which there are no readily available sources to use in cross-compilation.

Is there another way ?

Please sign in to comment.