ReactOS 0.4.17-dev-966-gf06eace
d3dkmt.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Display Driver Model
3 * LICENSE: MIT (https://spdx.org/licenses/MIT)
4 * PURPOSE: D3DKMT dxgkrnl syscalls
5 * COPYRIGHT: Copyright 2023 Justin Miller <justin.miller@reactos.org>
6 */
7
8#include <gdi32_vista.h>
9#include <d3dkmddi.h>
10#include <winuser.h>
11
12/*
13 * <d3dkmthk.h> hides D3DKMT_OPENADAPTERFROMLUID and D3DKMT_QUERYVIDEOMEMORYINFO
14 * behind DXGKDDI_INTERFACE_VERSION gates of WIN8 and WDDM2_2, while the tree
15 * targets Vista. for now but honestly this can change.
16 */
17
18#if (DXGKDDI_INTERFACE_VERSION < DXGKDDI_INTERFACE_VERSION_WIN8)
19typedef struct _D3DKMT_OPENADAPTERFROMLUID
20{
24#endif
25
26#if (DXGKDDI_INTERFACE_VERSION < DXGKDDI_INTERFACE_VERSION_WDDM2_2)
28{
38#endif
39
40#define D3DKMT_EMU_ADAPTER_TAG 0x0ada0000u
41#define D3DKMT_EMU_DEVICE_TAG 0x0de00000u
42#define D3DKMT_EMU_INDEX_MASK 0x0000ffffu
43
44#define D3DKMT_EMU_MAX_ADAPTERS 16
45#define D3DKMT_EMU_MAX_DEVICES 64
46
47typedef struct _D3DKMT_EMU_ADAPTER
48{
53
54typedef struct _D3DKMT_EMU_DEVICE
55{
59
62
63static
66 _In_ D3DKMT_HANDLE hAdapter)
67{
69
71 return NULL;
72
73 Index = hAdapter & D3DKMT_EMU_INDEX_MASK;
75 return NULL;
76
77 if (!D3DKMTEmuAdapters[Index - 1].InUse)
78 return NULL;
79
80 return &D3DKMTEmuAdapters[Index - 1];
81}
82
83static
86 _In_ D3DKMT_HANDLE hDevice)
87{
89
91 return NULL;
92
93 Index = hDevice & D3DKMT_EMU_INDEX_MASK;
95 return NULL;
96
97 if (!D3DKMTEmuDevices[Index - 1].InUse)
98 return NULL;
99
100 return &D3DKMTEmuDevices[Index - 1];
101}
102
103static
106 _In_ const LUID* AdapterLuid,
108{
109 ULONG Index;
110
112 {
113 if (InterlockedCompareExchange(&D3DKMTEmuAdapters[Index].InUse, 1, 0) == 0)
114 {
115 D3DKMTEmuAdapters[Index].AdapterLuid = *AdapterLuid;
117 return D3DKMT_EMU_ADAPTER_TAG | (Index + 1);
118 }
119 }
120
121 return 0;
122}
123
124/* fake LUID */
125static
126VOID
129 _Out_ LUID* AdapterLuid)
130{
131 AdapterLuid->HighPart = 0x524f5300; /* 'ROS\0' */
132 AdapterLuid->LowPart = VidPnSourceId + 1;
133}
134
135/* Not just a syscall even in wine. */
137WINAPI
139{
141 DISPLAY_DEVICEW DisplayDevice;
142 D3DKMT_HANDLE hAdapter;
143 LUID AdapterLuid;
144 DWORD Index = 0;
145
146 if (!unnamedParam1)
148
149 /* Locate the GDI display device with this name to obtain its index, which
150 doubles as the VidPN source ID */
151 DisplayDevice.cb = sizeof(DisplayDevice);
152 while (EnumDisplayDevicesW(NULL, Index, &DisplayDevice, 0))
153 {
154 if (wcsncmp(DisplayDevice.DeviceName,
155 unnamedParam1->DeviceName,
156 ARRAYSIZE(unnamedParam1->DeviceName)) == 0)
157 {
159 break;
160 }
161
162 DisplayDevice.cb = sizeof(DisplayDevice);
163 Index++;
164 }
165
166 if (!DisplayDevice.DeviceName[0] || VidPnSourceId != Index)
168
169 D3DKMTEmuMakeLuid(VidPnSourceId, &AdapterLuid);
170
171 hAdapter = D3DKMTEmuOpenAdapter(&AdapterLuid, VidPnSourceId);
172 if (!hAdapter)
174
175 unnamedParam1->hAdapter = hAdapter;
176 unnamedParam1->AdapterLuid = AdapterLuid;
177 unnamedParam1->VidPnSourceId = VidPnSourceId;
178
179 return STATUS_SUCCESS;
180}
181
183WINAPI
185{
188 D3DKMT_HANDLE hAdapter;
189
190 if (!unnamedParam1)
192
193 /* Recover the source ID for LUIDs we minted ourselves; anything else is a
194 caller-allocated LUID, for which the primary output is the best match. */
195 if (unnamedParam1->AdapterLuid.HighPart == 0x524f5300 &&
196 unnamedParam1->AdapterLuid.LowPart > 0)
197 {
198 VidPnSourceId = unnamedParam1->AdapterLuid.LowPart - 1;
199 }
200 else
201 {
202 VidPnSourceId = 0;
203 }
204
205 hAdapter = D3DKMTEmuOpenAdapter(&unnamedParam1->AdapterLuid, VidPnSourceId);
206 if (!hAdapter)
208
209 Desc->hAdapter = hAdapter;
210
211 return STATUS_SUCCESS;
212}
213
215WINAPI
217{
218 D3DKMT_EMU_ADAPTER* Adapter;
220
221 if (!unnamedParam1)
223
224 Status = NtGdiDdDDICloseAdapter(unnamedParam1);
226 return Status;
227
228 Adapter = D3DKMTEmuGetAdapter(unnamedParam1->hAdapter);
229 if (!Adapter)
231
232 InterlockedExchange(&Adapter->InUse, 0);
233
234 return STATUS_SUCCESS;
235}
236
238WINAPI
240{
242 ULONG Index;
243
244 if (!unnamedParam1)
246
247 Status = NtGdiDdDDICreateDevice(unnamedParam1);
249 return Status;
250
251 if (!D3DKMTEmuGetAdapter(unnamedParam1->hAdapter))
253
255 {
256 if (InterlockedCompareExchange(&D3DKMTEmuDevices[Index].InUse, 1, 0) == 0)
257 {
258 D3DKMTEmuDevices[Index].hAdapter = unnamedParam1->hAdapter;
259
260 unnamedParam1->hDevice = D3DKMT_EMU_DEVICE_TAG | (Index + 1);
261 unnamedParam1->pCommandBuffer = NULL;
262 unnamedParam1->CommandBufferSize = 0;
263 unnamedParam1->pAllocationList = NULL;
264 unnamedParam1->AllocationListSize = 0;
265 unnamedParam1->pPatchLocationList = NULL;
266 unnamedParam1->PatchLocationListSize = 0;
267
268 return STATUS_SUCCESS;
269 }
270 }
271
273}
274
276WINAPI
278{
281
282 if (!unnamedParam1)
284
285 Status = NtGdiDdDDIDestroyDevice(unnamedParam1);
287 return Status;
288
289 Device = D3DKMTEmuGetDevice(unnamedParam1->hDevice);
290 if (!Device)
292
293 InterlockedExchange(&Device->InUse, 0);
294
295 return STATUS_SUCCESS;
296}
297
299WINAPI
301{
303
304 if (!unnamedParam1)
306
307 Status = NtGdiDdDDISetVidPnSourceOwner(unnamedParam1);
309 return Status;
310
311 /* A zero VidPnSourceCount releases ownership, which always succeeds. */
312 if (unnamedParam1->VidPnSourceCount == 0)
313 return STATUS_SUCCESS;
314
315 if (!D3DKMTEmuGetDevice(unnamedParam1->hDevice))
317
319}
320
322WINAPI
324{
325 if (!unnamedParam1)
327
329}
330
332WINAPI
334{
335 if (!unnamedParam1)
337
338 if (!D3DKMTEmuGetAdapter(unnamedParam1->hAdapter))
340
342}
COMPILER_DEPENDENT_UINT64 UINT64
Definition: actypes.h:131
#define InterlockedExchange
Definition: armddk.h:54
LONG NTSTATUS
Definition: precomp.h:26
#define ARRAYSIZE(a)
Definition: cat.c:25
_Check_return_ _In_ ULONG VidPnSourceId
Definition: dispmprt.h:1205
#define NULL
Definition: types.h:112
_ACRTIMP int __cdecl wcsncmp(const wchar_t *, const wchar_t *, size_t)
Definition: wcs.c:523
unsigned long DWORD
Definition: ntddk_ex.h:95
#define D3DKMT_EMU_MAX_DEVICES
Definition: d3dkmt.c:45
#define D3DKMT_EMU_DEVICE_TAG
Definition: d3dkmt.c:41
NTSTATUS WINAPI D3DKMTOpenAdapterFromLuid(_Inout_ CONST D3DKMT_OPENADAPTERFROMLUID *unnamedParam1)
Definition: d3dkmt.c:184
NTSTATUS WINAPI D3DKMTCheckVidPnExclusiveOwnership(_In_ CONST D3DKMT_CHECKVIDPNEXCLUSIVEOWNERSHIP *unnamedParam1)
Definition: d3dkmt.c:323
NTSTATUS WINAPI D3DKMTCloseAdapter(_In_ const D3DKMT_CLOSEADAPTER *unnamedParam1)
Definition: d3dkmt.c:216
static D3DKMT_EMU_ADAPTER D3DKMTEmuAdapters[D3DKMT_EMU_MAX_ADAPTERS]
Definition: d3dkmt.c:60
NTSTATUS WINAPI D3DKMTDestroyDevice(_In_ const D3DKMT_DESTROYDEVICE *unnamedParam1)
Definition: d3dkmt.c:277
#define D3DKMT_EMU_MAX_ADAPTERS
Definition: d3dkmt.c:44
static D3DKMT_HANDLE D3DKMTEmuOpenAdapter(_In_ const LUID *AdapterLuid, _In_ D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
Definition: d3dkmt.c:105
static D3DKMT_EMU_DEVICE * D3DKMTEmuGetDevice(_In_ D3DKMT_HANDLE hDevice)
Definition: d3dkmt.c:85
#define D3DKMT_EMU_INDEX_MASK
Definition: d3dkmt.c:42
static D3DKMT_EMU_DEVICE D3DKMTEmuDevices[D3DKMT_EMU_MAX_DEVICES]
Definition: d3dkmt.c:61
static D3DKMT_EMU_ADAPTER * D3DKMTEmuGetAdapter(_In_ D3DKMT_HANDLE hAdapter)
Definition: d3dkmt.c:65
#define D3DKMT_EMU_ADAPTER_TAG
Definition: d3dkmt.c:40
struct _D3DKMT_EMU_ADAPTER D3DKMT_EMU_ADAPTER
NTSTATUS WINAPI D3DKMTQueryVideoMemoryInfo(_Inout_ D3DKMT_QUERYVIDEOMEMORYINFO *unnamedParam1)
Definition: d3dkmt.c:333
struct _D3DKMT_EMU_DEVICE D3DKMT_EMU_DEVICE
NTSTATUS WINAPI D3DKMTOpenAdapterFromGdiDisplayName(_Inout_ D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME *unnamedParam1)
Definition: d3dkmt.c:138
NTSTATUS WINAPI D3DKMTSetVidPnSourceOwner(_In_ const D3DKMT_SETVIDPNSOURCEOWNER *unnamedParam1)
Definition: d3dkmt.c:300
static VOID D3DKMTEmuMakeLuid(_In_ D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, _Out_ LUID *AdapterLuid)
Definition: d3dkmt.c:127
NTSTATUS WINAPI D3DKMTCreateDevice(_Inout_ D3DKMT_CREATEDEVICE *unnamedParam1)
Definition: d3dkmt.c:239
Status
Definition: gdiplustypes.h:24
unsigned int UINT
Definition: sysinfo.c:13
#define InterlockedCompareExchange
Definition: interlocked.h:119
#define _Inout_
Definition: no_sal2.h:162
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define STATUS_PROCEDURE_NOT_FOUND
Definition: ntstatus.h:452
#define CONST
Definition: pedump.c:81
long LONG
Definition: pedump.c:60
__kernel_entry W32KAPI NTSTATUS APIENTRY NtGdiDdDDIDestroyDevice(_In_ const D3DKMT_DESTROYDEVICE *unnamedParam1)
Definition: d3dkmt.c:238
__kernel_entry W32KAPI NTSTATUS APIENTRY NtGdiDdDDICreateDevice(_Inout_ D3DKMT_CREATEDEVICE *unnamedParam1)
Definition: d3dkmt.c:173
__kernel_entry W32KAPI NTSTATUS APIENTRY NtGdiDdDDICloseAdapter(_In_ const D3DKMT_CLOSEADAPTER *unnamedParam1)
Definition: d3dkmt.c:147
__kernel_entry W32KAPI NTSTATUS APIENTRY NtGdiDdDDISetVidPnSourceOwner(_In_ const D3DKMT_SETVIDPNSOURCEOWNER *unnamedParam1)
Definition: d3dkmt.c:629
#define STATUS_SUCCESS
Definition: shellext.h:65
D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId
Definition: d3dkmt.c:51
D3DKMT_HANDLE hAdapter
Definition: d3dkmt.c:57
D3DKMT_HANDLE hAdapter
Definition: d3dkmthk.h:135
D3DKMT_MEMORY_SEGMENT_GROUP MemorySegmentGroup
Definition: d3dkmthk.h:709
WCHAR DeviceName[32]
Definition: wingdi.h:3264
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
_In_ WDFCOLLECTION _In_ ULONG Index
BOOL WINAPI EnumDisplayDevicesW(LPCWSTR lpDevice, DWORD iDevNum, PDISPLAY_DEVICEW lpDisplayDevice, DWORD dwFlags)
Definition: display.c:78
#define WINAPI
Definition: msvc.h:6
UINT D3DKMT_HANDLE
Definition: d3dukmdt.h:28
UINT D3DDDI_VIDEO_PRESENT_SOURCE_ID
Definition: d3dukmdt.h:141
struct _D3DKMT_QUERYVIDEOMEMORYINFO D3DKMT_QUERYVIDEOMEMORYINFO
enum _D3DKMT_MEMORY_SEGMENT_GROUP D3DKMT_MEMORY_SEGMENT_GROUP
struct _D3DKMT_OPENADAPTERFROMLUID D3DKMT_OPENADAPTERFROMLUID