1/* 2 * Copyright 2011 Joakim Sindholt <opensource@zhasha.com> 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * on the rights to use, copy, modify, merge, publish, distribute, sub 8 * license, and/or sell copies of the Software, and to permit persons to whom 9 * the Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21 * USE OR OTHER DEALINGS IN THE SOFTWARE. */ 22 23#include "device9.h" 24#include "device9ex.h" 25#include "nine_pipe.h" 26#include "swapchain9ex.h" 27 28#include "nine_helpers.h" 29 30#include "util/macros.h" 31 32#define DBG_CHANNEL DBG_DEVICE 33 34static HRESULT 35NineDevice9Ex_ctor( struct NineDevice9Ex *This, 36 struct NineUnknownParams *pParams, 37 struct pipe_screen *pScreen, 38 D3DDEVICE_CREATION_PARAMETERS *pCreationParameters, 39 D3DCAPS9 *pCaps, 40 D3DPRESENT_PARAMETERS *pPresentationParameters, 41 D3DDISPLAYMODEEX *pFullscreenDisplayMode, 42 IDirect3D9Ex *pD3D9Ex, 43 ID3DPresentGroup *pPresentationGroup, 44 struct d3dadapter9_context *pCTX, 45 int minorVersionNum ) 46{ 47 DBG("This=%p pParams=%p pScreen=%p pCreationParameters=%p pCaps=%p " 48 "pPresentationParameters=%p pFullscreenDisplayMode=%p " 49 "pD3D9Ex=%p pPresentationGroup=%p pCTX=%p\n", 50 This, pParams, pScreen, pCreationParameters, pCaps, 51 pPresentationParameters, pFullscreenDisplayMode, 52 pD3D9Ex, pPresentationGroup, pCTX); 53 54 return NineDevice9_ctor(&This->base, pParams, 55 pScreen, pCreationParameters, pCaps, 56 pPresentationParameters, 57 (IDirect3D9 *)pD3D9Ex, pPresentationGroup, pCTX, 58 TRUE, pFullscreenDisplayMode, minorVersionNum); 59} 60 61static void 62NineDevice9Ex_dtor( struct NineDevice9Ex *This ) 63{ 64 NineDevice9_dtor(&This->base); 65} 66 67HRESULT NINE_WINAPI 68NineDevice9Ex_SetConvolutionMonoKernel( UNUSED struct NineDevice9Ex *This, 69 UNUSED UINT width, 70 UNUSED UINT height, 71 UNUSED float *rows, 72 UNUSED float *columns ) 73{ 74 DBG("This\n"); 75 STUB(D3D_OK); 76} 77 78HRESULT NINE_WINAPI 79NineDevice9Ex_ComposeRects( UNUSED struct NineDevice9Ex *This, 80 UNUSED IDirect3DSurface9 *pSrc, 81 UNUSED IDirect3DSurface9 *pDst, 82 UNUSED IDirect3DVertexBuffer9 *pSrcRectDescs, 83 UNUSED UINT NumRects, 84 UNUSED IDirect3DVertexBuffer9 *pDstRectDescs, 85 UNUSED D3DCOMPOSERECTSOP Operation, 86 UNUSED int Xoffset, 87 UNUSED int Yoffset ) 88{ 89 DBG("This\n"); 90 STUB(D3D_OK); 91} 92 93HRESULT NINE_WINAPI 94NineDevice9Ex_PresentEx( struct NineDevice9Ex *This, 95 const RECT *pSourceRect, 96 const RECT *pDestRect, 97 HWND hDestWindowOverride, 98 const RGNDATA *pDirtyRegion, 99 DWORD dwFlags ) 100{ 101 unsigned i; 102 HRESULT hr; 103 104 DBG("This=%p pSourceRect=%p pDestRect=%p hDestWindowOverride=%p " 105 "pDirtyRegion=%p dwFlags=%d\n", 106 This, pSourceRect, pDestRect, hDestWindowOverride, 107 pDirtyRegion, dwFlags); 108 109 for (i = 0; i < This->base.nswapchains; i++) { 110 hr = NineSwapChain9_Present(This->base.swapchains[i], pSourceRect, pDestRect, 111 hDestWindowOverride, pDirtyRegion, dwFlags); 112 if (FAILED(hr)) { return hr; } 113 } 114 115 return D3D_OK; 116} 117 118HRESULT NINE_WINAPI 119NineDevice9Ex_GetGPUThreadPriority( struct NineDevice9Ex *This, 120 INT *pPriority ) 121{ 122 DBG("This\n"); 123 user_assert(pPriority != NULL, D3DERR_INVALIDCALL); 124 *pPriority = This->base.gpu_priority; 125 return D3D_OK; 126} 127 128HRESULT NINE_WINAPI 129NineDevice9Ex_SetGPUThreadPriority( struct NineDevice9Ex *This, 130 INT Priority ) 131{ 132 DBG("This\n"); 133 user_assert(Priority >= -7 && Priority <= 7, D3DERR_INVALIDCALL); 134 This->base.gpu_priority = Priority; 135 return D3D_OK; 136} 137 138HRESULT NINE_WINAPI 139NineDevice9Ex_WaitForVBlank( UNUSED struct NineDevice9Ex *This, 140 UNUSED UINT iSwapChain ) 141{ 142 DBG("This\n"); 143 STUB(D3D_OK); 144} 145 146HRESULT NINE_WINAPI 147NineDevice9Ex_CheckResourceResidency( UNUSED struct NineDevice9Ex *This, 148 UNUSED IDirect3DResource9 **pResourceArray, 149 UNUSED UINT32 NumResources ) 150{ 151 DBG("This\n"); 152 STUB(D3D_OK); 153} 154 155HRESULT NINE_WINAPI 156NineDevice9Ex_SetMaximumFrameLatency( struct NineDevice9Ex *This, 157 UINT MaxLatency ) 158{ 159 DBG("This\n"); 160 This->base.max_frame_latency = MaxLatency; 161 return D3D_OK; 162} 163 164HRESULT NINE_WINAPI 165NineDevice9Ex_GetMaximumFrameLatency( struct NineDevice9Ex *This, 166 UINT *pMaxLatency ) 167{ 168 DBG("This\n"); 169 user_assert(pMaxLatency != NULL, D3DERR_INVALIDCALL); 170 *pMaxLatency = This->base.max_frame_latency; 171 return D3D_OK; 172} 173 174HRESULT NINE_WINAPI 175NineDevice9Ex_CheckDeviceState( struct NineDevice9Ex *This, 176 HWND hDestinationWindow ) 177{ 178 DBG("This=%p hDestinationWindow=%p\n", 179 This, hDestinationWindow); 180 181 user_assert(!This->base.swapchains[0]->params.Windowed, D3D_OK); 182 183 if (This->base.params.hFocusWindow == hDestinationWindow) { 184 if (NineSwapChain9_GetOccluded(This->base.swapchains[0])) 185 return S_PRESENT_OCCLUDED; 186 } else if(!NineSwapChain9_GetOccluded(This->base.swapchains[0])) { 187 return S_PRESENT_OCCLUDED; 188 } 189 /* TODO: handle the other return values */ 190 return D3D_OK; 191} 192 193HRESULT NINE_WINAPI 194NineDevice9Ex_CreateRenderTargetEx( struct NineDevice9Ex *This, 195 UINT Width, 196 UINT Height, 197 D3DFORMAT Format, 198 D3DMULTISAMPLE_TYPE MultiSample, 199 DWORD MultisampleQuality, 200 BOOL Lockable, 201 IDirect3DSurface9 **ppSurface, 202 HANDLE *pSharedHandle, 203 UNUSED DWORD Usage ) 204{ 205 DBG("This\n"); 206 /* The Create*Ex functions only purpose seem to introduce the 207 * Usage field, to pass the new d3d9ex flags on secure/restricted 208 * content. 209 * TODO: Return error on invalid Usage. 210 * TODO: Store Usage in the surface descriptor, in case the 211 * app checks */ 212 return NineDevice9_CreateRenderTarget(&This->base, 213 Width, 214 Height, 215 Format, 216 MultiSample, 217 MultisampleQuality, 218 Lockable, 219 ppSurface, 220 pSharedHandle); 221} 222 223HRESULT NINE_WINAPI 224NineDevice9Ex_CreateOffscreenPlainSurfaceEx( struct NineDevice9Ex *This, 225 UINT Width, 226 UINT Height, 227 D3DFORMAT Format, 228 D3DPOOL Pool, 229 IDirect3DSurface9 **ppSurface, 230 HANDLE *pSharedHandle, 231 UNUSED DWORD Usage ) 232{ 233 DBG("This\n"); 234 /* The Create*Ex functions only purpose seem to introduce the 235 * Usage field, to pass the new d3d9ex flags on secure/restricted 236 * content. 237 * TODO: Return error on invalid Usage. 238 * TODO: Store Usage in the surface descriptor, in case the 239 * app checks */ 240 return NineDevice9_CreateOffscreenPlainSurface(&This->base, 241 Width, 242 Height, 243 Format, 244 Pool, 245 ppSurface, 246 pSharedHandle); 247} 248 249HRESULT NINE_WINAPI 250NineDevice9Ex_CreateDepthStencilSurfaceEx( struct NineDevice9Ex *This, 251 UINT Width, 252 UINT Height, 253 D3DFORMAT Format, 254 D3DMULTISAMPLE_TYPE MultiSample, 255 DWORD MultisampleQuality, 256 BOOL Discard, 257 IDirect3DSurface9 **ppSurface, 258 HANDLE *pSharedHandle, 259 UNUSED DWORD Usage ) 260{ 261 DBG("This\n"); 262 /* The Create*Ex functions only purpose seem to introduce the 263 * Usage field, to pass the new d3d9ex flags on secure/restricted 264 * content. 265 * TODO: Return error on invalid Usage. 266 * TODO: Store Usage in the surface descriptor, in case the 267 * app checks */ 268 return NineDevice9_CreateDepthStencilSurface(&This->base, 269 Width, 270 Height, 271 Format, 272 MultiSample, 273 MultisampleQuality, 274 Discard, 275 ppSurface, 276 pSharedHandle); 277} 278 279HRESULT NINE_WINAPI 280NineDevice9Ex_ResetEx( struct NineDevice9Ex *This, 281 D3DPRESENT_PARAMETERS *pPresentationParameters, 282 D3DDISPLAYMODEEX *pFullscreenDisplayMode ) 283{ 284 HRESULT hr = D3D_OK; 285 float MinZ, MaxZ; 286 unsigned i; 287 288 DBG("This=%p pPresentationParameters=%p pFullscreenDisplayMode=%p\n", This, pPresentationParameters, pFullscreenDisplayMode); 289 290 for (i = 0; i < This->base.nswapchains; ++i) { 291 D3DDISPLAYMODEEX *mode = NULL; 292 D3DPRESENT_PARAMETERS *params = &pPresentationParameters[i]; 293 if (pFullscreenDisplayMode) mode = &(pFullscreenDisplayMode[i]); 294 hr = NineSwapChain9_Resize(This->base.swapchains[i], params, mode); 295 if (FAILED(hr)) 296 break; 297 } 298 299 MinZ = This->base.state.viewport.MinZ; /* These are preserved */ 300 MaxZ = This->base.state.viewport.MaxZ; 301 NineDevice9_SetRenderTarget( 302 (struct NineDevice9 *)This, 0, (IDirect3DSurface9 *)This->base.swapchains[0]->buffers[0]); 303 This->base.state.viewport.MinZ = MinZ; 304 This->base.state.viewport.MaxZ = MaxZ; 305 nine_context_set_viewport(&This->base, &This->base.state.viewport); 306 307 if (This->base.nswapchains && This->base.swapchains[0]->params.EnableAutoDepthStencil) 308 NineDevice9_SetDepthStencilSurface( 309 &This->base, (IDirect3DSurface9 *)This->base.swapchains[0]->zsbuf); 310 311 return hr; 312} 313 314HRESULT NINE_WINAPI 315NineDevice9Ex_Reset( struct NineDevice9Ex *This, 316 D3DPRESENT_PARAMETERS *pPresentationParameters ) 317{ 318 HRESULT hr = D3D_OK; 319 float MinZ, MaxZ; 320 unsigned i; 321 322 DBG("This=%p pPresentationParameters=%p\n", This, pPresentationParameters); 323 324 for (i = 0; i < This->base.nswapchains; ++i) { 325 D3DPRESENT_PARAMETERS *params = &pPresentationParameters[i]; 326 hr = NineSwapChain9_Resize(This->base.swapchains[i], params, NULL); 327 if (FAILED(hr)) 328 break; 329 } 330 331 MinZ = This->base.state.viewport.MinZ; /* These are preserved */ 332 MaxZ = This->base.state.viewport.MaxZ; 333 NineDevice9_SetRenderTarget( 334 (struct NineDevice9 *)This, 0, (IDirect3DSurface9 *)This->base.swapchains[0]->buffers[0]); 335 This->base.state.viewport.MinZ = MinZ; 336 This->base.state.viewport.MaxZ = MaxZ; 337 nine_context_set_viewport(&This->base, &This->base.state.viewport); 338 339 if (This->base.nswapchains && This->base.swapchains[0]->params.EnableAutoDepthStencil) 340 NineDevice9_SetDepthStencilSurface( 341 &This->base, (IDirect3DSurface9 *)This->base.swapchains[0]->zsbuf); 342 343 return hr; 344} 345 346HRESULT NINE_WINAPI 347NineDevice9Ex_GetDisplayModeEx( struct NineDevice9Ex *This, 348 UINT iSwapChain, 349 D3DDISPLAYMODEEX *pMode, 350 D3DDISPLAYROTATION *pRotation ) 351{ 352 struct NineSwapChain9Ex *swapchain; 353 354 DBG("This=%p iSwapChain=%u pMode=%p pRotation=%p\n", 355 This, iSwapChain, pMode, pRotation); 356 357 user_assert(iSwapChain < This->base.nswapchains, D3DERR_INVALIDCALL); 358 359 swapchain = NineSwapChain9Ex(This->base.swapchains[iSwapChain]); 360 return NineSwapChain9Ex_GetDisplayModeEx(swapchain, pMode, pRotation); 361} 362 363HRESULT NINE_WINAPI 364NineDevice9Ex_TestCooperativeLevel( UNUSED struct NineDevice9Ex *This ) 365{ 366 DBG("This\n"); 367 return D3D_OK; 368} 369 370 371IDirect3DDevice9ExVtbl NineDevice9Ex_vtable = { 372 (void *)NineUnknown_QueryInterface, 373 (void *)NineUnknown_AddRef, 374 (void *)NineUnknown_Release, 375 (void *)NineDevice9Ex_TestCooperativeLevel, 376 (void *)NineDevice9_GetAvailableTextureMem, 377 (void *)NineDevice9_EvictManagedResources, 378 (void *)NineDevice9_GetDirect3D, 379 (void *)NineDevice9_GetDeviceCaps, 380 (void *)NineDevice9_GetDisplayMode, 381 (void *)NineDevice9_GetCreationParameters, 382 (void *)NineDevice9_SetCursorProperties, 383 (void *)NineDevice9_SetCursorPosition, 384 (void *)NineDevice9_ShowCursor, 385 (void *)NineDevice9_CreateAdditionalSwapChain, 386 (void *)NineDevice9_GetSwapChain, 387 (void *)NineDevice9_GetNumberOfSwapChains, 388 (void *)NineDevice9Ex_Reset, 389 (void *)NineDevice9_Present, 390 (void *)NineDevice9_GetBackBuffer, 391 (void *)NineDevice9_GetRasterStatus, 392 (void *)NineDevice9_SetDialogBoxMode, 393 (void *)NineDevice9_SetGammaRamp, 394 (void *)NineDevice9_GetGammaRamp, 395 (void *)NineDevice9_CreateTexture, 396 (void *)NineDevice9_CreateVolumeTexture, 397 (void *)NineDevice9_CreateCubeTexture, 398 (void *)NineDevice9_CreateVertexBuffer, 399 (void *)NineDevice9_CreateIndexBuffer, 400 (void *)NineDevice9_CreateRenderTarget, 401 (void *)NineDevice9_CreateDepthStencilSurface, 402 (void *)NineDevice9_UpdateSurface, 403 (void *)NineDevice9_UpdateTexture, 404 (void *)NineDevice9_GetRenderTargetData, 405 (void *)NineDevice9_GetFrontBufferData, 406 (void *)NineDevice9_StretchRect, 407 (void *)NineDevice9_ColorFill, 408 (void *)NineDevice9_CreateOffscreenPlainSurface, 409 (void *)NineDevice9_SetRenderTarget, 410 (void *)NineDevice9_GetRenderTarget, 411 (void *)NineDevice9_SetDepthStencilSurface, 412 (void *)NineDevice9_GetDepthStencilSurface, 413 (void *)NineDevice9_BeginScene, 414 (void *)NineDevice9_EndScene, 415 (void *)NineDevice9_Clear, 416 (void *)NineDevice9_SetTransform, 417 (void *)NineDevice9_GetTransform, 418 (void *)NineDevice9_MultiplyTransform, 419 (void *)NineDevice9_SetViewport, 420 (void *)NineDevice9_GetViewport, 421 (void *)NineDevice9_SetMaterial, 422 (void *)NineDevice9_GetMaterial, 423 (void *)NineDevice9_SetLight, 424 (void *)NineDevice9_GetLight, 425 (void *)NineDevice9_LightEnable, 426 (void *)NineDevice9_GetLightEnable, 427 (void *)NineDevice9_SetClipPlane, 428 (void *)NineDevice9_GetClipPlane, 429 (void *)NineDevice9_SetRenderState, 430 (void *)NineDevice9_GetRenderState, 431 (void *)NineDevice9_CreateStateBlock, 432 (void *)NineDevice9_BeginStateBlock, 433 (void *)NineDevice9_EndStateBlock, 434 (void *)NineDevice9_SetClipStatus, 435 (void *)NineDevice9_GetClipStatus, 436 (void *)NineDevice9_GetTexture, 437 (void *)NineDevice9_SetTexture, 438 (void *)NineDevice9_GetTextureStageState, 439 (void *)NineDevice9_SetTextureStageState, 440 (void *)NineDevice9_GetSamplerState, 441 (void *)NineDevice9_SetSamplerState, 442 (void *)NineDevice9_ValidateDevice, 443 (void *)NineDevice9_SetPaletteEntries, 444 (void *)NineDevice9_GetPaletteEntries, 445 (void *)NineDevice9_SetCurrentTexturePalette, 446 (void *)NineDevice9_GetCurrentTexturePalette, 447 (void *)NineDevice9_SetScissorRect, 448 (void *)NineDevice9_GetScissorRect, 449 (void *)NineDevice9_SetSoftwareVertexProcessing, 450 (void *)NineDevice9_GetSoftwareVertexProcessing, 451 (void *)NineDevice9_SetNPatchMode, 452 (void *)NineDevice9_GetNPatchMode, 453 (void *)NineDevice9_DrawPrimitive, 454 (void *)NineDevice9_DrawIndexedPrimitive, 455 (void *)NineDevice9_DrawPrimitiveUP, 456 (void *)NineDevice9_DrawIndexedPrimitiveUP, 457 (void *)NineDevice9_ProcessVertices, 458 (void *)NineDevice9_CreateVertexDeclaration, 459 (void *)NineDevice9_SetVertexDeclaration, 460 (void *)NineDevice9_GetVertexDeclaration, 461 (void *)NineDevice9_SetFVF, 462 (void *)NineDevice9_GetFVF, 463 (void *)NineDevice9_CreateVertexShader, 464 (void *)NineDevice9_SetVertexShader, 465 (void *)NineDevice9_GetVertexShader, 466 (void *)NineDevice9_SetVertexShaderConstantF, 467 (void *)NineDevice9_GetVertexShaderConstantF, 468 (void *)NineDevice9_SetVertexShaderConstantI, 469 (void *)NineDevice9_GetVertexShaderConstantI, 470 (void *)NineDevice9_SetVertexShaderConstantB, 471 (void *)NineDevice9_GetVertexShaderConstantB, 472 (void *)NineDevice9_SetStreamSource, 473 (void *)NineDevice9_GetStreamSource, 474 (void *)NineDevice9_SetStreamSourceFreq, 475 (void *)NineDevice9_GetStreamSourceFreq, 476 (void *)NineDevice9_SetIndices, 477 (void *)NineDevice9_GetIndices, 478 (void *)NineDevice9_CreatePixelShader, 479 (void *)NineDevice9_SetPixelShader, 480 (void *)NineDevice9_GetPixelShader, 481 (void *)NineDevice9_SetPixelShaderConstantF, 482 (void *)NineDevice9_GetPixelShaderConstantF, 483 (void *)NineDevice9_SetPixelShaderConstantI, 484 (void *)NineDevice9_GetPixelShaderConstantI, 485 (void *)NineDevice9_SetPixelShaderConstantB, 486 (void *)NineDevice9_GetPixelShaderConstantB, 487 (void *)NineDevice9_DrawRectPatch, 488 (void *)NineDevice9_DrawTriPatch, 489 (void *)NineDevice9_DeletePatch, 490 (void *)NineDevice9_CreateQuery, 491 (void *)NineDevice9Ex_SetConvolutionMonoKernel, 492 (void *)NineDevice9Ex_ComposeRects, 493 (void *)NineDevice9Ex_PresentEx, 494 (void *)NineDevice9Ex_GetGPUThreadPriority, 495 (void *)NineDevice9Ex_SetGPUThreadPriority, 496 (void *)NineDevice9Ex_WaitForVBlank, 497 (void *)NineDevice9Ex_CheckResourceResidency, 498 (void *)NineDevice9Ex_SetMaximumFrameLatency, 499 (void *)NineDevice9Ex_GetMaximumFrameLatency, 500 (void *)NineDevice9Ex_CheckDeviceState, 501 (void *)NineDevice9Ex_CreateRenderTargetEx, 502 (void *)NineDevice9Ex_CreateOffscreenPlainSurfaceEx, 503 (void *)NineDevice9Ex_CreateDepthStencilSurfaceEx, 504 (void *)NineDevice9Ex_ResetEx, 505 (void *)NineDevice9Ex_GetDisplayModeEx 506}; 507 508static const GUID *NineDevice9Ex_IIDs[] = { 509 &IID_IDirect3DDevice9Ex, 510 &IID_IDirect3DDevice9, 511 &IID_IUnknown, 512 NULL 513}; 514 515HRESULT 516NineDevice9Ex_new( struct pipe_screen *pScreen, 517 D3DDEVICE_CREATION_PARAMETERS *pCreationParameters, 518 D3DCAPS9 *pCaps, 519 D3DPRESENT_PARAMETERS *pPresentationParameters, 520 D3DDISPLAYMODEEX *pFullscreenDisplayMode, 521 IDirect3D9Ex *pD3D9Ex, 522 ID3DPresentGroup *pPresentationGroup, 523 struct d3dadapter9_context *pCTX, 524 struct NineDevice9Ex **ppOut, 525 int minorVersionNum ) 526{ 527 BOOL lock; 528 lock = !!(pCreationParameters->BehaviorFlags & D3DCREATE_MULTITHREADED); 529 530 NINE_NEW(Device9Ex, ppOut, lock, 531 pScreen, pCreationParameters, pCaps, pPresentationParameters, 532 pFullscreenDisplayMode, pD3D9Ex, pPresentationGroup, pCTX, minorVersionNum ); 533} 534 535