1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: Native DirectDraw implementation
5 * FILE: win32ss/reactx/ntddraw/d3d.c
6 * PROGRAMER: Magnus olsen (magnus@greatlord.com)
7 * REVISION HISTORY:
8 * 19/1-2006 Magnus Olsen
9 */
10
11 /* Comment
12 * NtGdiDdLock and NtGdiDdLockD3D ultimately call the same function in dxg.sys
13 * NtGdiDdUnlock and NtGdiDdUnlockD3D ultimately call the same function in dxg.sys
14 */
15
16 #include <win32k.h>
17
18 // #define NDEBUG
19 #include <debug.h>
20
21 /*++
22 * @name NtGdiDdCanCreateD3DBuffer
23 * @implemented
24 *
25 * The function NtGdiDdCanCreateD3DBuffer checks if you can create a
26 * surface for DirectX. it redirects to dxg.sys in windows XP/2003,
27 * dxkrnl.sys in vista and is fully implemented in win32k.sys in windows 2000 and below
28 *
29 * @param HANDLE hDirectDraw
30 * The handle we got from NtGdiDdCreateDirectDrawObject
31 *
32 * @param PDD_CANCREATESURFACEDATA puCanCreateSurfaceData
33 * This contains information to check if the driver can create the buffers,
34 * surfaces, textures and vertexes, and how many of each the driver can create.
35
36 *
37 * @return
38 * Depending on if the driver supports this function or not, DDHAL_DRIVER_HANDLED
39 * or DDHAL_DRIVER_NOTHANDLED is returned.
40 * To check if the function has been successful, do a full check.
41 * A full check is done by checking if the return value is DDHAL_DRIVER_HANDLED
42 * and puCanCreateSurfaceData->ddRVal is set to DD_OK.
43 *
44 * @remarks.
45 * dxg.sys NtGdiDdCanCreateD3DBuffer and NtGdiDdCanCreateSurface calls are redirected to dxg.sys.
46 * Inside the dxg.sys they are redirected to the same function. Examine the memory addresses on the driver list functions
47 * table and you will see they are pointed to the same memory address.
48 *
49 * Before calling this function please set the puCanCreateSurfaceData->ddRVal to an error value such as DDERR_NOTUSPORTED,
50 * for the ddRVal will otherwise be unchanged even if an error occurs inside the driver.
51 * puCanCreateSurfaceData->lpDD is a pointer to DDRAWI_DIRECTDRAW_GBL, not PDD_DIRECTDRAW_GLOBAL as MSDN claims.
52 * puCanCreateSurfaceData->lpDD->hDD also needs be filled in with the handle we got from NtGdiDdCreateDirectDrawObject.
53 * puCreateSurfaceData->CanCreateSurface is a pointer to the real functions in the HAL or HEL, that you need fill in.
54 * Do not forget PDD_CANCREATESURFACEDATA is typecast of LPDDHAL_CANCREATESURFACEDATA and thuse two struct are different size,
55 * the correct struct is LPDDHAL_CANCREATESURFACEDATA.
56 *
57 *--*/
58 DWORD
59 APIENTRY
NtGdiDdCanCreateD3DBuffer(HANDLE hDirectDraw,PDD_CANCREATESURFACEDATA puCanCreateSurfaceData)60 NtGdiDdCanCreateD3DBuffer(HANDLE hDirectDraw,
61 PDD_CANCREATESURFACEDATA puCanCreateSurfaceData)
62 {
63 PGD_DDCANCREATED3DBUFFER pfnDdCanCreateD3DBuffer = (PGD_DDCANCREATED3DBUFFER)gpDxFuncs[DXG_INDEX_DxDdCanCreateD3DBuffer].pfn;
64
65 if (pfnDdCanCreateD3DBuffer == NULL)
66 {
67 DPRINT1("Warning: no pfnDdCanCreateD3DBuffer\n");
68 return DDHAL_DRIVER_NOTHANDLED;
69 }
70
71 DPRINT("Calling dxg.sys pfnDdCanCreateD3DBuffer\n");
72 return pfnDdCanCreateD3DBuffer(hDirectDraw,puCanCreateSurfaceData);
73 }
74
75 /*++
76 * @name NtGdiD3dContextCreate
77 * @implemented
78 *
79 * The Function NtGdiD3dContextCreate checks if you can create a
80 * context for Directx. It redirects to dxg.sys in windows XP/2003,
81 * dxkrnl.sys in vista and is fully implemented in win32k.sys in windows 2000 and below
82 *
83 * @param HANDLE hDirectDrawLocal
84 * The handle we got from NtGdiDdCreateDirectDrawObject
85 *
86 * @param HANDLE hSurfColor
87 * Handle to DD_SURFACE_LOCAL to be used for the rendering target
88 *
89 * @param HANDLE hSurfZ
90 * Handle to a DD_SURFACE_LOCAL. It is the Z deep buffer. According MSDN if it is set to NULL nothing should happen.
91 *
92 * @param LPD3DNTHAL_CONTEXTCREATEDATA pdcci
93 * The buffer to create the context data
94 *
95 * @return
96 * DDHAL_DRIVER_HANDLED or DDHAL_DRIVER_NOTHANDLED if the driver supports this function.
97 * A full check is done by checking if the return value is DDHAL_DRIVER_HANDLED
98 * and pdcci->ddRVal is set to DD_OK.
99 *
100 *
101 * @remarks.
102 * dxg.sys NtGdiD3dContextCreate calls are redirected to the same function in the dxg.sys. As such they all work the same way.
103 *
104 * Before calling this function please set the pdcci->ddRVal to an error value such as DDERR_NOTSUPORTED,
105 * for the ddRVal will otherwise be unchanged even if an error occurs inside the driver.
106 *
107 * pdcci->lpDDLcl is a pointer to DDRAWI_DIRECTDRAW_LCL, not DD_DIRECTDRAW_LOCAL as MSDN claims.
108 * pdcci->lpDDSLcl is a pointer to DDRAWI_DDRAWSURFACE_LCL, not DD_DDDRAWSURFACE_LOCAL as MSDN claims.
109 * pdcci->lpDDSZLcl is a pointer to DDRAWI_DDRAWSURFACE_LCL, not DD_DDRAWSURFACE_LOCAL as MSDN claims.
110 * pdcci->dwhContext also needs be filled in with the handle we receive from NtGdiDdCreateDirectDrawObject.
111 * pdcci->dwPID the processid it belong to, that you need to fill in.
112 * Do not forget LPD3DNTHAL_CONTEXTCREATEDATA is typecast of LPD3DHAL_CONTEXTCREATEDATA and thuse two struct are different size,
113 * the correct struct is LPD3DHAL_CONTEXTCREATEDATA.
114 *--*/
115 BOOL
116 APIENTRY
NtGdiD3dContextCreate(HANDLE hDirectDrawLocal,HANDLE hSurfColor,HANDLE hSurfZ,LPD3DNTHAL_CONTEXTCREATEDATA pdcci)117 NtGdiD3dContextCreate(HANDLE hDirectDrawLocal,
118 HANDLE hSurfColor,
119 HANDLE hSurfZ,
120 LPD3DNTHAL_CONTEXTCREATEDATA pdcci)
121 {
122 PGD_D3DCONTEXTCREATE pfnD3dContextCreate = (PGD_D3DCONTEXTCREATE)gpDxFuncs[DXG_INDEX_DxD3dContextCreate].pfn;
123
124 if (pfnD3dContextCreate == NULL)
125 {
126 DPRINT1("Warning: no pfnD3dContextCreate\n");
127 return FALSE;
128 }
129
130 DPRINT("Calling dxg.sys pfnD3dContextCreate\n");
131 return pfnD3dContextCreate(hDirectDrawLocal, hSurfColor, hSurfZ, pdcci);
132 }
133
134 /*++
135 * @name NtGdiD3dContextDestroy
136 * @implemented
137 *
138 * The Function NtGdiD3dContextDestroy destroys the context data we got from NtGdiD3dContextCreate
139 * It redirects to dxg.sys in windows XP/2003, dxkrnl.sys in vista and is fully implemented
140 * in win32k.sys in windows 2000 and below
141 *
142 * @param LPD3DNTHAL_CONTEXTDESTROYDATA pContextDestroyData
143 * The context data we want to destroy
144 *
145 * @remarks.
146 * dxg.sys NtGdiD3dContextDestroy calls are redirected to the same functions in the dxg.sys. As such they all work the same way.
147 *
148 * Before calling this function please set the pContextDestroyData->ddRVal to an error value such DDERR_NOTUSPORTED,
149 * for the ddRVal will otherwise be unchanged even if an error occurs inside the driver.
150 * pContextDestroyData->dwhContext also needs to be filled in with the handle we got from NtGdiDdCreateDirectDrawObject
151 *
152 *--*/
153 DWORD
154 APIENTRY
NtGdiD3dContextDestroy(LPD3DNTHAL_CONTEXTDESTROYDATA pContextDestroyData)155 NtGdiD3dContextDestroy(LPD3DNTHAL_CONTEXTDESTROYDATA pContextDestroyData)
156 {
157 PGD_D3DCONTEXTDESTROY pfnD3dContextDestroy = (PGD_D3DCONTEXTDESTROY)gpDxFuncs[DXG_INDEX_DxD3dContextDestroy].pfn;
158
159 if ( pfnD3dContextDestroy == NULL)
160 {
161 DPRINT1("Warning: no pfnD3dContextDestroy\n");
162 return DDHAL_DRIVER_NOTHANDLED;
163 }
164
165 DPRINT("Calling dxg.sys pfnD3dContextDestroy\n");
166 return pfnD3dContextDestroy(pContextDestroyData);
167 }
168
169 /*++
170 * @name NtGdiD3dContextDestroyAll
171 * @implemented
172 *
173 * The Function NtGdiD3dContextDestroyAll destroys all the context data in a process
174 * The data having been allocated with NtGdiD3dContextCreate
175 * It redirects to dxg.sys in windows XP/2003, dxkrnl.sys in vista and is fully implemented
176 * in win32k.sys in windows 2000 and below
177 *
178 * @param LPD3DNTHAL_CONTEXTDESTROYALLDATA pdcad
179 * The context data we want to destory
180 *
181 * @remarks.
182 * dxg.sys NtGdiD3dContextDestroy calls are redirected to the same function in the dxg.sys. As such they all work the same way.
183 *
184 * Before calling this function please set the pdcad->ddRVal to an error value such as DDERR_NOTUSPORTED,
185 * for the ddRVal will otherwise be unchanged even if an error occurs inside the driver.
186 * pdcad->dwPID also needs to be filled in with the ID of the process that needs its context data destroyed.
187 *
188 * Warning: MSDN is wrong about this function. It claims the function queries free memory and does not accept
189 * any parameters. Last time MSDN checked: 19/10-2007
190 *--*/
191 DWORD
192 APIENTRY
NtGdiD3dContextDestroyAll(LPD3DNTHAL_CONTEXTDESTROYALLDATA pdcad)193 NtGdiD3dContextDestroyAll(LPD3DNTHAL_CONTEXTDESTROYALLDATA pdcad)
194 {
195 PGD_D3DCONTEXTDESTROYALL pfnD3dContextDestroyAll = (PGD_D3DCONTEXTDESTROYALL)gpDxFuncs[DXG_INDEX_DxD3dContextDestroyAll].pfn;
196
197 if (pfnD3dContextDestroyAll == NULL)
198 {
199 DPRINT1("Warning: no pfnD3dContextDestroyAll\n");
200 return DDHAL_DRIVER_NOTHANDLED;
201 }
202
203 DPRINT("Calling dxg.sys pfnD3dContextDestroyAll\n");
204 return pfnD3dContextDestroyAll(pdcad);
205 }
206
207 /*++
208 * @name NtGdiDdCreateD3DBuffer
209 * @implemented
210 *
211 * The function NtGdiDdCreateD3DBuffer creates a surface for DirectX.
212 * It redirects to dxg.sys in windows XP/2003, dxkrnl.sys in vista and is fully implemented
213 * in win32k.sys in windows 2000 and below
214 *
215 * @param HANDLE hDirectDraw
216 * The handle we got from NtGdiDdCreateDirectDrawObject
217 *
218 * @param HANDLE *hSurface
219 * <FILLMEIN>
220 *
221 * @param DDSURFACEDESC puSurfaceDescription
222 * Surface description: what kind of surface it should be. Examples: RGB, compress, deep, and etc
223 * See DDSURFACEDESC for more information
224 *
225 * @param DD_SURFACE_GLOBAL *puSurfaceGlobalData
226 * <FILLMEIN>
227 *
228 * @param DD_SURFACE_LOCAL *puSurfaceLocalData
229 * <FILLMEIN>
230 *
231 * @param DD_SURFACE_MORE *puSurfaceMoreData
232 * <FILLMEIN>
233 *
234 * @param PDD_CREATESURFACEDATA puCreateSurfaceData
235 * <FILLMEIN>
236 *
237 * @param HANDLE *puhSurface
238 * <FILLMEIN>
239 *
240 * @return
241 * Depending on if the driver supports this function or not, DDHAL_DRIVER_HANDLED
242 * or DDHAL_DRIVER_NOTHANDLED is returned.
243 * To check if the function was successful, do a full check.
244 * A full check is done by checking if the return value is DDHAL_DRIVER_HANDLED
245 * and puCanCreateSurfaceData->ddRVal is set to DD_OK.
246 *
247 * @remarks.
248 * dxg.sys NtGdiDdCreateD3DBuffer and NtGdiDdCreateSurface calls are redirected to dxg.sys.
249 * Inside the dxg.sys they are redirected to the same function. Examine the memory addresses on the driver list functions
250 * table and you will see they are pointed to the same memory address.
251 *
252 * Before calling this function please set the puCreateSurfaceData->ddRVal to an error value such as DDERR_NOTUSPORTED,
253 * for the ddRVal will otherwise be unchanged even if an error occurs inside the driver.
254 * puCreateSurfaceData->lpDD is a pointer to DDRAWI_DIRECTDRAW_GBL. MSDN claims it is PDD_DIRECTDRAW_GLOBAL but it is not.
255 * puCreateSurfaceData->lpDD->hDD also needs to be filled in with the handle we got from NtGdiDdCreateDirectDrawObject
256 * puCreateSurfaceData->CreateSurface is a pointer to the real functions in the HAL or HEL, that you need fill in
257 *
258 *--*/
259 DWORD
260 APIENTRY
NtGdiDdCreateD3DBuffer(HANDLE hDirectDraw,HANDLE * hSurface,DDSURFACEDESC * puSurfaceDescription,DD_SURFACE_GLOBAL * puSurfaceGlobalData,DD_SURFACE_LOCAL * puSurfaceLocalData,DD_SURFACE_MORE * puSurfaceMoreData,PDD_CREATESURFACEDATA puCreateSurfaceData,HANDLE * puhSurface)261 NtGdiDdCreateD3DBuffer(HANDLE hDirectDraw,
262 HANDLE *hSurface,
263 DDSURFACEDESC *puSurfaceDescription,
264 DD_SURFACE_GLOBAL *puSurfaceGlobalData,
265 DD_SURFACE_LOCAL *puSurfaceLocalData,
266 DD_SURFACE_MORE *puSurfaceMoreData,
267 PDD_CREATESURFACEDATA puCreateSurfaceData,
268 HANDLE *puhSurface)
269 {
270 PGD_DDCREATED3DBUFFER pfnDdCreateD3DBuffer = (PGD_DDCREATED3DBUFFER)gpDxFuncs[DXG_INDEX_DxDdCreateD3DBuffer].pfn;
271
272 if (pfnDdCreateD3DBuffer == NULL)
273 {
274 DPRINT1("Warning: no pfnDdCreateD3DBuffer\n");
275 return DDHAL_DRIVER_NOTHANDLED;
276 }
277
278 DPRINT("Calling dxg.sys pfnDdCreateD3DBuffer\n");
279 return pfnDdCreateD3DBuffer(hDirectDraw, hSurface,
280 puSurfaceDescription, puSurfaceGlobalData,
281 puSurfaceLocalData, puSurfaceMoreData,
282 puCreateSurfaceData, puhSurface);
283 }
284
285 /************************************************************************/
286 /* NtGdiDdDestroyD3DBuffer */
287 /************************************************************************/
288 DWORD
289 APIENTRY
NtGdiDdDestroyD3DBuffer(HANDLE hSurface)290 NtGdiDdDestroyD3DBuffer(HANDLE hSurface)
291 {
292 PGD_DXDDDESTROYD3DBUFFER pfnDdDestroyD3DBuffer =
293 (PGD_DXDDDESTROYD3DBUFFER)gpDxFuncs[DXG_INDEX_DxDdDestroyD3DBuffer].pfn;
294
295 if (pfnDdDestroyD3DBuffer == NULL)
296 {
297 DPRINT1("Warning: no pfnDdDestroyD3DBuffer\n");
298 return DDHAL_DRIVER_NOTHANDLED;
299 }
300
301 DPRINT("Calling dxg.sys pfnDdDestroyD3DBuffer\n");
302 return pfnDdDestroyD3DBuffer(hSurface);
303 }
304
305 /************************************************************************/
306 /* NtGdiD3dDrawPrimitives2 */
307 /************************************************************************/
308 DWORD
309 APIENTRY
NtGdiD3dDrawPrimitives2(HANDLE hCmdBuf,HANDLE hVBuf,LPD3DNTHAL_DRAWPRIMITIVES2DATA pded,FLATPTR * pfpVidMemCmd,DWORD * pdwSizeCmd,FLATPTR * pfpVidMemVtx,DWORD * pdwSizeVtx)310 NtGdiD3dDrawPrimitives2(HANDLE hCmdBuf,
311 HANDLE hVBuf,
312 LPD3DNTHAL_DRAWPRIMITIVES2DATA pded,
313 FLATPTR *pfpVidMemCmd,
314 DWORD *pdwSizeCmd,
315 FLATPTR *pfpVidMemVtx,
316 DWORD *pdwSizeVtx)
317 {
318 PGD_D3DDRAWPRIMITIVES2 pfnD3dDrawPrimitives2 =
319 (PGD_D3DDRAWPRIMITIVES2)gpDxFuncs[DXG_INDEX_DxD3dDrawPrimitives2].pfn;
320
321 if (pfnD3dDrawPrimitives2 == NULL)
322 {
323 DPRINT1("Warning: no pfnD3dDrawPrimitives2\n");
324 return DDHAL_DRIVER_NOTHANDLED;
325 }
326
327 DPRINT("Calling dxg.sys pfnD3dDrawPrimitives2\n");
328 return pfnD3dDrawPrimitives2(hCmdBuf,hVBuf,pded,pfpVidMemCmd,pdwSizeCmd,pfpVidMemVtx,pdwSizeVtx);
329 }
330
331 /************************************************************************/
332 /* NtGdiD3dValidateTextureStageState */
333 /************************************************************************/
334 DWORD
335 APIENTRY
NtGdiDdLockD3D(HANDLE hSurface,PDD_LOCKDATA puLockData)336 NtGdiDdLockD3D(HANDLE hSurface,
337 PDD_LOCKDATA puLockData)
338 {
339 PGD_DXDDLOCKD3D pfnDdLockD3D = (PGD_DXDDLOCKD3D)gpDxFuncs[DXG_INDEX_DxDdLockD3D].pfn;
340
341 if (pfnDdLockD3D == NULL)
342 {
343 DPRINT1("Warning: no pfnDdLockD3D\n");
344 return DDHAL_DRIVER_NOTHANDLED;
345 }
346
347 DPRINT("Calling dxg.sys pfnDdLockD3D\n");
348 return pfnDdLockD3D(hSurface, puLockData);
349 }
350
351 /************************************************************************/
352 /* NtGdiD3dValidateTextureStageState */
353 /************************************************************************/
354 DWORD
355 APIENTRY
NtGdiD3dValidateTextureStageState(LPD3DNTHAL_VALIDATETEXTURESTAGESTATEDATA pData)356 NtGdiD3dValidateTextureStageState(LPD3DNTHAL_VALIDATETEXTURESTAGESTATEDATA pData)
357 {
358 PGD_D3DVALIDATETEXTURESTAGESTATE pfnD3dValidateTextureStageState =
359 (PGD_D3DVALIDATETEXTURESTAGESTATE)gpDxFuncs[DXG_INDEX_DxD3dValidateTextureStageState].pfn;
360
361 if (pfnD3dValidateTextureStageState == NULL)
362 {
363 DPRINT1("Warning: no pfnD3dValidateTextureStageState\n");
364 return DDHAL_DRIVER_NOTHANDLED;
365 }
366
367 DPRINT("Calling dxg.sys pfnD3dValidateTextureStageState\n");
368 return pfnD3dValidateTextureStageState(pData);
369 }
370
371 /************************************************************************/
372 /* NtGdiDdUnlockD3D */
373 /************************************************************************/
374 DWORD
375 APIENTRY
NtGdiDdUnlockD3D(HANDLE hSurface,PDD_UNLOCKDATA puUnlockData)376 NtGdiDdUnlockD3D(HANDLE hSurface,
377 PDD_UNLOCKDATA puUnlockData)
378 {
379 PGD_DXDDUNLOCKD3D pfnDdUnlockD3D = (PGD_DXDDUNLOCKD3D)gpDxFuncs[DXG_INDEX_DxDdUnlockD3D].pfn;
380
381 if (pfnDdUnlockD3D == NULL)
382 {
383 DPRINT1("Warning: no pfnDdUnlockD3D\n");
384 return DDHAL_DRIVER_NOTHANDLED;
385 }
386
387 DPRINT("Calling dxg.sys pfnDdUnlockD3D\n");
388 return pfnDdUnlockD3D(hSurface, puUnlockData);
389 }
390