Remove link-time dependency on WDK
authorNikhil Joshi <nikhilj@nvidia.com>
Wed, 30 Oct 2019 13:58:52 +0000 (19:28 +0530)
committerNikhil Joshi <nikhilj@nvidia.com>
Wed, 18 Dec 2019 15:32:22 +0000 (21:02 +0530)
Recent changes for using QueryAdapter and DXGI APIs
for enumerating platforms on Windows added a dependency on
WDK for linking OpenCL driver to Windows specific
libraries.

Querying function address using GetProcAddress for new QueryAdapterInfo
function so that there is no need to link to WDK while
building OpenCL ICD loader.

Also, removing knob OPENCL_ICD_LOADER_REQUIRE_WDK
needed because of link-time dependency on WDK.

Update README to reflect the changes wrt WDK dependency.

While at it -
1. Fix variable names to use camelCase.
2. Use realloc instead of malloc for reallocating memory for adapters.

CMakeLists.txt
README.md
loader/windows/icd_windows.c
loader/windows/icd_windows_dxgk.c

index 4bafa862e2dd336f80fa3c31948dbef0169d8589..525af511039c9dc0585eb8a96cfa37d8ff7ae01b 100644 (file)
@@ -80,26 +80,23 @@ set_target_properties (OpenCL PROPERTIES VERSION "1.2" SOVERSION "1")
 if (WIN32)
     target_link_libraries (OpenCL cfgmgr32.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(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()
+    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()
 
     if(NOT USE_DYNAMIC_VCXX_RUNTIME)
index 099f3a6cd47033443857c87c8bc2cc1bca660c27..827f07c61f8538cb01ff8fd8d21461d9ec786d9c 100644 (file)
--- a/README.md
+++ b/README.md
@@ -30,14 +30,11 @@ The OpenCL ICD Loader requires OpenCL Headers.
 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.
+OpenCL ICD Loader on Windows now requires the Windows Driver Kit (WDK). 
+While WDK headers are sufficient to be able to build OpenCL ICD Loader, you will need WDK libraries for it to function correctly. 
+Not having WDK installed may prevent the OpenCL ICD Loader from enumerating some OpenCL implementations on latest Windows versions.
+So, we advise that you install recent Windows WDK currently available at -
+* https://docs.microsoft.com/en-us/windows-hardware/drivers/download-the-wdk
 
 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).
index 46e261e4b2ff687d593521ce881d7f1d7a3ae952..00c4c02f698075dfe29465a08a963322afa29708 100644 (file)
@@ -58,16 +58,11 @@ BOOL adapterAdd(const char* szName, LUID luid)
             newCapacity *= 2;
        }
 
