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 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 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 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 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 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 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 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 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 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 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