2 * Copyright (c) 2018 The Khronos Group Inc.
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
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;
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/;
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
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
35 * OpenCL is a trademark of Apple Inc. used under license by Khronos.
40 #include "icd_windows_dxgk.h"
44 typedef LONG NTSTATUS;
45 #define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
46 #define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023)
47 #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
52 bool khrIcdOsVendorsEnumerateDXGK(void)
54 #if defined(DXGKDDI_INTERFACE_VERSION_WDDM2_4) && (DXGKDDI_INTERFACE_VERSION >= DXGKDDI_INTERFACE_VERSION_WDDM2_4)
56 D3DKMT_ADAPTERINFO* pAdapterInfo;
57 D3DKMT_ENUMADAPTERS2 EnumAdapters;
58 NTSTATUS Status = STATUS_SUCCESS;
60 // Get handle to GDI Runtime
61 HMODULE h = LoadLibrary("gdi32.dll");
63 char cszLibraryName[1024] = { 0 };
64 EnumAdapters.NumAdapters = 0;
65 EnumAdapters.pAdapters = NULL;
66 PFND3DKMT_ENUMADAPTERS2 pEnumAdapters2 = (PFND3DKMT_ENUMADAPTERS2)GetProcAddress((HMODULE)h, "D3DKMTEnumAdapters2");
72 Status = pEnumAdapters2(&EnumAdapters);
73 if (!NT_SUCCESS(Status) && (Status != STATUS_BUFFER_TOO_SMALL))
78 pAdapterInfo = (D3DKMT_ADAPTERINFO*)malloc(sizeof(D3DKMT_ADAPTERINFO)*(EnumAdapters.NumAdapters));
79 EnumAdapters.pAdapters = pAdapterInfo;
80 Status = pEnumAdapters2(&EnumAdapters);
81 if (!NT_SUCCESS(Status))
84 if (pAdapterInfo) free(pAdapterInfo);
87 for (UINT AdapterIndex = 0; AdapterIndex < EnumAdapters.NumAdapters; AdapterIndex++)
89 D3DDDI_QUERYREGISTRY_INFO QueryArgs = {0};
90 D3DDDI_QUERYREGISTRY_INFO* pQueryArgs = &QueryArgs;
91 D3DDDI_QUERYREGISTRY_INFO* pQueryBuffer = NULL;
92 QueryArgs.QueryType = D3DDDI_QUERYREGISTRY_ADAPTERKEY;
93 QueryArgs.QueryFlags.TranslatePath = TRUE;
94 QueryArgs.ValueType = REG_MULTI_SZ;
96 wcscpy_s(QueryArgs.ValueName, ARRAYSIZE(L"OpenCLDriverName"), L"OpenCLDriverName");
98 wcscpy_s(QueryArgs.ValueName, ARRAYSIZE(L"OpenCLDriverNameWow"), L"OpenCLDriverNameWow");
100 D3DKMT_QUERYADAPTERINFO QueryAdapterInfo = {0};
101 QueryAdapterInfo.hAdapter = pAdapterInfo[AdapterIndex].hAdapter;
102 QueryAdapterInfo.Type = KMTQAITYPE_QUERYREGISTRY;
103 QueryAdapterInfo.pPrivateDriverData = &QueryArgs;
104 QueryAdapterInfo.PrivateDriverDataSize = sizeof(QueryArgs);
105 Status = D3DKMTQueryAdapterInfo(&QueryAdapterInfo);
106 if (!NT_SUCCESS(Status))
109 if (pAdapterInfo) free(pAdapterInfo);
112 if (NT_SUCCESS(Status) && pQueryArgs->Status == D3DDDI_QUERYREGISTRY_STATUS_BUFFER_OVERFLOW)
114 unsigned int QueryBufferSize = sizeof(D3DDDI_QUERYREGISTRY_INFO) + QueryArgs.OutputValueSize;
115 pQueryBuffer = (D3DDDI_QUERYREGISTRY_INFO*)malloc(QueryBufferSize);
116 memcpy(pQueryBuffer, &QueryArgs, sizeof(D3DDDI_QUERYREGISTRY_INFO));
117 QueryAdapterInfo.pPrivateDriverData = pQueryBuffer;
118 QueryAdapterInfo.PrivateDriverDataSize = QueryBufferSize;
119 KHR_ICD_TRACE("Attempting to retrieve adpater info for adapter handle %x\n", pAdapterInfo[AdapterIndex].hAdapter);
120 Status = pQueryAdapterInfo(&QueryAdapterInfo);
121 if (!NT_SUCCESS(Status))
123 KHR_ICD_TRACE("Failed to retrieve adpater info for adapter handle %x, continuing with next adapater\n", pAdapterInfo[AdapterIndex].hAdapter);
124 // Continue trying to get as much info on each adapter as possible.
125 // It's too late to return FALSE and claim WDDM2_4 enumeration is not available here.
128 pQueryArgs = pQueryBuffer;
130 if (NT_SUCCESS(Status) && pQueryArgs->Status == D3DDDI_QUERYREGISTRY_STATUS_SUCCESS)
132 wchar_t* pWchar = pQueryArgs->OutputString;
134 memset(cszLibraryName, 0, sizeof(cszLibraryName));
136 while ((*pWchar != L'\0') && (i<1023))
138 cszLibraryName[i] = (char)*pWchar;
142 if (i < 1023) khrIcdVendorAdd(cszLibraryName);
145 if (pQueryBuffer) free(pQueryBuffer);
147 if (pAdapterInfo) free(pAdapterInfo);
149 // Tried all available adapters and the status is not success.
150 if (!NT_SUCCESS(Status)) {