-        WinAdapter* pNewBegin = malloc(newCapacity * sizeof(*pWinAdapterBegin));
+        WinAdapter* pNewBegin = realloc(pWinAdapterBegin, 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;
@@ -93,6 +88,7 @@ void adapterFree(WinAdapter *pWinAdapter)
 {
     free(pWinAdapter->szName);
     pWinAdapter->szName = NULL;
+    pWinAdapter->luid = ZeroLuid;
 }
 
 /*
index c55cbf7bff8b13638b45b1fd660af10a19f932fe..42ca4844b6dd910795e5fbb81abd4cbcfd904b06 100644 (file)
@@ -26,7 +26,7 @@
 typedef LONG NTSTATUS;
 #define STATUS_SUCCESS  ((NTSTATUS)0x00000000L)
 #define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023)
-#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
+#define NT_SUCCESS(status) (((NTSTATUS)(status)) >= 0)
 #endif
 
 #include <d3dkmthk.h>
@@ -36,7 +36,6 @@ 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");
@@ -47,7 +46,7 @@ bool khrIcdOsVendorsEnumerateDXGK(void)
     {
         D3DKMT_ADAPTERINFO* pAdapterInfo = NULL;
         D3DKMT_ENUMADAPTERS2 EnumAdapters;
-        NTSTATUS Status = STATUS_SUCCESS;
+        NTSTATUS status = STATUS_SUCCESS;
 
         char cszLibraryName[MAX_PATH] = { 0 };
         EnumAdapters.NumAdapters = 0;
@@ -62,13 +61,13 @@ bool khrIcdOsVendorsEnumerateDXGK(void)
         {
             EnumAdapters.NumAdapters = 0;
             EnumAdapters.pAdapters = NULL;
-            Status = pEnumAdapters2(&EnumAdapters);
-            if (Status == STATUS_BUFFER_TOO_SMALL)
+            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");
                 goto out;
@@ -82,14 +81,21 @@ bool khrIcdOsVendorsEnumerateDXGK(void)
             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");
             goto out;
         }
         const char* cszOpenCLRegKeyName = getOpenCLRegKeyName();
         const int szOpenCLRegKeyName = (int)(strlen(cszOpenCLRegKeyName) + 1)*sizeof(cszOpenCLRegKeyName[0]);
+        PFND3DKMT_QUERYADAPTERINFO pQueryAdapterInfo = (PFND3DKMT_QUERYADAPTERINFO)GetProcAddress((HMODULE)h, "D3DKMTQueryAdapterInfo");
+        if (!pQueryAdapterInfo)
+        {
+            KHR_ICD_TRACE("GetProcAddress failed for D3DKMT_ENUMADAPTERS2\n");
+            goto out;
+        }
+       
         for (UINT AdapterIndex = 0; AdapterIndex < EnumAdapters.NumAdapters; AdapterIndex++)
         {
             D3DDDI_QUERYREGISTRY_INFO queryArgs = {0};
@@ -115,14 +121,14 @@ bool khrIcdOsVendorsEnumerateDXGK(void)
             queryAdapterInfo.Type = KMTQAITYPE_QUERYREGISTRY;
             queryAdapterInfo.pPrivateDriverData = &queryArgs;
             queryAdapterInfo.PrivateDriverDataSize = sizeof(queryArgs);
-            Status = D3DKMTQueryAdapterInfo(&queryAdapterInfo);
-            if (!NT_SUCCESS(Status))
+            status = pQueryAdapterInfo(&queryAdapterInfo);
+            if (!NT_SUCCESS(status))
             {
                 // 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)
+            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);
@@ -131,10 +137,10 @@ bool khrIcdOsVendorsEnumerateDXGK(void)
                 memcpy(pQueryBuffer, &queryArgs, sizeof(D3DDDI_QUERYREGISTRY_INFO));
                 queryAdapterInfo.pPrivateDriverData = pQueryBuffer;
                 queryAdapterInfo.PrivateDriverDataSize = queryBufferSize;
-                Status = D3DKMTQueryAdapterInfo(&queryAdapterInfo);
+                status = pQueryAdapterInfo(&queryAdapterInfo);
                 pQueryArgs = pQueryBuffer;
             }
-            if (NT_SUCCESS(Status) && pQueryArgs->Status == D3DDDI_QUERYREGISTRY_STATUS_SUCCESS)
+            if (NT_SUCCESS(status) && pQueryArgs->Status == D3DDDI_QUERYREGISTRY_STATUS_SUCCESS)
             {
                 wchar_t* pWchar = pQueryArgs->OutputString;
                 memset(cszLibraryName, 0, sizeof(cszLibraryName));
@@ -144,7 +150,7 @@ bool khrIcdOsVendorsEnumerateDXGK(void)
                     ret |= adapterAdd(cszLibraryName, pAdapterInfo[AdapterIndex].AdapterLuid);
                 }
             }
-            else if (Status == STATUS_INVALID_PARAMETER && pQueryArgs->Status == D3DDDI_QUERYREGISTRY_STATUS_FAIL)
+            else if (status == STATUS_INVALID_PARAMETER && pQueryArgs->Status == D3DDDI_QUERYREGISTRY_STATUS_FAIL)
             {
                 free(pQueryBuffer);
                 goto out;
@@ -157,7 +163,6 @@ out:
 
     FreeLibrary(h);
 
-#endif
 #endif
     return ret;
 }