Promote Khronos OpenCL-ICD-Loader master

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

Change-Id: Ia852f55ecf0b0aceff915991328812ed9788698f
This commit is contained in:
Saleel Kudchadker
2020-03-24 10:31:31 -07:00
committato da Aakash Sudhanwa
parent 4092e3dee3
commit 49f3835666
14 ha cambiato i file con 279 aggiunte e 1511 eliminazioni
-20
Vedi File
@@ -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
-18
Vedi File
@@ -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
+1
Vedi File
@@ -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
+5
Vedi File
@@ -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.
File diff soppresso perché troppo grande Carica Diff
@@ -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);