xref: /aosp_15_r20/external/OpenCL-ICD-Loader/loader/windows/icd_windows_dxgk.c (revision 1cddb830dba8aa7c1cc1039338e56b3b9fa24952)
1*1cddb830SAndroid Build Coastguard Worker /*
2*1cddb830SAndroid Build Coastguard Worker  * Copyright (c) 2017-2020 The Khronos Group Inc.
3*1cddb830SAndroid Build Coastguard Worker  *
4*1cddb830SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*1cddb830SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*1cddb830SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*1cddb830SAndroid Build Coastguard Worker  *
8*1cddb830SAndroid Build Coastguard Worker  *     http://www.apache.org/licenses/LICENSE-2.0
9*1cddb830SAndroid Build Coastguard Worker  *
10*1cddb830SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*1cddb830SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*1cddb830SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*1cddb830SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*1cddb830SAndroid Build Coastguard Worker  * limitations under the License.
15*1cddb830SAndroid Build Coastguard Worker  *
16*1cddb830SAndroid Build Coastguard Worker  * OpenCL is a trademark of Apple Inc. used under license by Khronos.
17*1cddb830SAndroid Build Coastguard Worker  */
18*1cddb830SAndroid Build Coastguard Worker 
19*1cddb830SAndroid Build Coastguard Worker #include "icd.h"
20*1cddb830SAndroid Build Coastguard Worker #include "icd_windows_dxgk.h"
21*1cddb830SAndroid Build Coastguard Worker 
22*1cddb830SAndroid Build Coastguard Worker #include <windows.h>
23*1cddb830SAndroid Build Coastguard Worker #include "adapter.h"
24*1cddb830SAndroid Build Coastguard Worker 
25*1cddb830SAndroid Build Coastguard Worker #ifndef NTSTATUS
26*1cddb830SAndroid Build Coastguard Worker typedef LONG NTSTATUS;
27*1cddb830SAndroid Build Coastguard Worker #define STATUS_SUCCESS  ((NTSTATUS)0x00000000L)
28*1cddb830SAndroid Build Coastguard Worker #define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023)
29*1cddb830SAndroid Build Coastguard Worker #define NT_SUCCESS(status) (((NTSTATUS)(status)) >= 0)
30*1cddb830SAndroid Build Coastguard Worker #endif
31*1cddb830SAndroid Build Coastguard Worker 
khrIcdOsVendorsEnumerateDXGK(void)32*1cddb830SAndroid Build Coastguard Worker bool khrIcdOsVendorsEnumerateDXGK(void)
33*1cddb830SAndroid Build Coastguard Worker {
34*1cddb830SAndroid Build Coastguard Worker     bool ret = false;
35*1cddb830SAndroid Build Coastguard Worker     int result = 0;
36*1cddb830SAndroid Build Coastguard Worker 
37*1cddb830SAndroid Build Coastguard Worker     // Get handle to GDI Runtime
38*1cddb830SAndroid Build Coastguard Worker     HMODULE h = LoadLibraryA("gdi32.dll");
39*1cddb830SAndroid Build Coastguard Worker     if (h == NULL)
40*1cddb830SAndroid Build Coastguard Worker         return ret;
41*1cddb830SAndroid Build Coastguard Worker 
42*1cddb830SAndroid Build Coastguard Worker     if(GetProcAddress(h, "D3DKMTSubmitPresentBltToHwQueue")) // OS Version check
43*1cddb830SAndroid Build Coastguard Worker     {
44*1cddb830SAndroid Build Coastguard Worker         LoaderEnumAdapters2 EnumAdapters;
45*1cddb830SAndroid Build Coastguard Worker         NTSTATUS status = STATUS_SUCCESS;
46*1cddb830SAndroid Build Coastguard Worker 
47*1cddb830SAndroid Build Coastguard Worker         EnumAdapters.adapter_count = 0;
48*1cddb830SAndroid Build Coastguard Worker         EnumAdapters.adapters = NULL;
49*1cddb830SAndroid Build Coastguard Worker         PFN_LoaderEnumAdapters2 pEnumAdapters2 = (PFN_LoaderEnumAdapters2)GetProcAddress(h, "D3DKMTEnumAdapters2");
50*1cddb830SAndroid Build Coastguard Worker         if (!pEnumAdapters2)
51*1cddb830SAndroid Build Coastguard Worker         {
52*1cddb830SAndroid Build Coastguard Worker             KHR_ICD_TRACE("GetProcAddress failed for D3DKMTEnumAdapters2\n");
53*1cddb830SAndroid Build Coastguard Worker             goto out;
54*1cddb830SAndroid Build Coastguard Worker         }
55*1cddb830SAndroid Build Coastguard Worker         PFN_LoaderQueryAdapterInfo pQueryAdapterInfo = (PFN_LoaderQueryAdapterInfo)GetProcAddress(h, "D3DKMTQueryAdapterInfo");
56*1cddb830SAndroid Build Coastguard Worker         if (!pQueryAdapterInfo)
57*1cddb830SAndroid Build Coastguard Worker         {
58*1cddb830SAndroid Build Coastguard Worker             KHR_ICD_TRACE("GetProcAddress failed for D3DKMTQueryAdapterInfo\n");
59*1cddb830SAndroid Build Coastguard Worker             goto out;
60*1cddb830SAndroid Build Coastguard Worker         }
61*1cddb830SAndroid Build Coastguard Worker         while (1)
62*1cddb830SAndroid Build Coastguard Worker         {
63*1cddb830SAndroid Build Coastguard Worker             EnumAdapters.adapter_count = 0;
64*1cddb830SAndroid Build Coastguard Worker             EnumAdapters.adapters = NULL;
65*1cddb830SAndroid Build Coastguard Worker             status = pEnumAdapters2(&EnumAdapters);
66*1cddb830SAndroid Build Coastguard Worker             if (status == STATUS_BUFFER_TOO_SMALL)
67*1cddb830SAndroid Build Coastguard Worker             {
68*1cddb830SAndroid Build Coastguard Worker                 // Number of Adapters increased between calls, retry;
69*1cddb830SAndroid Build Coastguard Worker                 continue;
70*1cddb830SAndroid Build Coastguard Worker             }
71*1cddb830SAndroid Build Coastguard Worker             else if (!NT_SUCCESS(status))
72*1cddb830SAndroid Build Coastguard Worker             {
73*1cddb830SAndroid Build Coastguard Worker                 KHR_ICD_TRACE("D3DKMTEnumAdapters2 status != SUCCESS\n");
74*1cddb830SAndroid Build Coastguard Worker                 goto out;
75*1cddb830SAndroid Build Coastguard Worker             }
76*1cddb830SAndroid Build Coastguard Worker             break;
77*1cddb830SAndroid Build Coastguard Worker         }
78*1cddb830SAndroid Build Coastguard Worker         EnumAdapters.adapters = malloc(sizeof(*EnumAdapters.adapters)*(EnumAdapters.adapter_count));
79*1cddb830SAndroid Build Coastguard Worker         if (EnumAdapters.adapters == NULL)
80*1cddb830SAndroid Build Coastguard Worker         {
81*1cddb830SAndroid Build Coastguard Worker             KHR_ICD_TRACE("Allocation failure for adapters buffer\n");
82*1cddb830SAndroid Build Coastguard Worker             goto out;
83*1cddb830SAndroid Build Coastguard Worker         }
84*1cddb830SAndroid Build Coastguard Worker         status = pEnumAdapters2(&EnumAdapters);
85*1cddb830SAndroid Build Coastguard Worker         if (!NT_SUCCESS(status))
86*1cddb830SAndroid Build Coastguard Worker         {
87*1cddb830SAndroid Build Coastguard Worker             KHR_ICD_TRACE("D3DKMTEnumAdapters2 status != SUCCESS\n");
88*1cddb830SAndroid Build Coastguard Worker             goto out;
89*1cddb830SAndroid Build Coastguard Worker         }
90*1cddb830SAndroid Build Coastguard Worker         const char* cszOpenCLRegKeyName = getOpenCLRegKeyName();
91*1cddb830SAndroid Build Coastguard Worker         const int szOpenCLRegKeyName = (int)(strlen(cszOpenCLRegKeyName) + 1)*sizeof(cszOpenCLRegKeyName[0]);
92*1cddb830SAndroid Build Coastguard Worker         for (UINT AdapterIndex = 0; AdapterIndex < EnumAdapters.adapter_count; AdapterIndex++)
93*1cddb830SAndroid Build Coastguard Worker         {
94*1cddb830SAndroid Build Coastguard Worker             LoaderQueryRegistryInfo queryArgs = {0};
95*1cddb830SAndroid Build Coastguard Worker             LoaderQueryRegistryInfo* pQueryArgs = &queryArgs;
96*1cddb830SAndroid Build Coastguard Worker             LoaderQueryRegistryInfo* pQueryBuffer = NULL;
97*1cddb830SAndroid Build Coastguard Worker             queryArgs.query_type = LOADER_QUERY_REGISTRY_ADAPTER_KEY;
98*1cddb830SAndroid Build Coastguard Worker             queryArgs.query_flags.translate_path = TRUE;
99*1cddb830SAndroid Build Coastguard Worker             queryArgs.value_type = REG_SZ;
100*1cddb830SAndroid Build Coastguard Worker             result = MultiByteToWideChar(
101*1cddb830SAndroid Build Coastguard Worker                 CP_UTF8,
102*1cddb830SAndroid Build Coastguard Worker                 0,
103*1cddb830SAndroid Build Coastguard Worker                 cszOpenCLRegKeyName,
104*1cddb830SAndroid Build Coastguard Worker                 szOpenCLRegKeyName,
105*1cddb830SAndroid Build Coastguard Worker                 queryArgs.value_name,
106*1cddb830SAndroid Build Coastguard Worker                 ARRAYSIZE(queryArgs.value_name));
107*1cddb830SAndroid Build Coastguard Worker             if (!result)
108*1cddb830SAndroid Build Coastguard Worker             {
109*1cddb830SAndroid Build Coastguard Worker                 KHR_ICD_TRACE("MultiByteToWideChar status != SUCCESS\n");
110*1cddb830SAndroid Build Coastguard Worker                 continue;
111*1cddb830SAndroid Build Coastguard Worker             }
112*1cddb830SAndroid Build Coastguard Worker             LoaderQueryAdapterInfo queryAdapterInfo = {0};
113*1cddb830SAndroid Build Coastguard Worker             queryAdapterInfo.handle = EnumAdapters.adapters[AdapterIndex].handle;
114*1cddb830SAndroid Build Coastguard Worker             queryAdapterInfo.type = LOADER_QUERY_TYPE_REGISTRY;
115*1cddb830SAndroid Build Coastguard Worker             queryAdapterInfo.private_data = &queryArgs;
116*1cddb830SAndroid Build Coastguard Worker             queryAdapterInfo.private_data_size = sizeof(queryArgs);
117*1cddb830SAndroid Build Coastguard Worker             status = pQueryAdapterInfo(&queryAdapterInfo);
118*1cddb830SAndroid Build Coastguard Worker             if (!NT_SUCCESS(status))
119*1cddb830SAndroid Build Coastguard Worker             {
120*1cddb830SAndroid Build Coastguard Worker                 // Try a different value type.  Some vendors write the key as a multi-string type.
121*1cddb830SAndroid Build Coastguard Worker                 queryArgs.value_type = REG_MULTI_SZ;
122*1cddb830SAndroid Build Coastguard Worker                 status = pQueryAdapterInfo(&queryAdapterInfo);
123*1cddb830SAndroid Build Coastguard Worker                 if (NT_SUCCESS(status))
124*1cddb830SAndroid Build Coastguard Worker                 {
125*1cddb830SAndroid Build Coastguard Worker                     KHR_ICD_TRACE("Accepting multi-string registry key type\n");
126*1cddb830SAndroid Build Coastguard Worker                 }
127*1cddb830SAndroid Build Coastguard Worker                 else
128*1cddb830SAndroid Build Coastguard Worker                 {
129*1cddb830SAndroid Build Coastguard Worker                     // Continue trying to get as much info on each adapter as possible.
130*1cddb830SAndroid Build Coastguard Worker                     // It's too late to return FALSE and claim WDDM2_4 enumeration is not available here.
131*1cddb830SAndroid Build Coastguard Worker                     continue;
132*1cddb830SAndroid Build Coastguard Worker                 }
133*1cddb830SAndroid Build Coastguard Worker             }
134*1cddb830SAndroid Build Coastguard Worker             if (NT_SUCCESS(status) && pQueryArgs->status == LOADER_QUERY_REGISTRY_STATUS_BUFFER_OVERFLOW)
135*1cddb830SAndroid Build Coastguard Worker             {
136*1cddb830SAndroid Build Coastguard Worker                 ULONG queryBufferSize = sizeof(LoaderQueryRegistryInfo) + queryArgs.output_value_size;
137*1cddb830SAndroid Build Coastguard Worker                 pQueryBuffer = malloc(queryBufferSize);
138*1cddb830SAndroid Build Coastguard Worker                 if (pQueryBuffer == NULL)
139*1cddb830SAndroid Build Coastguard Worker                     continue;
140*1cddb830SAndroid Build Coastguard Worker                 memcpy(pQueryBuffer, &queryArgs, sizeof(LoaderQueryRegistryInfo));
141*1cddb830SAndroid Build Coastguard Worker                 queryAdapterInfo.private_data = pQueryBuffer;
142*1cddb830SAndroid Build Coastguard Worker                 queryAdapterInfo.private_data_size = queryBufferSize;
143*1cddb830SAndroid Build Coastguard Worker                 status = pQueryAdapterInfo(&queryAdapterInfo);
144*1cddb830SAndroid Build Coastguard Worker                 pQueryArgs = pQueryBuffer;
145*1cddb830SAndroid Build Coastguard Worker             }
146*1cddb830SAndroid Build Coastguard Worker             if (NT_SUCCESS(status) && pQueryArgs->status == LOADER_QUERY_REGISTRY_STATUS_SUCCESS)
147*1cddb830SAndroid Build Coastguard Worker             {
148*1cddb830SAndroid Build Coastguard Worker                 char cszLibraryName[MAX_PATH];
149*1cddb830SAndroid Build Coastguard Worker                 result = WideCharToMultiByte(
150*1cddb830SAndroid Build Coastguard Worker                     CP_UTF8,
151*1cddb830SAndroid Build Coastguard Worker                     0,
152*1cddb830SAndroid Build Coastguard Worker                     pQueryArgs->output_string,
153*1cddb830SAndroid Build Coastguard Worker                     -1,
154*1cddb830SAndroid Build Coastguard Worker                     cszLibraryName,
155*1cddb830SAndroid Build Coastguard Worker                     MAX_PATH,
156*1cddb830SAndroid Build Coastguard Worker                     NULL,
157*1cddb830SAndroid Build Coastguard Worker                     NULL);
158*1cddb830SAndroid Build Coastguard Worker                 if (!result)
159*1cddb830SAndroid Build Coastguard Worker                 {
160*1cddb830SAndroid Build Coastguard Worker                     KHR_ICD_TRACE("WideCharToMultiByte status != SUCCESS\n");
161*1cddb830SAndroid Build Coastguard Worker                 }
162*1cddb830SAndroid Build Coastguard Worker                 else
163*1cddb830SAndroid Build Coastguard Worker                 {
164*1cddb830SAndroid Build Coastguard Worker                     ret |= adapterAdd(cszLibraryName, EnumAdapters.adapters[AdapterIndex].luid);
165*1cddb830SAndroid Build Coastguard Worker                 }
166*1cddb830SAndroid Build Coastguard Worker             }
167*1cddb830SAndroid Build Coastguard Worker             else if (status == (NTSTATUS)STATUS_INVALID_PARAMETER)
168*1cddb830SAndroid Build Coastguard Worker             {
169*1cddb830SAndroid Build Coastguard Worker                 free(pQueryBuffer);
170*1cddb830SAndroid Build Coastguard Worker                 goto out;
171*1cddb830SAndroid Build Coastguard Worker             }
172*1cddb830SAndroid Build Coastguard Worker             free(pQueryBuffer);
173*1cddb830SAndroid Build Coastguard Worker         }
174*1cddb830SAndroid Build Coastguard Worker out:
175*1cddb830SAndroid Build Coastguard Worker       free(EnumAdapters.adapters);
176*1cddb830SAndroid Build Coastguard Worker     }
177*1cddb830SAndroid Build Coastguard Worker 
178*1cddb830SAndroid Build Coastguard Worker     FreeLibrary(h);
179*1cddb830SAndroid Build Coastguard Worker 
180*1cddb830SAndroid Build Coastguard Worker     return ret;
181*1cddb830SAndroid Build Coastguard Worker }
182