Merge pull request #7 from KhronosGroup/master

Merge master branch of Khronos
diff --git a/.appveyor.yml b/.appveyor.yml
new file mode 100644
index 0000000..6b4f86a
--- /dev/null
+++ b/.appveyor.yml
@@ -0,0 +1,20 @@
+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
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..0f09d80
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,18 @@
+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
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c750916..b3f8c0b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -41,12 +41,13 @@
     list (APPEND OPENCL_ICD_LOADER_SOURCES 
         loader/windows/icd_windows.c
         loader/windows/icd_windows_hkr.c
+        loader/windows/icd_windows_dxgk.c
         loader/windows/OpenCL.def
         loader/windows/OpenCL.rc)
     # Only add the DXSDK include directory if the environment variable is
     # defined.  Since the DXSDK has merged into the Windows SDK, this is
     # only required in rare cases.
-    if (DEFINED ENV{DXSDK_DIR})
+    if (DEFINED ENV{DXSDK_DIR} AND NOT (MINGW OR MSYS OR CYGWIN))
         include_directories ($ENV{DXSDK_DIR}/Include)
     endif ()
 else ()
@@ -62,6 +63,29 @@
 
 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(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/Makefile b/Makefile
deleted file mode 100644
index d804cb2..0000000
--- a/Makefile
+++ /dev/null
@@ -1,29 +0,0 @@
-.PHONY: default do_cmake do_build test package
-.PHONY: clean clobber
-
-BUILD_DIR:=build
-
-ICD_VERSION:=$(shell grep FileVersion OpenCL.rc | sed "s/.*\([0-9]\+\.[0-9]\+\.[0-9]\+.[0-9]\+\).*/\1/")
-PACKAGE_PATH:=/tmp/opencl-icd-${ICD_VERSION}.tgz
-
-default: do_build
-
-do_build: do_cmake
-	${MAKE} -C ${BUILD_DIR}
-
-do_cmake:
-	mkdir -p ${BUILD_DIR} && cd ${BUILD_DIR} && cmake ..
-
-test:
-	${MAKE} -C ${BUILD_DIR} test
-
-package: clobber
-	rm -f ${PACKAGE_PATH}
-	tar -C .. -czf ${PACKAGE_PATH} --exclude .git .gitignore icd
-	@echo "Package created at ${PACKAGE_PATH}"
-
-clean:
-	${MAKE} -C ${BUILD_DIR} clean
-
-clobber:
-	rm -rf ${BUILD_DIR}
diff --git a/README.md b/README.md
index 8d22438..27c1de7 100644
--- a/README.md
+++ b/README.md
@@ -1,49 +1,118 @@
-# Building the OpenCL ICD Loader and Tests
+# OpenCL ICD Loader
 
-The build system will build ICD Loader library (OpenCL.dll or libOpenCL.so), the
-ICD Loader Test binary (icd_loader_test), and some helper libraries for the test.
+This repo contains the source code and tests for the Khronos official OpenCL ICD Loader.
 
-## Linux
+## CI Build Status
 
-Run "make"
+[![Windows Build Status](https://ci.appveyor.com/api/projects/status/47uhjgp5h4de2f63/branch/master?svg=true)](https://ci.appveyor.com/project/Khronoswebmaster/opencl-icd-loader/branch/master) [![Linux OSX Build Status](https://travis-ci.com/KhronosGroup/opencl-icd-loader.svg?branch=master)](https://travis-ci.com/KhronosGroup/opencl-icd-loader)
 
-## Windows
+## Introduction
 
-Run "build_using_cmake.bat"
+OpenCL defines an *Installable Client Driver* (ICD) mechanism to allow developers to build applications against an *Installable Client Driver* loader (ICD loader) rather than linking their applications against a specific OpenCL implementation.
+The ICD Loader is responsible for:
 
-## Running ICD Test
+* Exporting OpenCL API entry points
+* Enumerating OpenCL implementations
+* Forwarding OpenCL API calls to the correct implementation
 
-The ICD Test can be run using ctest, which is a companion to cmake. It can also be
-run directly by executing icd_loader_test(.exe) executable from the bin folder.
+This repo contains the source code and tests for the Khronos official OpenCL ICD Loader.
 
-### Linux
+Note that this repo does not contain an OpenCL implementation (ICD).
+You will need to obtain and install an OpenCL implementation for your OpenCL device that supports the OpenCL ICD extension `cl_khr_icd` to run an application using the OpenCL ICD Loader.
 
-1. Add driver stub as an ICD
+The OpenCL *Installable Client Driver* extension (`cl_khr_icd`) is described in the OpenCL extensions specification, which may be found on the [Khronos OpenCL Registry](https://www.khronos.org/registry/OpenCL/).
+
+## Build Instructions
+
+### Dependencies
+
+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).
+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).
+
+### Build and Install Directories
+
+A common convention is to place the `build` directory in the top directory of the repository and to place the `install` directory as a child of the `build` directory.
+The remainder of these instructions follow this convention, although you may place these directories in any location.
+
+### Example Usage
+
+For most Windows and Linux usages, the following steps are sufficient to build the OpenCL ICD Loader:
+
+1. Clone this repo:
+
+        git clone https://github.com/KhronosGroup/OpenCL-ICD-Loader
+
+1. Obtain the OpenCL Headers, if you are not planning to use system OpenCL headers.
+Headers may be obtained from the [Khronos OpenCL Headers](https://github.com/KhronosGroup/OpenCL-Headers) repository.
+
+1. Create a `build` directory:
+
+        cd OpenCL-ICD-Loader
+        mkdir build
+        cd build
+
+1. Invoke `cmake` to generate solution files, Makefiles, or files for other build systems.
+
+        cmake ..
+
+1. Build using the CMake-generated files.
+
+Notes:
+
+* For 64-bit Windows builds, you may need to specify a 64-bit generator manually, for example:
+
+        cmake.exe -G "Visual Studio 14 2015 Win64" ..
+
+* Some users may prefer to use a CMake GUI frontend, such as `cmake-gui` or `ccmake`, vs. the command-line CMake.
+
+## OpenCL ICD Loader Tests
+
+OpenCL ICD Loader Tests can be run using `ctest`, which is a companion to CMake.
+The OpenCL ICD Loader Tests can also be run directly by executing icd_loader_test(.exe) executable from the bin folder.
+
+### Test Setup
+
+The OpenCL ICD Loader Tests use a "stub" ICD, which must be set up manually.
+The OpenCL ICD Loader Tests will "fail" if the "stub" ICD is not set up correctly.
+The method to install the "stub" ICD is operating system dependent.
+
+On Linux, install the "stub" ICD by creating a file with the full path to the "stub" ICD in `/etc/OpenCL/vendors`:
+
     echo full/path/to/libOpenCLDriverStub.so > /etc/OpenCL/vendors/test.icd
 
-2. Run test using ctest
-    make test
+On Windows, add the "stub" ICD by adding a `REG_DWORD` value to the registry keys:
 
-### Windows
-
-1. Add driver stub as an ICD by adding appropriate registry value
-    Key for 32-bit apps: HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Khronos\OpenCL\Vendors
-    Key for 64-bit apps: HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\OpenCL\Vendors
-
-    Add a REG_DWORD value:
-        Name: c:/full/path/to/OpenCLDriverStub.dll
-        Data: 0
-
-    Note: The build_using_cmake.bat builds ICD test as a 32-bit binary.
+    // For 32-bit operating systems, or 64-bit tests on a 64-bit operating system:
+    HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\OpenCL\Vendors
     
-2. Run test using ctest.exe
-    cd build
-    ctest.exe
+    // For 32-bit tests on a 64-bit operating system:
+    HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Khronos\OpenCL\Vendors
 
-### Cleanup
+    // The name of the REG_DWORD value should be the full path to the "stub" ICD
+    // OpenCLDriverStub.dll, and the data for this value should be 0.
 
-Manually remove the registry key or .icd files added for running the ICD test.
+### Running Tests
 
-The "build" and "bin" folders are autogenerated by the build so those may be
-safely deleted without losing any source code (on Linux "make clobber" will
-delete them).
+To run the tests, invoke `ctest` from the `build` directory.
+The CMake-generated build files may be able to invoke the OpenCL ICD Loader tests as well.
+
+### Test Cleanup
+
+Manually remove the file or registry keys added during Test Setup.
+
+## Support
+
+Please create a GitHub issue to report an issue or ask questions.
+
+## Contributing
+
+Contributions to the OpenCL ICD Loader are welcomed and encouraged.
+You will be prompted with a one-time "click-through" CLA dialog as part of submitting your pull request or other contribution to GitHub.
\ No newline at end of file
diff --git a/build_using_cmake.bat b/build_using_cmake.bat
deleted file mode 100644
index f0044db..0000000
--- a/build_using_cmake.bat
+++ /dev/null
@@ -1,11 +0,0 @@
-call "%VS90COMNTOOLS%/vsvars32.bat"
-
-set BUILD_DIR=build
-set BIN_DIR=bin
-
-mkdir %BUILD_DIR%
-cd %BUILD_DIR%
-cmake -G "NMake Makefiles" ../
-nmake
-cd ..
-
diff --git a/loader/windows/OpenCL.rc b/loader/windows/OpenCL.rc
index 561e6ba..330da28 100644
--- a/loader/windows/OpenCL.rc
+++ b/loader/windows/OpenCL.rc
@@ -18,11 +18,22 @@
 
 #include <windows.h>
 
+#define OPENCL_ICD_LOADER_VERSION_MAJOR 2
+#define OPENCL_ICD_LOADER_VERSION_MINOR 2
+#define OPENCL_ICD_LOADER_VERSION_REV   2
+
 #ifdef RC_INVOKED
 
+#define OPENCL_ICD_LOADER_VAL(_v) #_v
+#define OPENCL_ICD_LOADER_TOSTRING(_d) OPENCL_ICD_LOADER_VAL(_d)
+#define OPENCL_ICD_LOADER_VERSION_STRING \
+    OPENCL_ICD_LOADER_TOSTRING(OPENCL_ICD_LOADER_VERSION_MAJOR) "." \
+    OPENCL_ICD_LOADER_TOSTRING(OPENCL_ICD_LOADER_VERSION_MINOR) "." \
+    OPENCL_ICD_LOADER_TOSTRING(OPENCL_ICD_LOADER_VERSION_REV)
+
 VS_VERSION_INFO VERSIONINFO
-FILEVERSION    2,2,1,0
-PRODUCTVERSION 2,2,1,0
+FILEVERSION    OPENCL_ICD_LOADER_VERSION_MAJOR,OPENCL_ICD_LOADER_VERSION_MINOR,OPENCL_ICD_LOADER_VERSION_REV,0
+PRODUCTVERSION OPENCL_ICD_LOADER_VERSION_MAJOR,OPENCL_ICD_LOADER_VERSION_MINOR,OPENCL_ICD_LOADER_VERSION_REV,0
 FILETYPE       VFT_DLL
 
 BEGIN
@@ -31,9 +42,9 @@
         BLOCK "040904E4"
         BEGIN
             VALUE "FileDescription" ,"OpenCL Client DLL"
-            VALUE "ProductName"     ,"Khronos OpenCL ICD"
+            VALUE "ProductName"     ,"Khronos OpenCL ICD Loader"
             VALUE "LegalCopyright"  ,"Copyright \251 The Khronos Group Inc 2016-2019"
-            VALUE "FileVersion"     ,"2.2.1.0"
+            VALUE "FileVersion"     ,OPENCL_ICD_LOADER_VERSION_STRING ".0"
             VALUE "CompanyName"     ,"Khronos Group"
             VALUE "InternalName"    ,"OpenCL"
             VALUE "OriginalFilename","OpenCL.dll"
diff --git a/loader/windows/icd_windows.c b/loader/windows/icd_windows.c
index 5f89085..ec86184 100644
--- a/loader/windows/icd_windows.c
+++ b/loader/windows/icd_windows.c
@@ -18,6 +18,7 @@
 
 #include "icd.h"
 #include "icd_windows_hkr.h"
+#include "icd_windows_dxgk.h"
 #include <stdio.h>
 #include <windows.h>
 #include <winreg.h>
@@ -39,9 +40,13 @@
     HKEY platformsKey = NULL;
     DWORD dwIndex;
 
-    if (!khrIcdOsVendorsEnumerateHKR())
+    if (!khrIcdOsVendorsEnumerateDXGK())
     {
-        KHR_ICD_TRACE("Failed to enumerate HKR entries, continuing\n");
+        KHR_ICD_TRACE("Failed to load via DXGK interface on RS4, continuing\n");
+        if (!khrIcdOsVendorsEnumerateHKR())
+        {
+            KHR_ICD_TRACE("Failed to enumerate HKR entries, continuing\n");
+        }
     }
 
     KHR_ICD_TRACE("Opening key HKLM\\%s...\n", platformsName);
diff --git a/loader/windows/icd_windows_dxgk.c b/loader/windows/icd_windows_dxgk.c
new file mode 100644
index 0000000..8cc3fb9
--- /dev/null
+++ b/loader/windows/icd_windows_dxgk.c
@@ -0,0 +1,154 @@
+/*
+ * 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 "icd.h"
+#include "icd_windows_dxgk.h"
+
+#if defined(OPENCL_ICD_LOADER_REQUIRE_WDK)
+#include <windows.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>
+#endif
+
+bool khrIcdOsVendorsEnumerateDXGK(void)
+{
+    bool ret = false;
+#if defined(OPENCL_ICD_LOADER_REQUIRE_WDK)
+#if defined(DXGKDDI_INTERFACE_VERSION_WDDM2_4) && (DXGKDDI_INTERFACE_VERSION >= DXGKDDI_INTERFACE_VERSION_WDDM2_4)
+    {
+        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 };
+        PFND3DKMT_ENUMADAPTERS2 pEnumAdapters2 = (PFND3DKMT_ENUMADAPTERS2)GetProcAddress((HMODULE)h, "D3DKMTEnumAdapters2");
+        if (!pEnumAdapters2)
+        {
+            KHR_ICD_TRACE("GetProcAddress failed for D3DKMT_ENUMADAPTERS2\n");
+            goto out;
+        }
+        while (1)
+        {
+            EnumAdapters.NumAdapters = 0;
+            EnumAdapters.pAdapters = NULL;
+            Status = pEnumAdapters2(&EnumAdapters);
+            if (Status == STATUS_BUFFER_TOO_SMALL)
+            {
+                // Number of Adapters increased between calls, retry;
+                continue;
+            }
+            else if (!NT_SUCCESS(Status))
+            {
+                KHR_ICD_TRACE("D3DKMT_ENUMADAPTERS2 status != SUCCESS\n");
+                goto out;
+            }
+            break;
+        }
+        pAdapterInfo = (D3DKMT_ADAPTERINFO*)malloc(sizeof(D3DKMT_ADAPTERINFO)*(EnumAdapters.NumAdapters));
+        if (pAdapterInfo == NULL)
+        {
+            KHR_ICD_TRACE("Allocation failure for AdapterInfo buffer\n");
+            goto out;
+        }
+        EnumAdapters.pAdapters = pAdapterInfo;
+        Status = pEnumAdapters2(&EnumAdapters);
+        if (!NT_SUCCESS(Status))
+        {
+            KHR_ICD_TRACE("D3DKMT_ENUMADAPTERS2 status != SUCCESS\n");
+            goto out;
+        }
+        for (UINT AdapterIndex = 0; AdapterIndex < EnumAdapters.NumAdapters; 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;
+#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)
+            {
+                wcscpy_s(QueryArgs.ValueName, ARRAYSIZE(L"OpenCLDriverNameWow"), L"OpenCLDriverNameWow");
+            }
+            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);
+            if (!NT_SUCCESS(Status))
+            {
+                KHR_ICD_TRACE("D3DKMT_QUERYADAPTERINFO status != SUCCESS\n");
+                goto out;
+            }
+            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);
+                pQueryArgs = pQueryBuffer;
+            }
+            if (NT_SUCCESS(Status) && pQueryArgs->Status == D3DDDI_QUERYREGISTRY_STATUS_SUCCESS)
+            {
+                wchar_t* pWchar = pQueryArgs->OutputString;
+                memset(cszLibraryName, 0, sizeof(cszLibraryName));
+                {
+                    size_t len = wcstombs(cszLibraryName, pWchar, sizeof(cszLibraryName));
+                    KHR_ICD_ASSERT(len == (sizeof(cszLibraryName) - 1));
+                    khrIcdVendorAdd(cszLibraryName);
+                }
+            }
+            else if (Status == STATUS_INVALID_PARAMETER && pQueryArgs->Status == D3DDDI_QUERYREGISTRY_STATUS_FAIL)
+            {
+                free(pQueryBuffer);
+                goto out;
+            }
+            free(pQueryBuffer);
+        }
+        ret = true;
+out:
+      free(pAdapterInfo);
+      FreeLibrary(h);
+    }
+#endif
+#endif
+    return ret;
+}
diff --git a/loader/windows/icd_windows_dxgk.h b/loader/windows/icd_windows_dxgk.h
new file mode 100644
index 0000000..f6cb65d
--- /dev/null
+++ b/loader/windows/icd_windows_dxgk.h
@@ -0,0 +1,21 @@
+/*
+ * 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>
+
+bool khrIcdOsVendorsEnumerateDXGK(void);
diff --git a/loader/windows/icd_windows_hkr.c b/loader/windows/icd_windows_hkr.c
index 5f6c534..3387181 100644
--- a/loader/windows/icd_windows_hkr.c
+++ b/loader/windows/icd_windows_hkr.c
@@ -23,7 +23,7 @@
 #include <assert.h>
 #include <stdbool.h>
 #include <initguid.h>
-#include <Devpkey.h>
+#include <devpkey.h>
 #include <devguid.h>
 
  // This GUID was only added to devguid.h on Windows SDK v10.0.16232 which
@@ -117,7 +117,7 @@
 
         result = RegQueryValueExA(
             hkey,
-            OPENCL_REG_SUB_KEY,
+            GetOpenCLRegKeyName(),
             NULL,
             &dwLibraryNameType,
             (LPBYTE)cszOclPath,
diff --git a/test/Makefile b/test/Makefile
deleted file mode 100644
index db52dc5..0000000
--- a/test/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-
-.PHONY: all platform driver_stub loader_test clean
-
-all: platform driver_stub loader_test
-
-platform:
-	${MAKE} -C platform
-
-driver_stub:
-	${MAKE} -C driver_stub
-
-loader_test:
-	${MAKE} -C loader_test
-
-clean:
-	${MAKE} -C platform clean
-	${MAKE} -C driver_stub clean
-	${MAKE} -C loader_test clean
diff --git a/test/driver_stub/Makefile b/test/driver_stub/Makefile
deleted file mode 100644
index dd79b51..0000000
--- a/test/driver_stub/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-CC := gcc
-CFLAGS := -I ../inc -I ../../ -fPIC -g -O0
-
-OUTDIR := ../../bin
-
-${OUTDIR}/libOpenCLDriverStub.so: cl.c cl_ext.c cl_gl.c icd.c
-	${CC} ${CFLAGS} -shared -Wl,-soname,$@ \
-		-Wl,--version-script,icd_driver_exports.map \
-		-o $@ $^ ${OUTDIR}/libIcdLog.so
-
-.PHONY: clean
-
-clean:
-	rm -f ${OUTDIR}/libOpenCLDriverStub.so
diff --git a/test/loader_test/Makefile b/test/loader_test/Makefile
deleted file mode 100644
index 4b0dfe3..0000000
--- a/test/loader_test/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-CC := gcc
-CFLAGS := -I ../inc -I ../../ -g -O0
-
-OUTDIR := ../../bin
-
-${OUTDIR}/icd_loader_test: main.c callbacks.c icd_test_match.c
-
-${OUTDIR}/icd_loader_test: test_buffer_object.c test_clgl.c test_cl_runtime.c test_create_calls.c test_image_objects.c
-
-${OUTDIR}/icd_loader_test: test_kernel.c test_platforms.c test_program_objects.c test_sampler_objects.c
-	${CC} ${CFLAGS} ${OUTDIR}/libOpenCL.so -o $@ $^ ${OUTDIR}/libIcdLog.so
-
-.PHONY: clean
-
-clean:
-	rm -f ${OUTDIR}/icd_loader_test
diff --git a/test/log/Makefile b/test/log/Makefile
deleted file mode 100644
index 8cfb38d..0000000
--- a/test/log/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-# Set this if system does not have OpenCL headers in standard include directory
-CL_HEADER_PATH := ../../
-
-.PHONY: clean
-
-CFLAGS := -I${CL_HEADER_PATH}
-CFLAGS += -fPIC
-
-OUTDIR := ../../bin
-
-${OUTDIR}/libIcdLog.so: icd_test_log.c
-	${CC} ${CFLAGS} -shared -Wl,-soname,libIcdLog.so -o $@ $^
-
-clean:
-	rm -f ${OUTDIR}/libIcdLog.so