0017366d6b2e9c8516dbe5fa21cfcd2a2c8ea0fe
[reactos.git] / reactos / win32ss / reactx / dxg / eng.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: Native driver for dxg implementation
5 * FILE: win32ss/reactx/dxg/eng.c
6 * PROGRAMER: Magnus olsen (magnus@greatlord.com)
7 * REVISION HISTORY:
8 * 30/12-2007 Magnus Olsen
9 */
10
11 #include <dxg_int.h>
12
13 /*++
14 * @name intDdGetDriverInfo
15 * @implemented
16 *
17 * The function intDdGetDriverInfo is used internally in dxg.sys
18 * It retrieves driver information structures
19 *
20 * @param PEDD_DIRECTDRAW_GLOBAL peDdGl
21 * DirectDraw global structure
22 *
23 * @param GUID guid
24 * GUID of InfoData to read
25 *
26 * @param PVOID callbackStruct
27 * Callback structure pointer
28 *
29 * @param ULONG callbackSize
30 * Size of allocated callback structure
31 *
32 * @param ULONG *returnSize
33 * Desired structure size returned by driver
34 *
35 * @return
36 * Returns true on successful execution, false when error.
37 *
38 * @remarks.
39 * Only used internally in dxg.sys
40 *--*/
41 BOOL intDdGetDriverInfo(PEDD_DIRECTDRAW_GLOBAL peDdGl, GUID guid, PVOID callbackStruct, ULONG callbackSize, ULONG *returnSize)
42 {
43 DD_GETDRIVERINFODATA ddGetDriverInfoData;
44
45 if (peDdGl->ddHalInfo.dwFlags & DDHALINFO_GETDRIVERINFOSET && peDdGl->ddHalInfo.GetDriverInfo)
46 {
47 memset(&ddGetDriverInfoData, 0, sizeof(DD_GETDRIVERINFODATA));
48 ddGetDriverInfoData.dwSize = sizeof(DD_GETDRIVERINFODATA);
49 ddGetDriverInfoData.dhpdev = peDdGl->dhpdev;
50 memcpy(&ddGetDriverInfoData.guidInfo, &guid, sizeof(GUID));
51 ddGetDriverInfoData.dwExpectedSize = callbackSize;
52 ddGetDriverInfoData.lpvData = callbackStruct;
53 ddGetDriverInfoData.ddRVal = DDERR_CURRENTLYNOTAVAIL;
54 if (peDdGl->ddHalInfo.GetDriverInfo(&ddGetDriverInfoData) && !ddGetDriverInfoData.ddRVal)
55 {
56 if (returnSize)
57 *returnSize = ddGetDriverInfoData.dwActualSize;
58 return TRUE;
59 }
60
61 }
62
63 /* cleanup on error */
64 memset(callbackStruct, 0, callbackSize);
65 if (returnSize)
66 *returnSize = 0;
67 return FALSE;
68 }
69
70
71 PVOID
72 FASTCALL
73 intDdCreateDirectDrawLocal(HDEV hDev)
74 {
75 PEDD_DIRECTDRAW_GLOBAL peDdGl = NULL;
76 PEDD_DIRECTDRAW_LOCAL peDdL = NULL;
77 PDD_ENTRY AllocRet;
78
79 peDdGl = (PEDD_DIRECTDRAW_GLOBAL)gpEngFuncs.DxEngGetHdevData(hDev, DxEGShDevData_eddg);
80
81 AllocRet = DdHmgAlloc(sizeof(EDD_DIRECTDRAW_LOCAL), ObjType_DDLOCAL_TYPE, TRUE);
82 if (!AllocRet)
83 return NULL;
84
85 peDdL = (PEDD_DIRECTDRAW_LOCAL)AllocRet;
86
87 /* initialize DIRECTDRAW_LOCAL */
88 peDdL->peDirectDrawLocal_prev = peDdGl->peDirectDrawLocalList;
89 peDdL->UniqueProcess = PsGetCurrentThreadProcessId();
90 peDdL->Process = PsGetCurrentProcess();
91
92 // link DirectDrawGlobal and DirectDrawLocal
93 peDdGl->peDirectDrawLocalList = peDdL;
94 peDdL->peDirectDrawGlobal = peDdGl;
95 peDdL->peDirectDrawGlobal2 = peDdGl;
96
97 gpEngFuncs.DxEngReferenceHdev(hDev);
98
99 InterlockedExchangeAdd((LONG*)&peDdL->pobj.cExclusiveLock, 0xFFFFFFFF);
100
101 return peDdL->pobj.hHmgr;
102 }
103
104
105 PDD_SURFACE_LOCAL
106 NTAPI
107 DxDdLockDirectDrawSurface(HANDLE hDdSurface)
108 {
109 PEDD_SURFACE pEDDSurface = NULL;
110 PDD_SURFACE_LOCAL pSurfacelcl = NULL;
111
112 pEDDSurface = DdHmgLock(hDdSurface, ObjType_DDSURFACE_TYPE, FALSE);
113 if (pEDDSurface != NULL)
114 {
115 pSurfacelcl = &pEDDSurface->ddsSurfaceLocal;
116 }
117
118 return pSurfacelcl;
119 }
120
121 BOOL
122 NTAPI
123 DxDdUnlockDirectDrawSurface(PDD_SURFACE_LOCAL pSurface)
124 {
125 BOOL retVal = FALSE;
126 //PEDD_SURFACE pEDDSurface = NULL;
127
128 if (pSurface)
129 {
130 // pEDDSurface = (PEDD_SURFACE)( ((PBYTE)pSurface) - sizeof(DD_BASEOBJECT));
131 // InterlockedDecrement(&pEDDSurface->pobj.cExclusiveLock);
132 retVal = TRUE;
133 }
134
135 return retVal;
136 }
137
138 /*++
139 * @name intDdGetAllDriverInfo
140 * @implemented
141 *
142 * The function intDdGetAllDriverInfo is used internally in dxg.sys
143 * It retrieves all possible driver information structures
144 *
145 * @param PEDD_DIRECTDRAW_GLOBAL peDdGl
146 * Pointer to destination DirectDrawGlobal structure
147 *
148 * @remarks.
149 * Only used internally in dxg.sys
150 * Missing some callbacks (VideoPort, DxApi, AGP)
151 *--*/
152 VOID intDdGetAllDriverInfo(PEDD_DIRECTDRAW_GLOBAL peDdGl)
153 {
154 if (peDdGl->ddHalInfo.GetDriverInfo && peDdGl->ddHalInfo.dwFlags & DDHALINFO_GETDRIVERINFOSET)
155 {
156 intDdGetDriverInfo(peDdGl, GUID_KernelCaps, &peDdGl->ddKernelCaps, sizeof(peDdGl->ddKernelCaps), 0);
157 intDdGetDriverInfo(peDdGl, GUID_KernelCallbacks, &peDdGl->ddKernelCallbacks, sizeof(peDdGl->ddKernelCallbacks), 0);
158
159 if (intDdGetDriverInfo(peDdGl, GUID_D3DCallbacks3, &peDdGl->d3dNtHalCallbacks3, sizeof(peDdGl->d3dNtHalCallbacks3), 0))
160 peDdGl->dwCallbackFlags |= EDDDGBL_D3DCALLBACKS3;
161
162 if (intDdGetDriverInfo(peDdGl, GUID_ColorControlCallbacks, &peDdGl->ddColorControlCallbacks, sizeof(peDdGl->ddColorControlCallbacks), 0))
163 peDdGl->dwCallbackFlags |= EDDDGBL_COLORCONTROLCALLBACKS;
164
165 if (intDdGetDriverInfo(peDdGl, GUID_MiscellaneousCallbacks, &peDdGl->ddMiscellanousCallbacks, sizeof(peDdGl->ddMiscellanousCallbacks), 0))
166 peDdGl->dwCallbackFlags |= EDDDGBL_MISCCALLBACKS;
167
168 if (intDdGetDriverInfo(peDdGl, GUID_Miscellaneous2Callbacks, &peDdGl->ddMiscellanous2Callbacks, sizeof(peDdGl->ddMiscellanous2Callbacks), 0))
169 peDdGl->dwCallbackFlags |= EDDDGBL_MISC2CALLBACKS;
170
171 if (intDdGetDriverInfo(peDdGl, GUID_NTCallbacks, &peDdGl->ddNtCallbacks, sizeof(peDdGl->ddNtCallbacks), 0) )
172 peDdGl->dwCallbackFlags |= EDDDGBL_NTCALLBACKS;
173
174 if (intDdGetDriverInfo(peDdGl, GUID_DDMoreCaps, &peDdGl->ddMoreCaps, sizeof(peDdGl->ddMoreCaps), 0) )
175 peDdGl->dwCallbackFlags |= EDDDGBL_DDMORECAPS;
176
177 if (intDdGetDriverInfo(peDdGl, GUID_NTPrivateDriverCaps, &peDdGl->ddNtPrivateDriverCaps, sizeof(peDdGl->ddNtPrivateDriverCaps), 0) )
178 peDdGl->dwCallbackFlags |= EDDDGBL_PRIVATEDRIVERCAPS;
179
180 if (intDdGetDriverInfo(peDdGl, GUID_MotionCompCallbacks, &peDdGl->ddMotionCompCallbacks, sizeof(peDdGl->ddMotionCompCallbacks), 0) )
181 peDdGl->dwCallbackFlags |= EDDDGBL_MOTIONCOMPCALLBACKS;
182 }
183 }
184
185
186 /*++
187 * @name intDdEnableDriver
188 * @implemented
189 *
190 * The function intDdEnableDriver is used internally in dxg.sys
191 * Fills in all EDD_DIRECTDRAW_GLOBAL structures and enables DirectDraw acceleration when possible
192 *
193 * @param PEDD_DIRECTDRAW_GLOBAL peDdGl
194 * Pointer to destination DirectDrawGlobal structure
195 *
196 * @remarks.
197 * Only used internally in dxg.sys
198 *--*/
199 VOID intDdEnableDriver(PEDD_DIRECTDRAW_GLOBAL peDdGl)
200 {
201 PDRIVER_FUNCTIONS DriverFunctions;
202 LPD3DNTHAL_GLOBALDRIVERDATA GlobalDriverData;
203 LPD3DNTHAL_CALLBACKS HalCallbacks;
204 PDD_D3DBUFCALLBACKS D3DBufCallbacks;
205
206
207 gpEngFuncs.DxEngLockHdev(peDdGl->hDev);
208 DriverFunctions = (PDRIVER_FUNCTIONS)gpEngFuncs.DxEngGetHdevData(peDdGl->hDev, DxEGShDevData_DrvFuncs);
209
210 // check if driver has DirectDraw functions
211 if ((!DriverFunctions->GetDirectDrawInfo)||(!DriverFunctions->EnableDirectDraw)||(!DriverFunctions->DisableDirectDraw))
212 peDdGl->dhpdev = 0;
213
214
215 // reset acceleration flag
216 peDdGl->fl = peDdGl->fl & 0xFFFFFFFE;
217
218 // ask for structure sizes
219 if ((peDdGl->dhpdev)&&(DriverFunctions->GetDirectDrawInfo(peDdGl->dhpdev, &peDdGl->ddHalInfo, &peDdGl->dwNumHeaps, NULL, &peDdGl->dwNumFourCC, NULL)))
220 {
221 // allocate memory for DX data
222 if (peDdGl->dwNumHeaps)
223 peDdGl->pvmList = EngAllocMem(FL_ZERO_MEMORY, peDdGl->dwNumHeaps*sizeof(VIDEOMEMORY), TAG_GDDV);
224 if (peDdGl->dwNumFourCC)
225 peDdGl->pdwFourCC = EngAllocMem(FL_ZERO_MEMORY, peDdGl->dwNumFourCC * 4, TAG_GDDF);
226
227 // get data from driver
228 if (!DriverFunctions->GetDirectDrawInfo(peDdGl->dhpdev, &peDdGl->ddHalInfo, &peDdGl->dwNumHeaps, peDdGl->pvmList, &peDdGl->dwNumFourCC, peDdGl->pdwFourCC))
229 {
230 // failed - cleanup and exit
231 if (peDdGl->pvmList)
232 EngFreeMem(peDdGl->pvmList);
233 if (peDdGl->pdwFourCC)
234 EngFreeMem(peDdGl->pdwFourCC);
235 gpEngFuncs.DxEngUnlockHdev(peDdGl->hDev);
236 return;
237 }
238
239 // check if we can enable DirectDraw acceleration
240 if ((peDdGl->ddHalInfo.vmiData.pvPrimary) &&
241 (DriverFunctions->EnableDirectDraw(peDdGl->dhpdev, &peDdGl->ddCallbacks, &peDdGl->ddSurfaceCallbacks, &peDdGl->ddPaletteCallbacks))&&
242 !(gpEngFuncs.DxEngGetHdevData(peDdGl->hDev, DxEGShDevData_dd_flags) & CapOver_DisableD3DAccel)&&
243 (peDdGl->ddHalInfo.dwSize == sizeof(DD_HALINFO)))
244 {
245 GlobalDriverData = peDdGl->ddHalInfo.lpD3DGlobalDriverData;
246 HalCallbacks = peDdGl->ddHalInfo.lpD3DHALCallbacks;
247 D3DBufCallbacks = peDdGl->ddHalInfo.lpD3DHALCallbacks;
248
249 if (GlobalDriverData && GlobalDriverData->dwSize == sizeof(D3DNTHAL_GLOBALDRIVERDATA))
250 memcpy(&peDdGl->d3dNtGlobalDriverData, GlobalDriverData, sizeof(D3DNTHAL_GLOBALDRIVERDATA));
251
252 if (HalCallbacks && HalCallbacks->dwSize == sizeof(D3DNTHAL_CALLBACKS))
253 memcpy(&peDdGl->d3dNtHalCallbacks, HalCallbacks, sizeof(D3DNTHAL_CALLBACKS));
254
255 if (D3DBufCallbacks && D3DBufCallbacks->dwSize == sizeof(DD_D3DBUFCALLBACKS))
256 memcpy(&peDdGl->d3dBufCallbacks, D3DBufCallbacks, sizeof(DD_D3DBUFCALLBACKS));
257
258 intDdGetAllDriverInfo(peDdGl);
259
260 // enable DirectDraw acceleration
261 peDdGl->fl |= 1;
262 }
263 else
264 {
265 // failed - cleanup and exit
266 if (peDdGl->pvmList)
267 EngFreeMem(peDdGl->pvmList);
268 if (peDdGl->pdwFourCC)
269 EngFreeMem(peDdGl->pdwFourCC);
270 }
271 }
272
273 gpEngFuncs.DxEngUnlockHdev(peDdGl->hDev);
274 }
275
276 /*++
277 * @name DxDdEnableDirectDraw
278 * @implemented
279 *
280 * Function enables DirectDraw
281 *
282 * @param PEDD_DIRECTDRAW_GLOBAL peDdGl
283 * Pointer to destination DirectDrawGlobal structure
284 *--*/
285 BOOL
286 NTAPI
287 DxDdEnableDirectDraw(HANDLE hDev, BOOL arg2/*What for?*/)
288 {
289 PEDD_DIRECTDRAW_GLOBAL peDdGl = NULL;
290
291 if (gpEngFuncs.DxEngGetHdevData(hDev, DxEGShDevData_display))
292 {
293 peDdGl = (PEDD_DIRECTDRAW_GLOBAL)gpEngFuncs.DxEngGetHdevData(hDev, DxEGShDevData_eddg);
294 peDdGl->hDev = hDev;
295 peDdGl->bSuspended = FALSE;
296 peDdGl->dhpdev = (PVOID)gpEngFuncs.DxEngGetHdevData(hDev, DxEGShDevData_dhpdev);
297 intDdEnableDriver(peDdGl);
298 return TRUE;
299 }
300
301 return FALSE;
302 }
303
304 /*++
305 * @name DxDdCreateDirectDrawObject
306 * @implemented
307 *
308 * Function creates new DirectDraw object
309 *
310 * @param HDC hDC
311 * Device context handle
312 *
313 * @return
314 * Newly created DirectDraw object handle.
315 *
316 * @remarks.
317 * Missing all AGP stuff
318 *--*/
319 DWORD
320 NTAPI
321 DxDdCreateDirectDrawObject(
322 HDC hDC)
323 {
324 PDC pDC = NULL;
325 HDEV hDev = NULL;
326 DWORD retVal = 0;
327
328 pDC = gpEngFuncs.DxEngLockDC(hDC);
329 if (!pDC)
330 return 0;
331
332 // get driver hDev from DC
333 hDev = (HDEV)gpEngFuncs.DxEngGetDCState(hDC, 3);
334 if (!hDev) {
335 gpEngFuncs.DxEngUnlockDC(pDC);
336 return 0;
337 }
338
339 // is this primary display?
340 if (!gpEngFuncs.DxEngGetHdevData(hDev, DxEGShDevData_display))
341 {
342 gpEngFuncs.DxEngUnlockDC(pDC);
343 return 0;
344 }
345
346 gpEngFuncs.DxEngLockHdev(hDev);
347
348 // create object only for 8BPP and more
349 if (gpEngFuncs.DxEngGetHdevData(hDev, DxEGShDevData_DitherFmt) >= BMF_8BPP)
350 retVal = (DWORD)intDdCreateDirectDrawLocal(hDev);
351
352 gpEngFuncs.DxEngUnlockHdev(hDev);
353 gpEngFuncs.DxEngUnlockDC(pDC);
354 return retVal;
355 }