Promote Khronos OpenCL-ICD-Loader master

master as of https://github.com/KhronosGroup/OpenCL-ICD-Loader/
commit/c7fda8bb042760b5ead8650c64445f5972a64ad7

Change-Id: Ia852f55ecf0b0aceff915991328812ed9788698f


[ROCm/clr commit: 49f3835666]
This commit is contained in:
Saleel Kudchadker
2020-03-24 10:31:31 -07:00
zatwierdzone przez Aakash Sudhanwa
rodzic 5029a7b467
commit 8c8ad8153f
14 zmienionych plików z 279 dodań i 1511 usunięć
@@ -1,20 +0,0 @@
os:
- Visual Studio 2017
#- Visual Studio 2015
platform:
- Win32
- x64
configuration:
- Debug
- Release
before_build:
- git clone --depth=1 https://github.com/KhronosGroup/OpenCL-Headers inc/OpenCL-Headers
- cmake -DOPENCL_ICD_LOADER_HEADERS_DIR=inc/OpenCL-Headers -H. -Bbuild -A%PLATFORM%
build:
project: build\OPENCL_ICD_LOADER.sln
parallel: true
verbosity: normal
@@ -1,18 +0,0 @@
language: cpp
compiler:
- gcc
#- clang
os:
- linux
#- osx
before_install:
- git clone https://github.com/KhronosGroup/OpenCL-Headers inc/OpenCL-Headers
script:
- mkdir -p build
- cd build
- cmake -DOPENCL_ICD_LOADER_HEADERS_DIR=../inc/OpenCL-Headers ..
- make
@@ -51,6 +51,7 @@ set (OPENCL_ICD_LOADER_SOURCES
if (WIN32)
list (APPEND OPENCL_ICD_LOADER_SOURCES
loader/windows/icd_windows.c
loader/windows/icd_windows.h
loader/windows/icd_windows_dxgk.c
loader/windows/icd_windows_dxgk.h
loader/windows/icd_windows_envvars.c
@@ -31,6 +31,11 @@ To use system OpenCL Headers, please specify the OpenCL Header location using th
By default, the OpenCL ICD Loader will look for OpenCL Headers in the `inc` directory.
By default, the OpenCL ICD Loader on Windows requires the Windows Driver Kit (WDK).
To build OpenCL ICD Loader with WDK support -
* Install recent Windows WDK currently at https://docs.microsoft.com/en-us/windows-hardware/drivers/download-the-wdk
* Establish environment variable WDK to include directory. Ex: set WDK=C:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0
An OpenCL ICD Loader may be built without the Windows Driver Kit using the CMake variable `OPENCL_ICD_LOADER_REQUIRE_WDK`, however this option should be used with caution since it may prevent the OpenCL ICD Loader from enumerating some OpenCL implementations.
This dependency may be removed in the future.
@@ -172,4 +172,3 @@ void khrIcdOsLibraryUnload(void *library)
{
dlclose(library);
}
@@ -20,7 +20,7 @@
#define OPENCL_ICD_LOADER_VERSION_MAJOR 2
#define OPENCL_ICD_LOADER_VERSION_MINOR 2
#define OPENCL_ICD_LOADER_VERSION_REV 3
#define OPENCL_ICD_LOADER_VERSION_REV 6
#ifdef RC_INVOKED
@@ -17,14 +17,84 @@
*/
#include "icd.h"
#include "icd_windows.h"
#include "icd_windows_hkr.h"
#include "icd_windows_dxgk.h"
#include <stdio.h>
#include <windows.h>
#include <winreg.h>
#include <initguid.h>
#include <dxgi.h>
typedef HRESULT (WINAPI *PFN_CREATE_DXGI_FACTORY)(REFIID, void **);
static INIT_ONCE initialized = INIT_ONCE_STATIC_INIT;
typedef struct WinAdapter
{
char * szName;
LUID luid;
} WinAdapter;
const LUID ZeroLuid = { 0, 0 };
static WinAdapter* pWinAdapterBegin = NULL;
static WinAdapter* pWinAdapterEnd = NULL;
static WinAdapter* pWinAdapterCapacity = NULL;
BOOL adapterAdd(const char* szName, LUID luid)
{
BOOL result = TRUE;
if (pWinAdapterEnd == pWinAdapterCapacity)
{
size_t oldCapacity = pWinAdapterCapacity - pWinAdapterBegin;
size_t newCapacity = oldCapacity;
if (0 == newCapacity)
{
newCapacity = 1;
}
else if(newCapacity < UINT_MAX/2)
{
newCapacity *= 2;
}
WinAdapter* pNewBegin = malloc(newCapacity * sizeof(*pWinAdapterBegin));
if (!pNewBegin)
result = FALSE;
else
{
if (pWinAdapterBegin)
{
memcpy(pNewBegin, pWinAdapterBegin, oldCapacity * sizeof(*pWinAdapterBegin));
free(pWinAdapterBegin);
}
pWinAdapterCapacity = pNewBegin + newCapacity;
pWinAdapterEnd = pNewBegin + oldCapacity;
pWinAdapterBegin = pNewBegin;
}
}
if (pWinAdapterEnd != pWinAdapterCapacity)
{
size_t nameLen = (strlen(szName) + 1)*sizeof(szName[0]);
pWinAdapterEnd->szName = malloc(nameLen);
if (!pWinAdapterEnd->szName)
result = FALSE;
else
{
memcpy(pWinAdapterEnd->szName, szName, nameLen);
pWinAdapterEnd->luid = luid;
++pWinAdapterEnd;
}
}
return result;
}
void adapterFree(WinAdapter *pWinAdapter)
{
free(pWinAdapter->szName);
pWinAdapter->szName = NULL;
}
/*
*
* Vendor enumeration functions
@@ -36,16 +106,19 @@ static INIT_ONCE initialized = INIT_ONCE_STATIC_INIT;
BOOL CALLBACK khrIcdOsVendorsEnumerate(PINIT_ONCE InitOnce, PVOID Parameter, PVOID *lpContext)
{
LONG result;
BOOL status = FALSE;
const char* platformsName = "SOFTWARE\\Khronos\\OpenCL\\Vendors";
HKEY platformsKey = NULL;
DWORD dwIndex;
khrIcdVendorsEnumerateEnv();
if (!khrIcdOsVendorsEnumerateDXGK())
status |= khrIcdOsVendorsEnumerateDXGK();
if (!status)
{
KHR_ICD_TRACE("Failed to load via DXGK interface on RS4, continuing\n");
if (!khrIcdOsVendorsEnumerateHKR())
status |= khrIcdOsVendorsEnumerateHKR();
if (!status)
{
KHR_ICD_TRACE("Failed to enumerate HKR entries, continuing\n");
}
@@ -103,19 +176,66 @@ BOOL CALLBACK khrIcdOsVendorsEnumerate(PINIT_ONCE InitOnce, PVOID Parameter, PVO
KHR_ICD_TRACE("Value not zero, skipping\n");
continue;
}
// add the library
khrIcdVendorAdd(cszLibraryName);
}
result = RegCloseKey(platformsKey);
if (ERROR_SUCCESS != result)
{
KHR_ICD_TRACE("Failed to close platforms key %s, ignoring\n", platformsName);
status |= adapterAdd(cszLibraryName, ZeroLuid);
}
}
return TRUE;
// Add adapters according to DXGI's preference order
HMODULE hDXGI = LoadLibrary("dxgi.dll");
if (hDXGI)
{
IDXGIFactory* pFactory = NULL;
PFN_CREATE_DXGI_FACTORY pCreateDXGIFactory = (PFN_CREATE_DXGI_FACTORY)GetProcAddress(hDXGI, "CreateDXGIFactory");
if (pCreateDXGIFactory)
{
HRESULT hr = pCreateDXGIFactory(&IID_IDXGIFactory, &pFactory);
if (SUCCEEDED(hr))
{
UINT i = 0;
IDXGIAdapter* pAdapter = NULL;
while (SUCCEEDED(pFactory->lpVtbl->EnumAdapters(pFactory, i++, &pAdapter)))
{
DXGI_ADAPTER_DESC AdapterDesc;
if (SUCCEEDED(pAdapter->lpVtbl->GetDesc(pAdapter, &AdapterDesc)))
{
for (WinAdapter* iterAdapter = pWinAdapterBegin; iterAdapter != pWinAdapterEnd; ++iterAdapter)
{
if (iterAdapter->luid.LowPart == AdapterDesc.AdapterLuid.LowPart
&& iterAdapter->luid.HighPart == AdapterDesc.AdapterLuid.HighPart)
{
khrIcdVendorAdd(iterAdapter->szName);
break;
}
}
}
pAdapter->lpVtbl->Release(pAdapter);
}
pFactory->lpVtbl->Release(pFactory);
}
FreeLibrary(hDXGI);
}
}
// Go through the list again, putting any remaining adapters at the end of the list in an undefined order
for (WinAdapter* iterAdapter = pWinAdapterBegin; iterAdapter != pWinAdapterEnd; ++iterAdapter)
{
khrIcdVendorAdd(iterAdapter->szName);
adapterFree(iterAdapter);
}
free(pWinAdapterBegin);
pWinAdapterBegin = NULL;
pWinAdapterEnd = NULL;
pWinAdapterCapacity = NULL;
result = RegCloseKey(platformsKey);
if (ERROR_SUCCESS != result)
{
KHR_ICD_TRACE("Failed to close platforms key %s, ignoring\n", platformsName);
}
return status;
}
// go through the list of vendors only once
@@ -151,4 +271,3 @@ void khrIcdOsLibraryUnload(void *library)
{
FreeLibrary( (HMODULE)library);
}
@@ -0,0 +1,27 @@
/*
* 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 <windows.h>
extern const LUID ZeroLuid;
BOOL adapterAdd(const char* szName, LUID luid);
// Do not free the memory returned by this function.
const char* getOpenCLRegKeyName(void);
@@ -35,18 +35,23 @@ typedef LONG NTSTATUS;
bool khrIcdOsVendorsEnumerateDXGK(void)
{
bool ret = false;
int result = 0;
#if defined(OPENCL_ICD_LOADER_REQUIRE_WDK)
#if defined(DXGKDDI_INTERFACE_VERSION_WDDM2_4) && (DXGKDDI_INTERFACE_VERSION >= DXGKDDI_INTERFACE_VERSION_WDDM2_4)
// Get handle to GDI Runtime
HMODULE h = LoadLibrary("gdi32.dll");
if (h == NULL)
return ret;
if(GetProcAddress((HMODULE)h, "D3DKMTSubmitPresentBltToHwQueue")) // OS Version check
{
D3DKMT_ADAPTERINFO* pAdapterInfo = NULL;
D3DKMT_ENUMADAPTERS2 EnumAdapters;
NTSTATUS Status = STATUS_SUCCESS;
// Get handle to GDI Runtime
HMODULE h = LoadLibrary("gdi32.dll");
KHR_ICD_ASSERT(h != NULL);
char cszLibraryName[MAX_PATH] = { 0 };
EnumAdapters.NumAdapters = 0;
EnumAdapters.pAdapters = NULL;
PFND3DKMT_ENUMADAPTERS2 pEnumAdapters2 = (PFND3DKMT_ENUMADAPTERS2)GetProcAddress((HMODULE)h, "D3DKMTEnumAdapters2");
if (!pEnumAdapters2)
{
@@ -83,47 +88,60 @@ bool khrIcdOsVendorsEnumerateDXGK(void)
KHR_ICD_TRACE("D3DKMT_ENUMADAPTERS2 status != SUCCESS\n");
goto out;
}
const char* cszOpenCLRegKeyName = getOpenCLRegKeyName();
const int szOpenCLRegKeyName = (int)(strlen(cszOpenCLRegKeyName) + 1)*sizeof(cszOpenCLRegKeyName[0]);
for (UINT AdapterIndex = 0; AdapterIndex < EnumAdapters.NumAdapters; AdapterIndex++)
{
D3DDDI_QUERYREGISTRY_INFO QueryArgs = {0};
D3DDDI_QUERYREGISTRY_INFO* pQueryArgs = &QueryArgs;
D3DDDI_QUERYREGISTRY_INFO queryArgs = {0};
D3DDDI_QUERYREGISTRY_INFO* pQueryArgs = &queryArgs;
D3DDDI_QUERYREGISTRY_INFO* pQueryBuffer = NULL;
QueryArgs.QueryType = D3DDDI_QUERYREGISTRY_ADAPTERKEY;
QueryArgs.QueryFlags.TranslatePath = TRUE;
QueryArgs.ValueType = REG_SZ;
#ifdef _WIN64
wcscpy_s(QueryArgs.ValueName, ARRAYSIZE(L"OpenCLDriverName"), L"OpenCLDriverName");
#else
// There is no WOW prefix for 32bit Windows hence make a specific check
BOOL is_wow64;
if (IsWow64Process(GetCurrentProcess(), &is_wow64) && is_wow64)
queryArgs.QueryType = D3DDDI_QUERYREGISTRY_ADAPTERKEY;
queryArgs.QueryFlags.TranslatePath = TRUE;
queryArgs.ValueType = REG_SZ;
result = MultiByteToWideChar(
CP_ACP,
0,
cszOpenCLRegKeyName,
szOpenCLRegKeyName,
queryArgs.ValueName,
ARRAYSIZE(queryArgs.ValueName));
if (!result)
{
wcscpy_s(QueryArgs.ValueName, ARRAYSIZE(L"OpenCLDriverNameWow"), L"OpenCLDriverNameWow");
KHR_ICD_TRACE("MultiByteToWideChar status != SUCCESS\n");
continue;
}
else
{
wcscpy_s(QueryArgs.ValueName, ARRAYSIZE(L"OpenCLDriverName"), L"OpenCLDriverName");
}
#endif
D3DKMT_QUERYADAPTERINFO QueryAdapterInfo = {0};
QueryAdapterInfo.hAdapter = pAdapterInfo[AdapterIndex].hAdapter;
QueryAdapterInfo.Type = KMTQAITYPE_QUERYREGISTRY;
QueryAdapterInfo.pPrivateDriverData = &QueryArgs;
QueryAdapterInfo.PrivateDriverDataSize = sizeof(QueryArgs);
Status = D3DKMTQueryAdapterInfo(&QueryAdapterInfo);
D3DKMT_QUERYADAPTERINFO queryAdapterInfo = {0};
queryAdapterInfo.hAdapter = pAdapterInfo[AdapterIndex].hAdapter;
queryAdapterInfo.Type = KMTQAITYPE_QUERYREGISTRY;
queryAdapterInfo.pPrivateDriverData = &queryArgs;
queryAdapterInfo.PrivateDriverDataSize = sizeof(queryArgs);
Status = D3DKMTQueryAdapterInfo(&queryAdapterInfo);
if (!NT_SUCCESS(Status))
{
KHR_ICD_TRACE("D3DKMT_QUERYADAPTERINFO status != SUCCESS\n");
goto out;
// Try a different value type. Some vendors write the key as a multi-string type.
queryArgs.ValueType = REG_MULTI_SZ;
Status = D3DKMTQueryAdapterInfo(&queryAdapterInfo);
if (NT_SUCCESS(Status))
{
KHR_ICD_TRACE("Accepting multi-string registry key type\n");
}
else
{
// Continue trying to get as much info on each adapter as possible.
// It's too late to return FALSE and claim WDDM2_4 enumeration is not available here.
continue;
}
}
if (NT_SUCCESS(Status) && pQueryArgs->Status == D3DDDI_QUERYREGISTRY_STATUS_BUFFER_OVERFLOW)
{
ULONG QueryBufferSize = sizeof(D3DDDI_QUERYREGISTRY_INFO) + QueryArgs.OutputValueSize;
pQueryBuffer = (D3DDDI_QUERYREGISTRY_INFO*)malloc(QueryBufferSize);
memcpy(pQueryBuffer, &QueryArgs, sizeof(D3DDDI_QUERYREGISTRY_INFO));
QueryAdapterInfo.pPrivateDriverData = pQueryBuffer;
QueryAdapterInfo.PrivateDriverDataSize = QueryBufferSize;
Status = D3DKMTQueryAdapterInfo(&QueryAdapterInfo);
ULONG queryBufferSize = sizeof(D3DDDI_QUERYREGISTRY_INFO) + queryArgs.OutputValueSize;
pQueryBuffer = (D3DDDI_QUERYREGISTRY_INFO*)malloc(queryBufferSize);
if (pQueryBuffer == NULL)
continue;
memcpy(pQueryBuffer, &queryArgs, sizeof(D3DDDI_QUERYREGISTRY_INFO));
queryAdapterInfo.pPrivateDriverData = pQueryBuffer;
queryAdapterInfo.PrivateDriverDataSize = queryBufferSize;
Status = D3DKMTQueryAdapterInfo(&queryAdapterInfo);
pQueryArgs = pQueryBuffer;
}
if (NT_SUCCESS(Status) && pQueryArgs->Status == D3DDDI_QUERYREGISTRY_STATUS_SUCCESS)
@@ -133,7 +151,7 @@ bool khrIcdOsVendorsEnumerateDXGK(void)
{
size_t len = wcstombs(cszLibraryName, pWchar, sizeof(cszLibraryName));
KHR_ICD_ASSERT(len == (sizeof(cszLibraryName) - 1));
khrIcdVendorAdd(cszLibraryName);
ret |= adapterAdd(cszLibraryName, pAdapterInfo[AdapterIndex].AdapterLuid);
}
}
else if (Status == STATUS_INVALID_PARAMETER && pQueryArgs->Status == D3DDDI_QUERYREGISTRY_STATUS_FAIL)
@@ -143,11 +161,12 @@ bool khrIcdOsVendorsEnumerateDXGK(void)
}
free(pQueryBuffer);
}
ret = true;
out:
free(pAdapterInfo);
FreeLibrary(h);
}
FreeLibrary(h);
#endif
#endif
return ret;
@@ -17,5 +17,6 @@
*/
#include <stdbool.h>
#include "icd_windows.h"
bool khrIcdOsVendorsEnumerateDXGK(void);
@@ -16,6 +16,8 @@
* OpenCL is a trademark of Apple Inc. used under license by Khronos.
*/
#include <icd.h>
#include <stdbool.h>
#include <windows.h>
char *khrIcd_getenv(const char *name) {
@@ -38,7 +40,36 @@ char *khrIcd_getenv(const char *name) {
return retVal;
}
static bool khrIcd_IsHighIntegrityLevel()
{
bool isHighIntegrityLevel = false;
HANDLE processToken;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_QUERY_SOURCE, &processToken)) {
// Maximum possible size of SID_AND_ATTRIBUTES is maximum size of a SID + size of attributes DWORD.
char mandatoryLabelBuffer[SECURITY_MAX_SID_SIZE + sizeof(DWORD)] = {0};
DWORD bufferSize;
if (GetTokenInformation(processToken, TokenIntegrityLevel, mandatoryLabelBuffer, sizeof(mandatoryLabelBuffer),
&bufferSize) != 0) {
const TOKEN_MANDATORY_LABEL* mandatoryLabel = (const TOKEN_MANDATORY_LABEL*)(mandatoryLabelBuffer);
const DWORD subAuthorityCount = *GetSidSubAuthorityCount(mandatoryLabel->Label.Sid);
const DWORD integrityLevel = *GetSidSubAuthority(mandatoryLabel->Label.Sid, subAuthorityCount - 1);
isHighIntegrityLevel = integrityLevel > SECURITY_MANDATORY_MEDIUM_RID;
}
CloseHandle(processToken);
}
return isHighIntegrityLevel;
}
char *khrIcd_secure_getenv(const char *name) {
if (khrIcd_IsHighIntegrityLevel()) {
KHR_ICD_TRACE("Running at a high integrity level, so secure_getenv is returning NULL\n");
return NULL;
}
return khrIcd_getenv(name);
}
@@ -19,6 +19,7 @@
#include "icd.h"
#include "icd_windows_hkr.h"
#include <windows.h>
#include "icd_windows_dxgk.h"
#include <cfgmgr32.h>
#include <assert.h>
#include <stdbool.h>
@@ -51,7 +52,7 @@ static const char OPENCL_REG_SUB_KEY_WOW[] = "OpenCLDriverNameWow";
#endif
// Do not free the memory returned by this function.
static const char* GetOpenCLRegKeyName(void)
const char* getOpenCLRegKeyName(void)
{
#ifdef _WIN64
return OPENCL_REG_SUB_KEY;
@@ -96,7 +97,7 @@ static bool ReadOpenCLKey(DEVINST dnDevNode)
{
result = RegQueryValueExA(
hkey,
GetOpenCLRegKeyName(),
getOpenCLRegKeyName(),
NULL,
&dwLibraryNameType,
NULL,
@@ -117,7 +118,7 @@ static bool ReadOpenCLKey(DEVINST dnDevNode)
result = RegQueryValueExA(
hkey,
GetOpenCLRegKeyName(),
getOpenCLRegKeyName(),
NULL,
&dwLibraryNameType,
(LPBYTE)cszOclPath,
@@ -130,15 +131,20 @@ static bool ReadOpenCLKey(DEVINST dnDevNode)
if (REG_SZ != dwLibraryNameType)
{
KHR_ICD_TRACE("Unexpected registry entry 0x%x! continuing\n", dwLibraryNameType);
goto out;
if (REG_MULTI_SZ == dwLibraryNameType)
{
KHR_ICD_TRACE("Accepting multi-string registry key type\n");
}
else
{
KHR_ICD_TRACE("Unexpected registry entry 0x%x! continuing\n", dwLibraryNameType);
goto out;
}
}
KHR_ICD_TRACE(" Path: %s\n", cszOclPath);
khrIcdVendorAdd(cszOclPath);
bRet = true;
bRet |= adapterAdd(cszOclPath, ZeroLuid);
}
out:
@@ -17,5 +17,6 @@
*/
#include <stdbool.h>
#include "icd_windows.h"
bool khrIcdOsVendorsEnumerateHKR(void);