ReactOS 0.4.15-dev-7704-gc07eb9f
d3d9_impl.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS ReactX
4 * FILE: dll/directx/d3d9/d3d9_impl.c
5 * PURPOSE: IDirect3D9 implementation
6 * PROGRAMERS: Gregor Brunmar <gregor (dot) brunmar (at) home (dot) se>
7 */
8
9#include "d3d9_common.h"
10#include <d3d9.h>
11#include <debug.h>
12#include "d3d9_helpers.h"
13#include "adapter.h"
14#include "device.h"
15#include "format.h"
16
17#define LOCK_D3D9() EnterCriticalSection(&This->d3d9_cs);
18#define UNLOCK_D3D9() LeaveCriticalSection(&This->d3d9_cs);
19
20/* Convert a IDirect3D9 pointer safely to the internal implementation struct */
22{
23 if (NULL == iface)
24 return NULL;
25
26 return (LPDIRECT3D9_INT)((ULONG_PTR)iface - FIELD_OFFSET(DIRECT3D9_INT, lpVtbl));
27}
28
29/* IDirect3D9: IUnknown implementation */
31{
33
34 if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDirect3D9))
35 {
36 IUnknown_AddRef(iface);
37 *ppvObject = &This->lpVtbl;
38 return S_OK;
39 }
40
41 *ppvObject = NULL;
42 return E_NOINTERFACE;
43}
44
46{
49
50 return ref;
51}
52
54{
57
58 if (ref == 0)
59 {
60 EnterCriticalSection(&This->d3d9_cs);
61 /* TODO: Free resources here */
62 LeaveCriticalSection(&This->d3d9_cs);
64 }
65
66 return ref;
67}
68
69/* IDirect3D9 interface */
70static HRESULT WINAPI IDirect3D9Impl_RegisterSoftwareDevice(LPDIRECT3D9 iface, void* pInitializeFunction)
71{
73
74 return D3D_OK;
75}
76
77/*++
78* @name IDirect3D9::GetAdapterCount
79* @implemented
80*
81* The function IDirect3D9Impl_GetAdapterCount returns the number of adapters
82*
83* @param LPDIRECT3D iface
84* Pointer to the IDirect3D9 object returned from Direct3DCreate9()
85*
86* @return UINT
87* The number of display adapters on the system when Direct3DCreate9() was called.
88*
89*/
91{
92 UINT NumDisplayAdapters;
93
95 LOCK_D3D9();
96
97 NumDisplayAdapters = This->NumDisplayAdapters;
98
100 return NumDisplayAdapters;
101}
102
103/*++
104* @name IDirect3D9::GetAdapterIdentifier
105* @implemented
106*
107* The function IDirect3D9Impl_GetAdapterIdentifier gathers information about
108* a specified display adapter and fills the pIdentifier argument with the available information.
109*
110* @param LPDIRECT3D iface
111* Pointer to the IDirect3D9 object returned from Direct3DCreate9()
112*
113* @param UINT Adapter
114* Adapter index to get information about. D3DADAPTER_DEFAULT is the primary display.
115* The maximum value for this is the value returned by IDirect3D::GetAdapterCount() - 1.
116*
117* @param DWORD Flags
118* Ignored at the moment, but the only valid flag is D3DENUM_WHQL_LEVEL
119*
120* @param D3DADAPTER_IDENTIFIER9* pIdentifier
121* Pointer to a D3DADAPTER_IDENTIFIER9 structure to be filled with the available information
122* about the display adapter.
123*
124* @return HRESULT
125* If the method successfully fills the pIdentified structure, the return value is D3D_OK.
126* If Adapter is out of range, Flags is invalid or pIdentifier is a bad pointer, the return value
127* will be D3DERR_INVALIDCALL.
128*
129*/
131 D3DADAPTER_IDENTIFIER9* pIdentifier)
132{
134 LOCK_D3D9();
135
136 if (Adapter >= This->NumDisplayAdapters)
137 {
138 DPRINT1("Invalid Adapter number specified");
139 UNLOCK_D3D9();
140 return D3DERR_INVALIDCALL;
141 }
142
143 if (Flags & ~D3DENUM_WHQL_LEVEL)
144 {
145 DPRINT1("Invalid Flags specified");
146 UNLOCK_D3D9();
147 return D3DERR_INVALIDCALL;
148 }
149
150 if (NULL == pIdentifier)
151 {
152 DPRINT1("Invalid pIdentifier parameter specified");
153 UNLOCK_D3D9();
154 return D3DERR_INVALIDCALL;
155 }
156
157 memset(pIdentifier, 0, sizeof(D3DADAPTER_IDENTIFIER9));
158
159 if (FALSE == GetAdapterInfo(This->DisplayAdapters[Adapter].szDeviceName, pIdentifier))
160 {
161 DPRINT1("Internal error: Couldn't get the adapter info for device (%d): %s", Adapter, This->DisplayAdapters[Adapter].szDeviceName);
162 UNLOCK_D3D9();
163 return D3DERR_INVALIDCALL;
164 }
165
166 UNLOCK_D3D9();
167 return D3D_OK;
168}
169
170/*++
171* @name IDirect3D9::GetAdapterModeCount
172* @implemented
173*
174* The function IDirect3D9Impl_GetAdapterModeCount looks if the specified display adapter supports
175* a specific pixel format and counts the available display modes for that format.
176*
177* @param LPDIRECT3D iface
178* Pointer to the IDirect3D9 object returned from Direct3DCreate9()
179*
180* @param UINT Adapter
181* Adapter index to get information about. D3DADAPTER_DEFAULT is the primary display.
182* The maximum value for this is the value returned by IDirect3D9::GetAdapterCount() - 1.
183*
184* @param D3DFORMAT Format
185* The pixel format to search for
186*
187* @return HRESULT
188* If the method is successful it returns the number of display modes with the specified Format.
189* If Adapter is out of range, the return value will be 0.
190*
191*/
193{
194 UINT AdapterModeCount;
195
197 LOCK_D3D9();
198
199 if (Adapter >= This->NumDisplayAdapters)
200 {
201 DPRINT1("Invalid Adapter number specified");
202 UNLOCK_D3D9();
203 return D3DERR_INVALIDCALL;
204 }
205
207 {
208 AdapterModeCount = GetDisplayFormatCount(
209 Format,
210 This->DisplayAdapters[Adapter].pSupportedD3DFormats,
211 This->DisplayAdapters[Adapter].NumSupportedD3DFormats);
212 }
213 else
214 {
215 AdapterModeCount = GetDisplayFormatCount(
216 Format,
217 This->DisplayAdapters[Adapter].pSupportedD3DExtendedFormats,
218 This->DisplayAdapters[Adapter].NumSupportedD3DExtendedFormats);
219 }
220
221 UNLOCK_D3D9();
222 return AdapterModeCount;
223}
224
225/*++
226* @name IDirect3D9::EnumAdapterModes
227* @implemented
228*
229* The function IDirect3D9Impl_EnumAdapterModes looks if the specified display adapter supports
230* a specific pixel format and fills the pMode argument with the available display modes for that format.
231* This function is often used in a loop to enumerate all the display modes the adapter supports.
232*
233* @param LPDIRECT3D iface
234* Pointer to the IDirect3D9 object returned from Direct3DCreate9()
235*
236* @param UINT Adapter
237* Adapter index to get information about. D3DADAPTER_DEFAULT is the primary display.
238* The maximum value for this is the value returned by IDirect3D9::GetAdapterCount() - 1.
239*
240* @param D3DFORMAT Format
241* The pixel format to search for
242*
243* @param UINT Mode
244* Index within the pixel format to be returned.
245* The maximum value for this is the value returned by IDirect3D9::GetAdapterModeCount() - 1.
246*
247* @param D3DDISPLAYMODE* pMode
248* Pointer to a D3DDISPLAYMODE structure to be filled with the display mode information
249* for the specified format.
250*
251* @return HRESULT
252* If the method successfully fills the pMode structure, the return value is D3D_OK.
253* If Adapter is out of range, pMode is a bad pointer or, no modes for the specified
254* format was found or the mode parameter was invalid - the return value will be D3DERR_INVALIDCALL.
255*
256*/
258 UINT Mode, D3DDISPLAYMODE* pMode)
259{
260 const D3DDISPLAYMODE* pMatchingDisplayFormat;
262 LOCK_D3D9();
263
264 if (Adapter >= This->NumDisplayAdapters)
265 {
266 DPRINT1("Invalid Adapter number specified");
267 UNLOCK_D3D9();
268 return D3DERR_INVALIDCALL;
269 }
270
271 if (NULL == pMode)
272 {
273 DPRINT1("Invalid pMode parameter specified");
274 UNLOCK_D3D9();
275 return D3DERR_INVALIDCALL;
276 }
277
279 {
280 pMatchingDisplayFormat = FindDisplayFormat(
281 Format,
282 Mode,
283 This->DisplayAdapters[Adapter].pSupportedD3DFormats,
284 This->DisplayAdapters[Adapter].NumSupportedD3DFormats);
285 }
286 else
287 {
288 pMatchingDisplayFormat = FindDisplayFormat(
289 Format,
290 Mode,
291 This->DisplayAdapters[Adapter].pSupportedD3DExtendedFormats,
292 This->DisplayAdapters[Adapter].NumSupportedD3DExtendedFormats);
293 }
294
295 if (pMatchingDisplayFormat != NULL)
296 {
297 *pMode = *pMatchingDisplayFormat;
298 }
299 UNLOCK_D3D9();
300
301
302 if (pMatchingDisplayFormat == NULL)
303 return D3DERR_INVALIDCALL;
304
305 return D3D_OK;
306}
307
308/*++
309* @name IDirect3D9::GetAdapterDisplayMode
310* @implemented
311*
312* The function IDirect3D9Impl_GetAdapterDisplayMode fills the pMode argument with the
313* currently set display mode.
314*
315* @param LPDIRECT3D iface
316* Pointer to the IDirect3D9 object returned from Direct3DCreate9()
317*
318* @param UINT Adapter
319* Adapter index to get information about. D3DADAPTER_DEFAULT is the primary display.
320* The maximum value for this is the value returned by IDirect3D9::GetAdapterCount() - 1.
321*
322* @param D3DDISPLAYMODE* pMode
323* Pointer to a D3DDISPLAYMODE structure to be filled with the current display mode information.
324*
325* @return HRESULT
326* If the method successfully fills the pMode structure, the return value is D3D_OK.
327* If Adapter is out of range or pMode is a bad pointer, the return value will be D3DERR_INVALIDCALL.
328*
329*/
331{
333 LOCK_D3D9();
334
335 if (Adapter >= This->NumDisplayAdapters)
336 {
337 DPRINT1("Invalid Adapter number specified");
338 UNLOCK_D3D9();
339 return D3DERR_INVALIDCALL;
340 }
341
342 if (NULL == pMode)
343 {
344 DPRINT1("Invalid pMode parameter specified");
345 UNLOCK_D3D9();
346 return D3DERR_INVALIDCALL;
347 }
348
349 /* TODO: Handle (This->DisplayAdapters[Adapter].bInUseFlag == FALSE) */
350 if (FALSE == GetAdapterMode(This->DisplayAdapters[Adapter].szDeviceName, pMode))
351 DPRINT1("Internal error, GetAdapterMode() failed.");
352
353 UNLOCK_D3D9();
354 return D3D_OK;
355}
356
357
358/*++
359* @name IDirect3D9::CheckDeviceType
360* @implemented
361*
362* The function IDirect3D9Impl_CheckDeviceType checks if a specific D3DFORMAT is hardware accelerated
363* on the specified display adapter.
364*
365* @param LPDIRECT3D iface
366* Pointer to the IDirect3D9 object returned from Direct3DCreate9()
367*
368* @param UINT Adapter
369* Adapter index to get information about. D3DADAPTER_DEFAULT is the primary display.
370* The maximum value for this is the value returned by IDirect3D9::GetAdapterCount() - 1.
371*
372* @param D3DDEVTYPE DeviceType
373* One of the D3DDEVTYPE enum members.
374*
375* @param D3DFORMAT DisplayFormat
376* One of the D3DFORMAT enum members except D3DFMT_UNKNOWN for the display adapter mode to be checked.
377*
378* @param D3DFORMAT BackBufferFormat
379* One of the D3DFORMAT enum members for the render target mode to be checked. D3DFMT_UNKNOWN is only allowed in windowed mode.
380*
381* @param BOOL Windowed
382* If this value is TRUE, the D3DFORMAT check will be done for windowed mode and FALSE equals fullscreen mode.
383*
384* @return HRESULT
385* If the format is hardware accelerated, the method returns D3D_OK.
386* If the format isn't hardware accelerated or unsupported - the return value will be D3DERR_NOTAVAILABLE.
387* If Adapter is out of range, DeviceType is invalid,
388* DisplayFormat or BackBufferFormat is invalid - the return value will be D3DERR_INVALIDCALL.
389*
390*/
392 D3DFORMAT DisplayFormat, D3DFORMAT BackBufferFormat, BOOL Windowed)
393{
394 HRESULT hResult;
395
397 LOCK_D3D9();
398
399 if (Adapter >= This->NumDisplayAdapters)
400 {
401 DPRINT1("Invalid Adapter number specified");
402 UNLOCK_D3D9();
403 return D3DERR_INVALIDCALL;
404 }
405
406 if (DeviceType != D3DDEVTYPE_HAL &&
409 {
410 DPRINT1("Invalid DeviceType specified");
411 UNLOCK_D3D9();
412 return D3DERR_INVALIDCALL;
413 }
414
415 if ((BackBufferFormat == D3DFMT_UNKNOWN) &&
416 (Windowed != FALSE))
417 {
418 BackBufferFormat = DisplayFormat;
419 }
420
421 if (DisplayFormat == D3DFMT_UNKNOWN && BackBufferFormat == D3DFMT_UNKNOWN)
422 {
423 DPRINT1("Invalid D3DFORMAT specified");
424 UNLOCK_D3D9();
425 return D3DERR_INVALIDCALL;
426 }
427
428 if (FALSE == IsBackBufferFormat(BackBufferFormat))
429 {
430 DPRINT1("Invalid D3DFORMAT specified");
431 UNLOCK_D3D9();
432 return D3DERR_NOTAVAILABLE;
433 }
434
435 if (TRUE == Windowed && TRUE == IsExtendedFormat(DisplayFormat))
436 {
437 DPRINT1("Extended display modes can only be used in fullscreen mode");
438 UNLOCK_D3D9();
439 return D3DERR_NOTAVAILABLE;
440 }
441
442 hResult = CheckDeviceType(&This->DisplayAdapters[Adapter].DriverCaps, DisplayFormat, BackBufferFormat, Windowed);
443
444 UNLOCK_D3D9();
445 return hResult;
446}
447
448
449/*++
450* @name IDirect3D9::CheckDeviceFormat
451* @implemented
452*
453* The function IDirect3D9Impl_CheckDeviceFormat checks if a specific D3DFORMAT
454* can be used for a specific purpose like texture, depth/stencil buffer or as a render target
455* on the specified display adapter.
456*
457* @param LPDIRECT3D iface
458* Pointer to the IDirect3D9 object returned from Direct3DCreate9()
459*
460* @param UINT Adapter
461* Adapter index to get information about. D3DADAPTER_DEFAULT is the primary display.
462* The maximum value for this is the value returned by IDirect3D9::GetAdapterCount() - 1.
463*
464* @param D3DDEVTYPE DeviceType
465* One of the D3DDEVTYPE enum members.
466*
467* @param D3DFORMAT AdapterFormat
468* One of the D3DFORMAT enum members except D3DFMT_UNKNOWN for the display adapter mode to be checked.
469*
470* @param DWORD Usage
471* Valid values are any of the D3DUSAGE_QUERY constants or any of these D3DUSAGE constants:
472* D3DUSAGE_AUTOGENMIPMAP, D3DUSAGE_DEPTHSTENCIL, D3DUSAGE_DMAP, D3DUSAGE_DYNAMIC,
473* D3DUSAGE_NONSECURE, D3DUSAGE_RENDERTARGET and D3DUSAGE_SOFTWAREPROCESSING.
474*
475* @param D3DRESOURCETYPE RType
476* One of the D3DRESOURCETYPE enum members. Specifies what format will be used for.
477*
478* @param D3DFORMAT CheckFormat
479* One of the D3DFORMAT enum members for the surface format to be checked.
480*
481* @return HRESULT
482* If the format is compatible with the specified usage and resource type, the method returns D3D_OK.
483* If the format isn't compatible with the specified usage and resource type - the return value will be D3DERR_NOTAVAILABLE.
484* If Adapter is out of range, DeviceType is invalid, AdapterFormat or CheckFormat is invalid,
485* Usage and RType isn't compatible - the return value will be D3DERR_INVALIDCALL.
486*
487*/
489 D3DFORMAT AdapterFormat, DWORD Usage, D3DRESOURCETYPE RType,
490 D3DFORMAT CheckFormat)
491{
492 LPD3D9_DRIVERCAPS pDriverCaps;
493 BOOL bIsTextureRType = FALSE;
494 HRESULT hResult;
495
497 LOCK_D3D9();
498
499 if (Adapter >= This->NumDisplayAdapters)
500 {
501 DPRINT1("Invalid Adapter number specified");
502 UNLOCK_D3D9();
503 return D3DERR_INVALIDCALL;
504 }
505
506 if (DeviceType != D3DDEVTYPE_HAL &&
509 {
510 DPRINT1("Invalid DeviceType specified");
511 UNLOCK_D3D9();
512 return D3DERR_INVALIDCALL;
513 }
514
515 if (AdapterFormat == D3DFMT_UNKNOWN ||
516 CheckFormat == D3DFMT_UNKNOWN)
517 {
518 DPRINT1("Invalid D3DFORMAT specified");
519 UNLOCK_D3D9();
520 return D3DERR_INVALIDCALL;
521 }
522
524 {
525 DPRINT1("Invalid Usage specified");
526 UNLOCK_D3D9();
527 return D3DERR_INVALIDCALL;
528 }
529
530 if (RType == D3DRTYPE_TEXTURE ||
531 RType == D3DRTYPE_VOLUMETEXTURE ||
532 RType == D3DRTYPE_CUBETEXTURE)
533 {
534 bIsTextureRType = TRUE;
535 }
536 else if (RType == D3DRTYPE_SURFACE &&
538 Usage != 0)
539 {
540 DPRINT1("When RType is set to D3DRTYPE_SURFACE, Usage must be 0 or have set D3DUSAGE_DEPTHSTENCIL or D3DUSAGE_RENDERTARGET");
541 UNLOCK_D3D9();
542 return D3DERR_INVALIDCALL;
543 }
544
545 if ((Usage & D3DUSAGE_DEPTHSTENCIL) != 0)
546 {
547 if (FALSE == IsZBufferFormat(CheckFormat))
548 {
549 DPRINT1("Invalid CheckFormat Z-Buffer format");
550 UNLOCK_D3D9();
551 return D3DERR_INVALIDCALL;
552 }
553
554 if ((Usage & D3DUSAGE_AUTOGENMIPMAP) != 0)
555 {
556 DPRINT1("Invalid Usage specified, D3DUSAGE_DEPTHSTENCIL and D3DUSAGE_AUTOGENMIPMAP can't be combined.");
557 UNLOCK_D3D9();
558 return D3DERR_INVALIDCALL;
559 }
560 }
561
562 if (FALSE == bIsTextureRType &&
563 RType != D3DRTYPE_SURFACE &&
564 RType != D3DRTYPE_VOLUME)
565 {
566 DPRINT1("Invalid RType specified");
567 UNLOCK_D3D9();
568 return D3DERR_INVALIDCALL;
569 }
570
572 {
573 if (RType == D3DRTYPE_VOLUME || RType == D3DRTYPE_VOLUMETEXTURE)
574 {
575 DPRINT1("Invalid Usage specified, D3DUSAGE_AUTOGENMIPMAP, D3DUSAGE_DEPTHSTENCIL and D3DUSAGE_RENDERTARGET can't be combined with RType D3DRTYPE_VOLUME or D3DRTYPE_VOLUMETEXTURE");
576 UNLOCK_D3D9();
577 return D3DERR_INVALIDCALL;
578 }
579 }
580
581 if (FALSE == bIsTextureRType &&
583 {
584 DPRINT1("Invalid Usage specified, D3DUSAGE_QUERY_VERTEXTEXTURE can only be used with a texture RType");
585 UNLOCK_D3D9();
586 return D3DERR_INVALIDCALL;
587 }
588
589 if ((Usage & D3DUSAGE_AUTOGENMIPMAP) != 0 &&
590 TRUE == IsMultiElementFormat(CheckFormat))
591 {
592 DPRINT1("Invalid Usage specified, D3DUSAGE_AUTOGENMIPMAP can't be used with a multi-element format");
593 UNLOCK_D3D9();
594 return D3DERR_INVALIDCALL;
595 }
596
597 pDriverCaps = &This->DisplayAdapters[Adapter].DriverCaps;
598 if (((Usage & D3DUSAGE_DYNAMIC) != 0) && (bIsTextureRType != FALSE))
599 {
600 if ((pDriverCaps->DriverCaps9.Caps2 & D3DCAPS2_DYNAMICTEXTURES) == 0)
601 {
602 DPRINT1("Driver doesn't support dynamic textures");
603 UNLOCK_D3D9();
604 return D3DERR_NOTAVAILABLE;
605 }
606
608 {
609 DPRINT1("Invalid Usage specified, D3DUSAGE_DEPTHSTENCIL and D3DUSAGE_RENDERTARGET can't be combined with D3DUSAGE_DYNAMIC and a texture RType");
610 UNLOCK_D3D9();
611 return D3DERR_INVALIDCALL;
612 }
613 }
614
615 if ((Usage & D3DUSAGE_DMAP) != 0)
616 {
618 {
619 DPRINT1("Driver doesn't support displacement mapping");
620 UNLOCK_D3D9();
621 return D3DERR_NOTAVAILABLE;
622 }
623
624 if (RType != D3DRTYPE_TEXTURE)
625 {
626 DPRINT1("Invalid Usage specified, D3DUSAGE_DMAP must be combined with RType D3DRTYPE_TEXTURE");
627 UNLOCK_D3D9();
628 return D3DERR_INVALIDCALL;
629 }
630 }
631
632 hResult = CheckDeviceFormat(pDriverCaps, AdapterFormat, Usage, RType, CheckFormat);
633
634 UNLOCK_D3D9();
635 return hResult;
636}
637
639 D3DFORMAT SurfaceFormat, BOOL Windowed,
640 D3DMULTISAMPLE_TYPE MultiSampleType, DWORD* pQualityLevels)
641{
643
644 return D3D_OK;
645}
646
647
648/*++
649* @name IDirect3D9::CheckDepthStencilMatch
650* @implemented
651*
652* The function IDirect3D9Impl_CheckDepthStencilMatch checks if a specific combination
653* of a render target D3DFORMAT and a depth-stencil D3DFORMAT can be used with a specified
654* D3DFORMAT on the specified display adapter.
655*
656* @param LPDIRECT3D iface
657* Pointer to the IDirect3D9 object returned from Direct3DCreate9()
658*
659* @param UINT Adapter
660* Adapter index to get information about. D3DADAPTER_DEFAULT is the primary display.
661* The maximum value for this is the value returned by IDirect3D9::GetAdapterCount() - 1.
662*
663* @param D3DDEVTYPE DeviceType
664* One of the D3DDEVTYPE enum members.
665*
666* @param D3DFORMAT AdapterFormat
667* One of the D3DFORMAT enum members except D3DFMT_UNKNOWN that the display adapter mode where the test should occur.
668*
669* @param D3DFORMAT RenderTargetFormat
670* One of the D3DFORMAT enum members except D3DFMT_UNKNOWN for the display adapter mode's render target format to be tested.
671*
672* @param D3DFORMAT DepthStencilFormat
673* One of the D3DFORMAT enum members except D3DFMT_UNKNOWN for the display adapter mode's depth-stencil format to be tested.
674*
675* @return HRESULT
676* If the DepthStencilFormat can be used with the RenderTargetFormat under the specified AdapterFormat,
677* the method returns D3D_OK.
678* If the DepthStencilFormat can NOT used with the RenderTargetFormat under the specified AdapterFormat,
679* the method returns D3DERR_NOTAVAILABLE.
680* If Adapter is out of range, DeviceType is invalid,
681* AdapterFormat, RenderTargetFormat or DepthStencilFormat is invalid, the method returns D3DERR_INVALIDCALL.
682*
683*/
685 D3DFORMAT AdapterFormat, D3DFORMAT RenderTargetFormat,
686 D3DFORMAT DepthStencilFormat)
687{
688 HRESULT hResult;
689
691 LOCK_D3D9();
692
693 if (Adapter >= This->NumDisplayAdapters)
694 {
695 DPRINT1("Invalid Adapter number specified");
696 UNLOCK_D3D9();
697 return D3DERR_INVALIDCALL;
698 }
699
700 if (DeviceType != D3DDEVTYPE_HAL &&
703 {
704 DPRINT1("Invalid DeviceType specified");
705 UNLOCK_D3D9();
706 return D3DERR_INVALIDCALL;
707 }
708
709 if (AdapterFormat == D3DFMT_UNKNOWN ||
710 RenderTargetFormat == D3DFMT_UNKNOWN ||
711 DepthStencilFormat == D3DFMT_UNKNOWN)
712 {
713 DPRINT1("Invalid D3DFORMAT specified");
714 UNLOCK_D3D9();
715 return D3DERR_INVALIDCALL;
716 }
717
718 hResult = CheckDepthStencilMatch(&This->DisplayAdapters[Adapter].DriverCaps, AdapterFormat, RenderTargetFormat, DepthStencilFormat);
719
720 UNLOCK_D3D9();
721 return hResult;
722}
723
724
725/*++
726* @name IDirect3D9::CheckDeviceFormatConversion
727* @implemented
728*
729* The function IDirect3D9Impl_CheckDeviceFormatConversion checks if a specific D3DFORMAT
730* can be converted to another on the specified display adapter.
731*
732* @param LPDIRECT3D iface
733* Pointer to the IDirect3D9 object returned from Direct3DCreate9()
734*
735* @param UINT Adapter
736* Adapter index to get information about. D3DADAPTER_DEFAULT is the primary display.
737* The maximum value for this is the value returned by IDirect3D9::GetAdapterCount() - 1.
738*
739* @param D3DDEVTYPE DeviceType
740* One of the D3DDEVTYPE enum members. Only D3DDEVTYPE_HAL can potentially return D3D_OK.
741*
742* @param D3DFORMAT SourceFormat
743* One of the D3DFORMAT enum members except D3DFMT_UNKNOWN for the display adapter mode to be converted from.
744*
745* @param D3DFORMAT TargetFormat
746* One of the D3DFORMAT enum members except D3DFMT_UNKNOWN for the display adapter mode to be converted to.
747*
748* @return HRESULT
749* If the SourceFormat can be converted to the TargetFormat, the method returns D3D_OK.
750* If the SourceFormat can NOT be converted to the TargetFormat, the method returns D3DERR_NOTAVAILABLE.
751* If Adapter is out of range, DeviceType is invalid,
752* SourceFormat or TargetFormat is invalid, the method returns D3DERR_INVALIDCALL.
753*
754*/
756 D3DFORMAT SourceFormat, D3DFORMAT TargetFormat)
757{
758 HRESULT hResult;
760 LOCK_D3D9();
761
762 if (Adapter >= This->NumDisplayAdapters)
763 {
764 DPRINT1("Invalid Adapter number specified");
765 UNLOCK_D3D9();
766 return D3DERR_INVALIDCALL;
767 }
768
769 if (DeviceType != D3DDEVTYPE_HAL &&
772 {
773 DPRINT1("Invalid DeviceType specified");
774 UNLOCK_D3D9();
775 return D3DERR_INVALIDCALL;
776 }
777
778 if (SourceFormat == D3DFMT_UNKNOWN ||
779 TargetFormat == D3DFMT_UNKNOWN)
780 {
781 DPRINT1("Invalid D3DFORMAT specified");
782 UNLOCK_D3D9();
783 return D3DERR_NOTAVAILABLE;
784 }
785
787 {
788 hResult = CheckDeviceFormatConversion(&This->DisplayAdapters[Adapter].DriverCaps, SourceFormat, TargetFormat);
789 }
790 else
791 {
792 hResult = D3DERR_NOTAVAILABLE;
793 }
794
795 UNLOCK_D3D9();
796 return hResult;
797}
798
799
800/*++
801* @name IDirect3D9::GetDeviceCaps
802* @implemented
803*
804* The function IDirect3D9Impl_GetDeviceCaps fills the pCaps argument with the
805* capabilities of the specified adapter and device type.
806*
807* @param LPDIRECT3D iface
808* Pointer to the IDirect3D9 object returned from Direct3DCreate9()
809*
810* @param UINT Adapter
811* Adapter index to get information about. D3DADAPTER_DEFAULT is the primary display.
812* The maximum value for this is the value returned by IDirect3D9::GetAdapterCount() - 1.
813*
814* @param D3DDEVTYPE DeviceType
815* One of the D3DDEVTYPE enum members.
816* NOTE: Currently only D3DDEVTYPE_HAL is implemented.
817*
818* @param D3DCAPS9* pCaps
819* Pointer to a D3DCAPS9 structure to be filled with the adapter's device type capabilities.
820*
821* @return HRESULT
822* If the method successfully fills the pCaps structure, the return value is D3D_OK.
823* If Adapter is out of range or pCaps is a bad pointer, the return value will be D3DERR_INVALIDCALL.
824* If DeviceType is invalid, the return value will be D3DERR_INVALIDDEVICE.
825*
826*/
828{
829 HRESULT hResult;
831 LOCK_D3D9();
832
833 if (Adapter >= This->NumDisplayAdapters)
834 {
835 DPRINT1("Invalid Adapter number specified");
836 UNLOCK_D3D9();
837 return D3DERR_INVALIDCALL;
838 }
839
840 if (NULL == pCaps)
841 {
842 DPRINT1("Invalid pCaps parameter specified");
843 UNLOCK_D3D9();
844 return D3DERR_INVALIDCALL;
845 }
846
847 hResult = GetAdapterCaps(&This->DisplayAdapters[Adapter], DeviceType, pCaps);
848
849 UNLOCK_D3D9();
850 return hResult;
851}
852
853/*++
854* @name IDirect3D9::GetAdapterMonitor
855* @implemented
856*
857* The function IDirect3D9Impl_GetAdapterMonitor returns the monitor associated
858* with the specified display adapter.
859*
860* @param LPDIRECT3D iface
861* Pointer to the IDirect3D9 object returned from Direct3DCreate9()
862*
863* @param UINT Adapter
864* Adapter index to get information about. D3DADAPTER_DEFAULT is the primary display.
865* The maximum value for this is the value returned by IDirect3D9::GetAdapterCount() - 1.
866*
867* @return HMONITOR
868* If the method successfully it returns the HMONITOR belonging to the specified adapter.
869* If the method fails, the return value is NULL.
870*
871*/
873{
874 HMONITOR hAdapterMonitor = NULL;
875
877 LOCK_D3D9();
878
879 if (Adapter < This->NumDisplayAdapters)
880 {
881 hAdapterMonitor = GetAdapterMonitor(This->DisplayAdapters[Adapter].szDeviceName);
882 }
883 else
884 {
885 DPRINT1("Invalid Adapter number specified");
886 }
887
888 UNLOCK_D3D9();
889 return hAdapterMonitor;
890}
891
892/*++
893* @name IDirect3D9::CreateDevice
894* @implemented
895*
896* The function IDirect3D9Impl_CreateDevice creates an IDirect3DDevice9 object
897* that represents the display adapter.
898*
899* @param LPDIRECT3D iface
900* Pointer to the IDirect3D9 object returned from Direct3DCreate9()
901*
902* @param UINT Adapter
903* Adapter index to get information about. D3DADAPTER_DEFAULT is the primary display.
904* The maximum value for this is the value returned by IDirect3D::GetAdapterCount() - 1.
905*
906* @param D3DDEVTYPE DeviceType
907* One of the D3DDEVTYPE enum members.
908*
909* @param HWND hFocusWindow
910* A window handle that is used as a reference when Direct3D should switch between
911* foreground mode and background mode.
912*
913* @param DWORD BehaviourFlags
914* Any valid combination of the D3DCREATE constants.
915*
916* @param D3DPRESENT_PARAMETERS* pPresentationParameters
917* Pointer to a D3DPRESENT_PARAMETERS structure describing the parameters for the device
918* to be created. If D3DCREATE_ADAPTERGROUP_DEVICE is specified in the BehaviourFlags parameter,
919* the pPresentationParameters is treated as an array.
920*
921* @param IDirect3DDevice9** ppReturnedDeviceInterface
922* Return object that represents the created device.
923*
924* @return HRESULT
925* If the method successfully creates a device and returns a valid ppReturnedDeviceInterface object,
926* the return value is D3D_OK.
927* If Adapter is out of range, DeviceType is invalid, hFocusWindow is not a valid, BehaviourFlags is invalid
928* pPresentationParameters is invalid or ppReturnedDeviceInterface is a bad pointer, the return value
929* will be D3DERR_INVALIDCALL.
930*
931*/
933 HWND hFocusWindow, DWORD BehaviourFlags,
934 D3DPRESENT_PARAMETERS* pPresentationParameters,
935 struct IDirect3DDevice9** ppReturnedDeviceInterface)
936{
937 DWORD NumAdaptersToCreate;
938 HRESULT Ret;
939
941 LOCK_D3D9();
942
943 if (Adapter >= This->NumDisplayAdapters)
944 {
945 DPRINT1("Invalid Adapter number specified");
946 UNLOCK_D3D9();
947 return D3DERR_INVALIDCALL;
948 }
949
950 if (DeviceType != D3DDEVTYPE_HAL &&
953 {
954 DPRINT1("Invalid DeviceType specified");
955 UNLOCK_D3D9();
956 return D3DERR_INVALIDCALL;
957 }
958
960 {
962 DPRINT1("Sorry, only D3DDEVTYPE_HAL is implemented at this time...");
963 return D3DERR_INVALIDCALL;
964 }
965
966 if (hFocusWindow != NULL && FALSE == IsWindow(hFocusWindow))
967 {
968 DPRINT1("Invalid hFocusWindow parameter specified, expected NULL or a valid HWND");
969 UNLOCK_D3D9();
970 return D3DERR_INVALIDCALL;
971 }
972
973 if (NULL == pPresentationParameters)
974 {
975 DPRINT1("Invalid pPresentationParameters parameter specified");
976 UNLOCK_D3D9();
977 return D3DERR_INVALIDCALL;
978 }
979
980 if (pPresentationParameters->hDeviceWindow != NULL && FALSE == IsWindow(pPresentationParameters->hDeviceWindow))
981 {
982 DPRINT1("Invalid pPresentationParameters->hDeviceWindow parameter specified, expected NULL or a valid HWND");
983 UNLOCK_D3D9();
984 return D3DERR_INVALIDCALL;
985 }
986
987 if (FALSE == pPresentationParameters->Windowed && hFocusWindow == NULL)
988 {
989 DPRINT1("When pPresentationParameters->Windowed is not set, hFocusWindow must be a valid HWND");
990 UNLOCK_D3D9();
991 return D3DERR_INVALIDCALL;
992 }
993
994 if (NULL == hFocusWindow && NULL == pPresentationParameters->hDeviceWindow)
995 {
996 DPRINT1("Any of pPresentationParameters->Windowed and hFocusWindow must be set to a valid HWND");
997 UNLOCK_D3D9();
998 return D3DERR_INVALIDCALL;
999 }
1000
1001 if (Adapter > 0 && NULL == pPresentationParameters->hDeviceWindow)
1002 {
1003 DPRINT1("Invalid pPresentationParameters->hDeviceWindow, must be set to a valid unique HWND when Adapter is greater than 0");
1004 UNLOCK_D3D9();
1005 return D3DERR_INVALIDCALL;
1006 }
1007
1008 if (NULL == ppReturnedDeviceInterface)
1009 {
1010 DPRINT1("Invalid ppReturnedDeviceInterface parameter specified");
1011 UNLOCK_D3D9();
1012 return D3DERR_INVALIDCALL;
1013 }
1014
1015 if ((BehaviourFlags & D3DCREATE_ADAPTERGROUP_DEVICE) != 0)
1016 NumAdaptersToCreate = This->DisplayAdapters[Adapter].NumAdaptersInGroup;
1017 else
1018 NumAdaptersToCreate = 1;
1019
1020 *ppReturnedDeviceInterface = 0;
1021
1022 Ret = CreateD3D9HalDevice(This, Adapter, hFocusWindow, BehaviourFlags, pPresentationParameters, NumAdaptersToCreate, ppReturnedDeviceInterface);
1023
1024 UNLOCK_D3D9();
1025 return Ret;
1026}
1027
1028IDirect3D9Vtbl Direct3D9_Vtbl =
1029{
1030 /* IUnknown */
1034
1035 /* IDirect3D9 */
1050};
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define DPRINT1
Definition: precomp.h:8
const GUID IID_IUnknown
#define UNIMPLEMENTED
Definition: debug.h:115
#define D3DCAPS2_DYNAMICTEXTURES
Definition: d3d8caps.h:25
#define D3DUSAGE_NPATCHES
Definition: d3d8types.h:98
enum _D3DRESOURCETYPE D3DRESOURCETYPE
enum _D3DDEVTYPE D3DDEVTYPE
#define D3DUSAGE_POINTS
Definition: d3d8types.h:96
#define D3DUSAGE_DONOTCLIP
Definition: d3d8types.h:95
@ D3DFMT_UNKNOWN
Definition: d3d8types.h:601
#define D3DUSAGE_DYNAMIC
Definition: d3d8types.h:99
#define D3DUSAGE_WRITEONLY
Definition: d3d8types.h:93
@ D3DRTYPE_TEXTURE
Definition: d3d8types.h:812
@ D3DRTYPE_VOLUMETEXTURE
Definition: d3d8types.h:813
@ D3DRTYPE_CUBETEXTURE
Definition: d3d8types.h:814
@ D3DRTYPE_VOLUME
Definition: d3d8types.h:811
@ D3DRTYPE_SURFACE
Definition: d3d8types.h:810
@ D3DDEVTYPE_SW
Definition: d3d8types.h:578
@ D3DDEVTYPE_HAL
Definition: d3d8types.h:576
@ D3DDEVTYPE_REF
Definition: d3d8types.h:577
#define D3DUSAGE_RENDERTARGET
Definition: d3d8types.h:91
enum _D3DFORMAT D3DFORMAT
#define D3DUSAGE_RTPATCHES
Definition: d3d8types.h:97
#define D3DUSAGE_DEPTHSTENCIL
Definition: d3d8types.h:92
enum _D3DMULTISAMPLE_TYPE D3DMULTISAMPLE_TYPE
#define D3DCREATE_ADAPTERGROUP_DEVICE
Definition: d3d9.h:49
struct IDirect3D9 * LPDIRECT3D9
Definition: d3d9.h:124
VOID AlignedFree(IN OUT LPVOID pObject)
Definition: d3d9_helpers.c:130
static HRESULT WINAPI IDirect3D9Impl_CheckDeviceType(LPDIRECT3D9 iface, UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT DisplayFormat, D3DFORMAT BackBufferFormat, BOOL Windowed)
Definition: d3d9_impl.c:391
static HRESULT WINAPI IDirect3D9Impl_CreateDevice(LPDIRECT3D9 iface, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviourFlags, D3DPRESENT_PARAMETERS *pPresentationParameters, struct IDirect3DDevice9 **ppReturnedDeviceInterface)
Definition: d3d9_impl.c:932
HRESULT WINAPI IDirect3D9Impl_GetAdapterIdentifier(LPDIRECT3D9 iface, UINT Adapter, DWORD Flags, D3DADAPTER_IDENTIFIER9 *pIdentifier)
Definition: d3d9_impl.c:130
static HRESULT WINAPI IDirect3D9Impl_CheckDepthStencilMatch(LPDIRECT3D9 iface, UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat)
Definition: d3d9_impl.c:684
static HRESULT WINAPI IDirect3D9Impl_RegisterSoftwareDevice(LPDIRECT3D9 iface, void *pInitializeFunction)
Definition: d3d9_impl.c:70
static HRESULT WINAPI IDirect3D9Impl_GetAdapterDisplayMode(LPDIRECT3D9 iface, UINT Adapter, D3DDISPLAYMODE *pMode)
Definition: d3d9_impl.c:330
#define LOCK_D3D9()
Definition: d3d9_impl.c:17
static HRESULT WINAPI IDirect3D9Impl_EnumAdapterModes(LPDIRECT3D9 iface, UINT Adapter, D3DFORMAT Format, UINT Mode, D3DDISPLAYMODE *pMode)
Definition: d3d9_impl.c:257
#define UNLOCK_D3D9()
Definition: d3d9_impl.c:18
static UINT WINAPI IDirect3D9Impl_GetAdapterCount(LPDIRECT3D9 iface)
Definition: d3d9_impl.c:90
static HRESULT WINAPI IDirect3D9Impl_CheckDeviceFormatConversion(LPDIRECT3D9 iface, UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SourceFormat, D3DFORMAT TargetFormat)
Definition: d3d9_impl.c:755
static HRESULT WINAPI IDirect3D9Impl_QueryInterface(LPDIRECT3D9 iface, REFIID riid, LPVOID *ppvObject)
Definition: d3d9_impl.c:30
static HRESULT WINAPI IDirect3D9Impl_CheckDeviceMultiSampleType(LPDIRECT3D9 iface, UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat, BOOL Windowed, D3DMULTISAMPLE_TYPE MultiSampleType, DWORD *pQualityLevels)
Definition: d3d9_impl.c:638
static HRESULT WINAPI IDirect3D9Impl_CheckDeviceFormat(LPDIRECT3D9 iface, UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat)
Definition: d3d9_impl.c:488
IDirect3D9Vtbl Direct3D9_Vtbl
Definition: d3d9_impl.c:1028
static UINT WINAPI IDirect3D9Impl_GetAdapterModeCount(LPDIRECT3D9 iface, UINT Adapter, D3DFORMAT Format)
Definition: d3d9_impl.c:192
static ULONG WINAPI IDirect3D9Impl_Release(LPDIRECT3D9 iface)
Definition: d3d9_impl.c:53
static LPDIRECT3D9_INT IDirect3D9ToImpl(LPDIRECT3D9 iface)
Definition: d3d9_impl.c:21
static ULONG WINAPI IDirect3D9Impl_AddRef(LPDIRECT3D9 iface)
Definition: d3d9_impl.c:45
static HMONITOR WINAPI IDirect3D9Impl_GetAdapterMonitor(LPDIRECT3D9 iface, UINT Adapter)
Definition: d3d9_impl.c:872
static HRESULT WINAPI IDirect3D9Impl_GetDeviceCaps(LPDIRECT3D9 iface, UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9 *pCaps)
Definition: d3d9_impl.c:827
#define D3DDEVCAPS2_DMAPNPATCH
Definition: d3d9caps.h:202
#define D3DDEVCAPS2_PRESAMPLEDDMAPNPATCH
Definition: d3d9caps.h:206
@ D3DFMT_A2R10G10B10
Definition: d3d9types.h:779
#define D3DUSAGE_AUTOGENMIPMAP
Definition: d3d9types.h:113
#define D3DUSAGE_DMAP
Definition: d3d9types.h:114
#define D3DUSAGE_QUERY_VERTEXTEXTURE
Definition: d3d9types.h:121
#define D3D_OK
Definition: d3d.h:106
#define D3DERR_INVALIDCALL
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
BOOL GetAdapterInfo(LPCSTR lpszDeviceName, D3DADAPTER_IDENTIFIER9 *pIdentifier)
Definition: adapter.c:150
BOOL GetAdapterMode(LPCSTR lpszDeviceName, D3DDISPLAYMODE *pMode)
Definition: adapter.c:333
const D3DDISPLAYMODE * FindDisplayFormat(D3DFORMAT Format, UINT ModeIndex, const D3DDISPLAYMODE *pSupportedDisplayModes, UINT NumDisplayModes)
Definition: adapter.c:422
HRESULT GetAdapterCaps(const LPDIRECT3D9_DISPLAYADAPTER pDisplayAdapter, D3DDEVTYPE DeviceType, D3DCAPS9 *pDstCaps)
Definition: adapter.c:240
UINT GetDisplayFormatCount(D3DFORMAT Format, const D3DDISPLAYMODE *pSupportedDisplayModes, UINT NumDisplayModes)
Definition: adapter.c:406
HMONITOR GetAdapterMonitor(LPCSTR lpszDeviceName)
Definition: adapter.c:393
HRESULT CreateD3D9HalDevice(LPDIRECT3D9_INT pDirect3D9, UINT Adapter, HWND hFocusWindow, DWORD BehaviourFlags, D3DPRESENT_PARAMETERS *pPresentationParameters, DWORD NumAdaptersToCreate, struct IDirect3DDevice9 **ppReturnedDeviceInterface)
Definition: device.c:95
BOOL IsBackBufferFormat(D3DFORMAT Format)
Definition: format.c:14
BOOL IsMultiElementFormat(D3DFORMAT Format)
Definition: format.c:32
BOOL IsZBufferFormat(D3DFORMAT Format)
Definition: format.c:25
BOOL IsExtendedFormat(D3DFORMAT Format)
Definition: format.c:20
HRESULT CheckDeviceType(LPD3D9_DRIVERCAPS pDriverCaps, D3DFORMAT DisplayFormat, D3DFORMAT BackBufferFormat, BOOL Windowed)
Definition: format.c:224
HRESULT CheckDeviceFormatConversion(LPD3D9_DRIVERCAPS pDriverCaps, D3DFORMAT SourceFormat, D3DFORMAT TargetFormat)
Definition: format.c:495
HRESULT CheckDepthStencilMatch(LPD3D9_DRIVERCAPS pDriverCaps, D3DFORMAT AdapterFormat, D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat)
Definition: format.c:539
HRESULT CheckDeviceFormat(LPD3D9_DRIVERCAPS pDriverCaps, D3DFORMAT AdapterFormat, DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat)
Definition: format.c:326
#define ULONG_PTR
Definition: config.h:101
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ _In_ USAGE _In_ USHORT _In_ USAGE Usage
Definition: hidpi.h:384
_In_ ULONG Mode
Definition: hubbusif.h:303
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
DeviceType
Definition: mmdrv.h:42
unsigned int UINT
Definition: ndis.h:50
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
#define D3DERR_NOTAVAILABLE
Definition: d3d8.h:84
#define memset(x, y, z)
Definition: compat.h:39
D3DCAPS9 DriverCaps9
Definition: d3d9_private.h:68
DWORD DevCaps2
Definition: d3d9caps.h:317
DWORD Caps2
Definition: d3d9caps.h:267
Definition: send.c:48
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
uint32_t ULONG
Definition: typedefs.h:59
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
_In_ void _In_ PCCERT_CONTEXT _In_opt_ LPFILETIME _In_ DWORD _In_ DWORD _Outptr_opt_ void ** ppvObject
Definition: wincrypt.h:6082
#define WINAPI
Definition: msvc.h:6
#define E_NOINTERFACE
Definition: winerror.h:2364
BOOL WINAPI IsWindow(_In_opt_ HWND)
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170