Added OpenCL Universal Driver Support for Win10 RS3 (#21)
[platform/upstream/OpenCL-ICD-Loader.git] / icd_windows.c
1 /*
2  * Copyright (c) 2016 The Khronos Group Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software source and associated documentation files (the "Materials"),
6  * to deal in the Materials without restriction, including without limitation
7  * the rights to use, copy, modify, compile, merge, publish, distribute,
8  * sublicense, and/or sell copies of the Materials, and to permit persons to
9  * whom the Materials are furnished to do so, subject the following terms and
10  * conditions:
11  *
12  * All modifications to the Materials used to create a binary that is
13  * distributed to third parties shall be provided to Khronos with an
14  * unrestricted license to use for the purposes of implementing bug fixes and
15  * enhancements to the Materials;
16  *
17  * If the binary is used as part of an OpenCL(TM) implementation, whether binary
18  * is distributed together with or separately to that implementation, then
19  * recipient must become an OpenCL Adopter and follow the published OpenCL
20  * conformance process for that implementation, details at:
21  * http://www.khronos.org/conformance/;
22  *
23  * The above copyright notice, the OpenCL trademark license, and this permission
24  * notice shall be included in all copies or substantial portions of the
25  * Materials.
26  *
27  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32  * OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS IN
33  * THE MATERIALS.
34  *
35  * OpenCL is a trademark of Apple Inc. used under license by Khronos.
36  */
37
38 #include "icd.h"
39 #include "icd_windows_hkr.h"
40 #include <stdio.h>
41 #include <windows.h>
42 #include <winreg.h>
43
44 static INIT_ONCE initialized = INIT_ONCE_STATIC_INIT;
45
46 /*
47  * 
48  * Vendor enumeration functions
49  *
50  */
51
52 // go through the list of vendors in the registry and call khrIcdVendorAdd 
53 // for each vendor encountered
54 BOOL CALLBACK khrIcdOsVendorsEnumerate(PINIT_ONCE InitOnce, PVOID Parameter, PVOID *lpContext)
55 {
56     LONG result;
57     const char* platformsName = "SOFTWARE\\Khronos\\OpenCL\\Vendors";
58     HKEY platformsKey = NULL;
59     DWORD dwIndex;
60
61     if (!khrIcdOsVendorsEnumerateHKR())
62     {
63         KHR_ICD_TRACE("Failed to enumerate HKR entries, continuing\n");
64     }
65
66     KHR_ICD_TRACE("Opening key HKLM\\%s...\n", platformsName);
67     result = RegOpenKeyExA(
68         HKEY_LOCAL_MACHINE,
69         platformsName,
70         0,
71         KEY_READ,
72         &platformsKey);
73     if (ERROR_SUCCESS != result)
74     {
75         KHR_ICD_TRACE("Failed to open platforms key %s, continuing\n", platformsName);
76         return FALSE;
77     }
78
79     // for each value
80     for (dwIndex = 0;; ++dwIndex)
81     {
82         char cszLibraryName[1024] = {0};
83         DWORD dwLibraryNameSize = sizeof(cszLibraryName);
84         DWORD dwLibraryNameType = 0;     
85         DWORD dwValue = 0;
86         DWORD dwValueSize = sizeof(dwValue);
87
88         // read the value name
89         KHR_ICD_TRACE("Reading value %d...\n", dwIndex);
90         result = RegEnumValueA(
91               platformsKey,
92               dwIndex,
93               cszLibraryName,
94               &dwLibraryNameSize,
95               NULL,
96               &dwLibraryNameType,
97               (LPBYTE)&dwValue,
98               &dwValueSize);
99         // if RegEnumKeyEx fails, we are done with the enumeration
100         if (ERROR_SUCCESS != result) 
101         {
102             KHR_ICD_TRACE("Failed to read value %d, done reading key.\n", dwIndex);
103             break;
104         }
105         KHR_ICD_TRACE("Value %s found...\n", cszLibraryName);
106         
107         // Require that the value be a DWORD and equal zero
108         if (REG_DWORD != dwLibraryNameType)  
109         {
110             KHR_ICD_TRACE("Value not a DWORD, skipping\n");
111             continue;
112         }
113         if (dwValue)
114         {
115             KHR_ICD_TRACE("Value not zero, skipping\n");
116             continue;
117         }
118
119         // add the library
120         khrIcdVendorAdd(cszLibraryName);
121     }
122
123     result = RegCloseKey(platformsKey);
124     if (ERROR_SUCCESS != result)
125     {
126         KHR_ICD_TRACE("Failed to close platforms key %s, ignoring\n", platformsName);
127     }
128         
129     return TRUE;
130 }
131
132 // go through the list of vendors only once
133 void khrIcdOsVendorsEnumerateOnce()
134 {
135     InitOnceExecuteOnce(&initialized, khrIcdOsVendorsEnumerate, NULL, NULL);
136 }
137  
138 /*
139  * 
140  * Dynamic library loading functions
141  *
142  */
143
144 // dynamically load a library.  returns NULL on failure
145 void *khrIcdOsLibraryLoad(const char *libraryName)
146 {
147     return (void *)LoadLibraryA(libraryName);
148 }
149
150 // get a function pointer from a loaded library.  returns NULL on failure.
151 void *khrIcdOsLibraryGetFunctionAddress(void *library, const char *functionName)
152 {
153     if (!library || !functionName)
154     {
155         return NULL;
156     }
157     return GetProcAddress( (HMODULE)library, functionName);
158 }
159
160 // unload a library.
161 void khrIcdOsLibraryUnload(void *library)
162 {
163     FreeLibrary( (HMODULE)library);
164 }
165