remove WDK dependency for OpenCL ICD loader (#102)
* remove dependency on Windows WDK for Windows ICD Loader builds
After this change, instead of including a WDK header file, a
private header file is used with just the definitions needed
for the ICD loader. The header file is copied unchanged from
the Vulkan loader repo.
* update README to remove WDK dependency
* updated file version to v2.2.8
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7e0b225..9e2d7df 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -50,6 +50,7 @@
if (WIN32)
list (APPEND OPENCL_ICD_LOADER_SOURCES
+ loader/windows/adapter.h
loader/windows/icd_windows.c
loader/windows/icd_windows.h
loader/windows/icd_windows_dxgk.c
@@ -82,28 +83,6 @@
if (WIN32)
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)
- if(DEFINED ENV{WDKContentRoot})
- file(GLOB D3DKMT_HEADER "$ENV{WDKContentRoot}/Include/*/km/d3dkmthk.h")
- else()
- file(GLOB D3DKMT_HEADER "$ENV{HOMEDRIVE}/Program Files */Windows Kits/10/Include/*/km/d3dkmthk.h")
- endif()
-
- if(D3DKMT_HEADER)
- list(GET D3DKMT_HEADER -1 LATEST_D3DKMT_HEADER)
- get_filename_component(WDK_DIRECTORY ${LATEST_D3DKMT_HEADER} DIRECTORY)
- get_filename_component(WDK_DIRECTORY ${WDK_DIRECTORY} DIRECTORY)
- message(STATUS "Found the Windows WDK in: ${WDK_DIRECTORY}")
- target_compile_definitions(OpenCL PRIVATE OPENCL_ICD_LOADER_REQUIRE_WDK)
- target_include_directories(OpenCL PRIVATE ${WDK_DIRECTORY}/um)
- target_include_directories(OpenCL PRIVATE ${WDK_DIRECTORY}/km)
- target_include_directories(OpenCL PRIVATE ${WDK_DIRECTORY}/shared)
- else()
- message(FATAL_ERROR "The Windows WDK was not found. Consider disabling OPENCL_ICD_LOADER_REQUIRE_WDK. Aborting.")
- endif()
- endif()
-
if(NOT USE_DYNAMIC_VCXX_RUNTIME)
string(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
string(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
diff --git a/README.md b/README.md
index 099f3a6..fcea27c 100644
--- a/README.md
+++ b/README.md
@@ -30,15 +30,6 @@
To use system OpenCL Headers, please specify the OpenCL Header location using the CMake variable `OPENCL_ICD_LOADER_HEADERS_DIR`.
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.
-
The OpenCL ICD Loader uses CMake for its build system.
If CMake is not provided by your build system or OS package manager, please consult the [CMake website](https://cmake.org).
diff --git a/loader/windows/OpenCL.rc b/loader/windows/OpenCL.rc
index 38f2c84..2d983f7 100644
--- a/loader/windows/OpenCL.rc
+++ b/loader/windows/OpenCL.rc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019 The Khronos Group Inc.
+ * Copyright (c) 2016-2020 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.
@@ -20,7 +20,7 @@
#define OPENCL_ICD_LOADER_VERSION_MAJOR 2
#define OPENCL_ICD_LOADER_VERSION_MINOR 2
-#define OPENCL_ICD_LOADER_VERSION_REV 7
+#define OPENCL_ICD_LOADER_VERSION_REV 8
#ifdef RC_INVOKED
@@ -43,7 +43,7 @@
BEGIN
VALUE "FileDescription" ,"OpenCL Client DLL"
VALUE "ProductName" ,"Khronos OpenCL ICD Loader"
- VALUE "LegalCopyright" ,"Copyright \251 The Khronos Group Inc 2016-2019"
+ VALUE "LegalCopyright" ,"Copyright \251 The Khronos Group Inc 2016-2020"
VALUE "FileVersion" ,OPENCL_ICD_LOADER_VERSION_STRING ".0"
VALUE "CompanyName" ,"Khronos Group"
VALUE "InternalName" ,"OpenCL"
diff --git a/loader/windows/adapter.h b/loader/windows/adapter.h
new file mode 100644
index 0000000..ef97d66
--- /dev/null
+++ b/loader/windows/adapter.h
@@ -0,0 +1,80 @@
+/*
+* Copyright (c) 2019 The Khronos Group Inc.
+* Copyright (c) 2019 Valve Corporation
+* Copyright (c) 2019 LunarG, 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.
+*
+* Author: Lenny Komow <lenny@lunarg.com>
+*/
+
+typedef struct LoaderEnumAdapters2 {
+ ULONG adapter_count;
+ struct {
+ UINT handle;
+ LUID luid;
+ ULONG source_count;
+ BOOL present_move_regions_preferred;
+ } * adapters;
+} LoaderEnumAdapters2;
+
+typedef _Check_return_ NTSTATUS(APIENTRY *PFN_LoaderEnumAdapters2)(const LoaderEnumAdapters2 *);
+
+typedef enum AdapterInfoType {
+ LOADER_QUERY_TYPE_REGISTRY = 48,
+} AdapterInfoType;
+
+typedef struct LoaderQueryAdapterInfo {
+ UINT handle;
+ AdapterInfoType type;
+ VOID *private_data;
+ UINT private_data_size;
+} LoaderQueryAdapterInfo;
+
+typedef _Check_return_ NTSTATUS(APIENTRY *PFN_LoaderQueryAdapterInfo)(const LoaderQueryAdapterInfo *);
+
+typedef enum LoaderQueryRegistryType {
+ LOADER_QUERY_REGISTRY_ADAPTER_KEY = 1,
+} LoaderQueryRegistryType;
+
+typedef enum LoaderQueryRegistryStatus {
+ LOADER_QUERY_REGISTRY_STATUS_SUCCESS = 0,
+ LOADER_QUERY_REGISTRY_STATUS_BUFFER_OVERFLOW = 1,
+} LoaderQueryRegistryStatus;
+
+typedef struct LoaderQueryRegistryFlags {
+ union {
+ struct {
+ UINT translate_path : 1;
+ UINT mutable_value : 1;
+ UINT reserved : 30;
+ };
+ UINT value;
+ };
+} LoaderQueryRegistryFlags;
+
+typedef struct LoaderQueryRegistryInfo {
+ LoaderQueryRegistryType query_type;
+ LoaderQueryRegistryFlags query_flags;
+ WCHAR value_name[MAX_PATH];
+ ULONG value_type;
+ ULONG physical_adapter_index;
+ ULONG output_value_size;
+ LoaderQueryRegistryStatus status;
+ union {
+ DWORD output_dword;
+ UINT64 output_qword;
+ WCHAR output_string[1];
+ BYTE output_binary[1];
+ };
+} LoaderQueryRegistryInfo;
diff --git a/loader/windows/icd_windows_dxgk.c b/loader/windows/icd_windows_dxgk.c
index d16986b..6f1568e 100644
--- a/loader/windows/icd_windows_dxgk.c
+++ b/loader/windows/icd_windows_dxgk.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 The Khronos Group Inc.
+ * Copyright (c) 2017-2020 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.
@@ -19,109 +19,109 @@
#include "icd.h"
#include "icd_windows_dxgk.h"
-#if defined(OPENCL_ICD_LOADER_REQUIRE_WDK)
#include <windows.h>
+#include "adapter.h"
#ifndef NTSTATUS
typedef LONG NTSTATUS;
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023)
-#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
-#endif
-
-#include <d3dkmthk.h>
+#define NT_SUCCESS(status) (((NTSTATUS)(status)) >= 0)
#endif
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
+ if(GetProcAddress(h, "D3DKMTSubmitPresentBltToHwQueue")) // OS Version check
{
- D3DKMT_ADAPTERINFO* pAdapterInfo = NULL;
- D3DKMT_ENUMADAPTERS2 EnumAdapters;
- NTSTATUS Status = STATUS_SUCCESS;
+ LoaderEnumAdapters2 EnumAdapters;
+ NTSTATUS status = STATUS_SUCCESS;
char cszLibraryName[MAX_PATH] = { 0 };
- EnumAdapters.NumAdapters = 0;
- EnumAdapters.pAdapters = NULL;
- PFND3DKMT_ENUMADAPTERS2 pEnumAdapters2 = (PFND3DKMT_ENUMADAPTERS2)GetProcAddress((HMODULE)h, "D3DKMTEnumAdapters2");
+ EnumAdapters.adapter_count = 0;
+ EnumAdapters.adapters = NULL;
+ PFN_LoaderEnumAdapters2 pEnumAdapters2 = (PFN_LoaderEnumAdapters2)GetProcAddress(h, "D3DKMTEnumAdapters2");
if (!pEnumAdapters2)
{
- KHR_ICD_TRACE("GetProcAddress failed for D3DKMT_ENUMADAPTERS2\n");
+ KHR_ICD_TRACE("GetProcAddress failed for D3DKMTEnumAdapters2\n");
+ goto out;
+ }
+ PFN_LoaderQueryAdapterInfo pQueryAdapterInfo = (PFN_LoaderQueryAdapterInfo)GetProcAddress(h, "D3DKMTQueryAdapterInfo");
+ if (!pQueryAdapterInfo)
+ {
+ KHR_ICD_TRACE("GetProcAddress failed for D3DKMTQueryAdapterInfo\n");
goto out;
}
while (1)
{
- EnumAdapters.NumAdapters = 0;
- EnumAdapters.pAdapters = NULL;
- Status = pEnumAdapters2(&EnumAdapters);
- if (Status == STATUS_BUFFER_TOO_SMALL)
+ EnumAdapters.adapter_count = 0;
+ EnumAdapters.adapters = NULL;
+ status = pEnumAdapters2(&EnumAdapters);
+ if (status == STATUS_BUFFER_TOO_SMALL)
{
// Number of Adapters increased between calls, retry;
continue;
}
- else if (!NT_SUCCESS(Status))
+ else if (!NT_SUCCESS(status))
{
- KHR_ICD_TRACE("D3DKMT_ENUMADAPTERS2 status != SUCCESS\n");
+ KHR_ICD_TRACE("D3DKMTEnumAdapters2 status != SUCCESS\n");
goto out;
}
break;
}
- pAdapterInfo = (D3DKMT_ADAPTERINFO*)malloc(sizeof(D3DKMT_ADAPTERINFO)*(EnumAdapters.NumAdapters));
- if (pAdapterInfo == NULL)
+ EnumAdapters.adapters = malloc(sizeof(*EnumAdapters.adapters)*(EnumAdapters.adapter_count));
+ if (EnumAdapters.adapters == NULL)
{
- KHR_ICD_TRACE("Allocation failure for AdapterInfo buffer\n");
+ KHR_ICD_TRACE("Allocation failure for adapters buffer\n");
goto out;
}
- EnumAdapters.pAdapters = pAdapterInfo;
- Status = pEnumAdapters2(&EnumAdapters);
- if (!NT_SUCCESS(Status))
+ status = pEnumAdapters2(&EnumAdapters);
+ if (!NT_SUCCESS(status))
{
- KHR_ICD_TRACE("D3DKMT_ENUMADAPTERS2 status != SUCCESS\n");
+ KHR_ICD_TRACE("D3DKMTEnumAdapters2 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++)
+ for (UINT AdapterIndex = 0; AdapterIndex < EnumAdapters.adapter_count; AdapterIndex++)
{
- 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;
+ LoaderQueryRegistryInfo queryArgs = {0};
+ LoaderQueryRegistryInfo* pQueryArgs = &queryArgs;
+ LoaderQueryRegistryInfo* pQueryBuffer = NULL;
+ queryArgs.query_type = LOADER_QUERY_REGISTRY_ADAPTER_KEY;
+ queryArgs.query_flags.translate_path = TRUE;
+ queryArgs.value_type = REG_SZ;
result = MultiByteToWideChar(
CP_ACP,
0,
cszOpenCLRegKeyName,
szOpenCLRegKeyName,
- queryArgs.ValueName,
- ARRAYSIZE(queryArgs.ValueName));
+ queryArgs.value_name,
+ ARRAYSIZE(queryArgs.value_name));
if (!result)
{
KHR_ICD_TRACE("MultiByteToWideChar status != SUCCESS\n");
continue;
}
- 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))
+ LoaderQueryAdapterInfo queryAdapterInfo = {0};
+ queryAdapterInfo.handle = EnumAdapters.adapters[AdapterIndex].handle;
+ queryAdapterInfo.type = LOADER_QUERY_TYPE_REGISTRY;
+ queryAdapterInfo.private_data = &queryArgs;
+ queryAdapterInfo.private_data_size = sizeof(queryArgs);
+ status = pQueryAdapterInfo(&queryAdapterInfo);
+ if (!NT_SUCCESS(status))
{
// 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))
+ queryArgs.value_type = REG_MULTI_SZ;
+ status = pQueryAdapterInfo(&queryAdapterInfo);
+ if (NT_SUCCESS(status))
{
KHR_ICD_TRACE("Accepting multi-string registry key type\n");
}
@@ -132,29 +132,30 @@
continue;
}
}
- if (NT_SUCCESS(Status) && pQueryArgs->Status == D3DDDI_QUERYREGISTRY_STATUS_BUFFER_OVERFLOW)
+ if (NT_SUCCESS(status) && pQueryArgs->status == LOADER_QUERY_REGISTRY_STATUS_BUFFER_OVERFLOW)
{
- ULONG queryBufferSize = sizeof(D3DDDI_QUERYREGISTRY_INFO) + queryArgs.OutputValueSize;
- pQueryBuffer = (D3DDDI_QUERYREGISTRY_INFO*)malloc(queryBufferSize);
+ ULONG queryBufferSize = sizeof(LoaderQueryRegistryInfo) + queryArgs.output_value_size;
+ pQueryBuffer = malloc(queryBufferSize);
if (pQueryBuffer == NULL)
continue;
- memcpy(pQueryBuffer, &queryArgs, sizeof(D3DDDI_QUERYREGISTRY_INFO));
- queryAdapterInfo.pPrivateDriverData = pQueryBuffer;
- queryAdapterInfo.PrivateDriverDataSize = queryBufferSize;
- Status = D3DKMTQueryAdapterInfo(&queryAdapterInfo);
+ memcpy(pQueryBuffer, &queryArgs, sizeof(LoaderQueryRegistryInfo));
+ queryAdapterInfo.private_data = pQueryBuffer;
+ queryAdapterInfo.private_data_size = queryBufferSize;
+ status = pQueryAdapterInfo(&queryAdapterInfo);
pQueryArgs = pQueryBuffer;
}
- if (NT_SUCCESS(Status) && pQueryArgs->Status == D3DDDI_QUERYREGISTRY_STATUS_SUCCESS)
+ if (NT_SUCCESS(status) && pQueryArgs->status == LOADER_QUERY_REGISTRY_STATUS_SUCCESS)
{
- wchar_t* pWchar = pQueryArgs->OutputString;
+ wchar_t* pWchar = pQueryArgs->output_string;
memset(cszLibraryName, 0, sizeof(cszLibraryName));
{
- size_t len = wcstombs(cszLibraryName, pWchar, sizeof(cszLibraryName));
+ size_t len;
+ wcstombs_s(&len, cszLibraryName, sizeof(cszLibraryName), pWchar, sizeof(cszLibraryName));
KHR_ICD_ASSERT(len == (sizeof(cszLibraryName) - 1));
- ret |= adapterAdd(cszLibraryName, pAdapterInfo[AdapterIndex].AdapterLuid);
+ ret |= adapterAdd(cszLibraryName, EnumAdapters.adapters[AdapterIndex].luid);
}
}
- else if (Status == STATUS_INVALID_PARAMETER && pQueryArgs->Status == D3DDDI_QUERYREGISTRY_STATUS_FAIL)
+ else if (status == STATUS_INVALID_PARAMETER)
{
free(pQueryBuffer);
goto out;
@@ -162,12 +163,10 @@
free(pQueryBuffer);
}
out:
- free(pAdapterInfo);
+ free(EnumAdapters.adapters);
}
FreeLibrary(h);
-#endif
-#endif
return ret;
}