Implemented IDirect3D::GetDeviceCaps()
authorGregor Brunmar <gbrunmar.ros@gmail.com>
Sat, 16 Feb 2008 11:17:46 +0000 (11:17 +0000)
committerGregor Brunmar <gbrunmar.ros@gmail.com>
Sat, 16 Feb 2008 11:17:46 +0000 (11:17 +0000)
svn path=/trunk/; revision=32385

reactos/dll/directx/d3d9/adapter.c
reactos/dll/directx/d3d9/adapter.h
reactos/dll/directx/d3d9/d3d9_create.c
reactos/dll/directx/d3d9/d3d9_impl.c
reactos/dll/directx/d3d9/d3d9_private.h

index 086f87e..0e1d574 100644 (file)
@@ -6,13 +6,25 @@
  * PROGRAMERS:      Gregor Brunmar <gregor (dot) brunmar (at) home (dot) se>
  */
 
+#define _WIN32_WINNT    0x0502
 #include "d3d9_common.h"
 #include <d3d9.h>
 #include <ddraw.h>
 #include <strsafe.h>
 #include <debug.h>
+#include "d3d9_private.h"
 #include "adapter.h"
 
+#define D3D9_CAPS1              (D3DCAPS_READ_SCANLINE)
+#define D3D9_PRE_XP_CAPS2       (D3DCAPS2_CANAUTOGENMIPMAP | D3DCAPS2_DYNAMICTEXTURES | D3DCAPS2_RESERVED | D3DCAPS2_FULLSCREENGAMMA)
+#define D3D9_XP_OR_LATER_CAPS2  (D3D9_PRE_XP_CAPS2 | D3DCAPS2_CANMANAGERESOURCE)
+#define D3D9_CAPS3              (D3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD | D3DCAPS3_LINEAR_TO_SRGB_PRESENTATION | D3DCAPS3_COPY_TO_VIDMEM | D3DCAPS3_COPY_TO_SYSTEMMEM)
+
+#define D3DCAPS2_PRESENT_INTERVAL_SEVERAL       0x00200000
+#define D3DCAPS2_PRESENT_INTERVAL_IMMEDIATE     0x00400000
+
+#define D3DVTXPCAPS_FOGVERTEX                   0x00000004
+
 typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
 typedef BOOL (WINAPI *LPFN_DISABLEWOW64FSREDIRECTION) (PVOID*);
 typedef BOOL (WINAPI *LPFN_REVERTWOW64FSREDIRECTION) (PVOID);
@@ -169,6 +181,98 @@ BOOL GetAdapterInfo(LPCSTR lpszDeviceName, D3DADAPTER_IDENTIFIER9* pIdentifier)
 
 
 
+static BOOL IsWindowsXPorLaterCompatible()
+{
+    OSVERSIONINFOA osvi;
+
+    ZeroMemory(&osvi, sizeof(OSVERSIONINFOA));
+    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
+
+    if (GetVersionExA(&osvi) != 0)
+    {
+        return ( (osvi.dwMajorVersion > 5) ||
+               ( (osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion >= 1) ));
+    }
+
+    return FALSE;
+}
+
+static void CopyDriverCaps(const D3DCAPS9* pSrcCaps, D3DCAPS9* pDstCaps)
+{
+    *pDstCaps = *pSrcCaps;
+
+    pDstCaps->Caps = pSrcCaps->Caps & D3D9_CAPS1;
+
+    /* TODO: Fit in D3DCAPS2_CANCALIBRATEGAMMA somewhere here */
+    if (IsWindowsXPorLaterCompatible())
+        pDstCaps->Caps2 = pSrcCaps->Caps2 & D3D9_XP_OR_LATER_CAPS2;
+    else
+        pDstCaps->Caps2 = pSrcCaps->Caps2 & D3D9_PRE_XP_CAPS2;
+
+    pDstCaps->Caps3 = pSrcCaps->Caps3 & D3D9_CAPS3;
+
+    pDstCaps->PresentationIntervals = D3DPRESENT_INTERVAL_ONE;
+    if (pSrcCaps->Caps2 & D3DCAPS2_PRESENT_INTERVAL_SEVERAL)
+        pDstCaps->PresentationIntervals |= (D3DPRESENT_INTERVAL_TWO | D3DPRESENT_INTERVAL_THREE | D3DPRESENT_INTERVAL_FOUR);
+    if (pSrcCaps->Caps2 & D3DCAPS2_PRESENT_INTERVAL_IMMEDIATE)
+        pDstCaps->PresentationIntervals |= D3DPRESENT_INTERVAL_IMMEDIATE;
+
+    pDstCaps->PrimitiveMiscCaps = pSrcCaps->PrimitiveMiscCaps & ~D3DPMISCCAPS_SEPERATEFVFFOG;
+
+    if (pSrcCaps->VertexProcessingCaps & D3DVTXPCAPS_FOGVERTEX)
+    {
+        pDstCaps->RasterCaps |= D3DPRASTERCAPS_FOGVERTEX;
+        pDstCaps->VertexProcessingCaps &= ~D3DVTXPCAPS_FOGVERTEX;
+    }
+
+    if (pSrcCaps->MaxPointSize < 0.0f)
+        pDstCaps->MaxPointSize = 1.0f;
+}
+
+HRESULT GetAdapterCaps(const LPDIRECT3D9_DISPLAYADAPTER_INT pDisplayAdapter, D3DDEVTYPE DeviceType, D3DCAPS9* pDstCaps)
+{
+    HRESULT hResult = D3DERR_INVALIDDEVICE;
+    LPD3D9_DRIVERCAPS pDriverCaps = NULL;
+
+    ZeroMemory(pDstCaps, sizeof(D3DCAPS9));
+
+    switch (DeviceType)
+    {
+    case D3DDEVTYPE_HAL:
+        pDriverCaps = &pDisplayAdapter->DriverCaps;
+        hResult = D3D_OK;
+        break;
+
+    case D3DDEVTYPE_REF:
+    case D3DDEVTYPE_SW:
+    case D3DDEVTYPE_NULLREF:
+        UNIMPLEMENTED;
+        hResult = D3D_OK;
+        break;
+
+    default:
+        DPRINT1("Unknown DeviceType argument");
+        break;
+    }
+
+    if (pDriverCaps != NULL)
+    {
+        CopyDriverCaps(&pDriverCaps->DriverCaps, pDstCaps);
+    }
+
+    if (SUCCEEDED(hResult))
+    {
+        pDstCaps->DeviceType = DeviceType;
+        pDstCaps->MasterAdapterOrdinal = pDisplayAdapter->MasterAdapterIndex;
+        pDstCaps->AdapterOrdinalInGroup = pDisplayAdapter->AdapterIndexInGroup;
+        pDstCaps->NumberOfAdaptersInGroup = pDisplayAdapter->NumAdaptersInGroup;
+    }
+
+    return hResult;
+}
+
+
+
 static D3DFORMAT Get16BitD3DFormat(LPCSTR lpszDeviceName)
 {
     HDC hDC;
index 8818789..7651ead 100644 (file)
@@ -13,6 +13,8 @@ BOOL GetAdapterInfo(LPCSTR lpszDeviceName, D3DADAPTER_IDENTIFIER9* pIdentifier);
 
 BOOL GetAdapterMode(LPCSTR lpszDeviceName, D3DDISPLAYMODE* pMode);
 
+HRESULT GetAdapterCaps(const LPDIRECT3D9_DISPLAYADAPTER_INT pDisplayAdapter, D3DDEVTYPE DeviceType, D3DCAPS9* pDstCaps);
+
 HMONITOR GetAdapterMonitor(LPCSTR lpszDeviceName);
 
 UINT GetDisplayFormatCount(D3DFORMAT Format, const D3DDISPLAYMODE* pSupportedDisplayModes, UINT NumDisplayModes);
index f3ddecd..e7188ec 100644 (file)
@@ -6,8 +6,7 @@
  * PROGRAMERS:      Gregor Brunmar <gregor (dot) brunmar (at) home (dot) se>
  */
 
-typedef struct IDirect3D9 *LPDIRECT3D9;
-
+#include <d3d9.h>
 #include "d3d9_create.h"
 #include "d3d9_helpers.h"
 #include <debug.h>
index 7fcae5b..201bf6a 100644 (file)
@@ -312,7 +312,8 @@ static HRESULT WINAPI IDirect3D9Impl_EnumAdapterModes(LPDIRECT3D9 iface, UINT Ad
 * If the method successfully fills the pMode structure, the return value is D3D_OK.
 * If Adapter is out of range or pMode is a bad pointer, the return value will be D3DERR_INVALIDCALL.
 *
-*/static HRESULT WINAPI IDirect3D9Impl_GetAdapterDisplayMode(LPDIRECT3D9 iface, UINT Adapter, D3DDISPLAYMODE* pMode)
+*/
+static HRESULT WINAPI IDirect3D9Impl_GetAdapterDisplayMode(LPDIRECT3D9 iface, UINT Adapter, D3DDISPLAYMODE* pMode)
 {
     LPDIRECT3D9_INT This = impl_from_IDirect3D9(iface);
     LOCK_D3D9();
@@ -382,11 +383,58 @@ static HRESULT WINAPI IDirect3D9Impl_CheckDeviceFormatConversion(LPDIRECT3D9 ifa
     return D3D_OK;
 }
 
+
+/*++
+* @name IDirect3D9::GetDeviceCaps
+* @implemented
+*
+* The function IDirect3D9Impl_GetDeviceCaps fills the pCaps argument with the
+* capabilities of the specified adapter and device type.
+*
+* @param LPDIRECT3D iface
+* Pointer to the IDirect3D object returned from Direct3DCreate9()
+*
+* @param UINT Adapter
+* Adapter index to get information about. D3DADAPTER_DEFAULT is the primary display.
+* The maximum value for this is the value returned by IDirect3D::GetAdapterCount().
+*
+* @param D3DDEVTYPE DeviceType
+* One of the D3DDEVTYPE enum members.
+* NOTE: Currently only D3DDEVTYPE_HAL is implemented.
+*
+* @param D3DCAPS9* pCaps
+* Pointer to a D3DCAPS9 structure to be filled with the adapter's device type capabilities.
+*
+* @return HRESULT
+* If the method successfully fills the pCaps structure, the return value is D3D_OK.
+* If Adapter is out of range or pCaps is a bad pointer, the return value will be D3DERR_INVALIDCALL.
+* If DeviceType is invalid, the return value will be D3DERR_INVALIDDEVICE.
+*
+*/
 static HRESULT WINAPI IDirect3D9Impl_GetDeviceCaps(LPDIRECT3D9 iface, UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9* pCaps)
 {
-    UNIMPLEMENTED
+    HRESULT hResult;
+    LPDIRECT3D9_INT This = impl_from_IDirect3D9(iface);
+    LOCK_D3D9();
 
-    return D3D_OK;
+    if (Adapter >= This->NumDisplayAdapters)
+    {
+        DPRINT1("Invalid Adapter number specified");
+        UNLOCK_D3D9();
+        return D3DERR_INVALIDCALL;
+    }
+
+    if (IsBadWritePtr(pCaps, sizeof(D3DCAPS9)))
+    {
+        DPRINT1("Invalid pCaps parameter specified");
+        UNLOCK_D3D9();
+        return D3DERR_INVALIDCALL;
+    }
+
+    hResult = GetAdapterCaps(&This->DisplayAdapters[Adapter], DeviceType, pCaps);
+
+    UNLOCK_D3D9();
+    return hResult;
 }
 
 /*++
index ba48707..5b20a26 100644 (file)
 
 #define DX_D3D9_MAX_NUM_ADAPTERS    12
 
+typedef struct _tagD3D9_DRIVERCAPS
+{
+    D3DCAPS9 DriverCaps;
+} D3D9_DRIVERCAPS, FAR* LPD3D9_DRIVERCAPS;
+
 typedef struct _tagDIRECT3D9DisplayAdapterInfo_
 {
 /* 0x0000 */    GUID DisplayGuid;
 /* 0x0010 */    CHAR szDeviceName[MAX_PATH];
 /* 0x0114 */    DWORD dwStateFlags;
 /* 0x0118 */    BOOL bInUseFlag;
-/* 0x011c */    DWORD unknown000002;
-/* 0x0120 */    DWORD unknown000003;
-/* 0x0124 */    DWORD unknown000004;    /* 0x00000001 */
+/* 0x011c */    DWORD MasterAdapterIndex;
+/* 0x0120 */    DWORD AdapterIndexInGroup;
+/* 0x0124 */    DWORD NumAdaptersInGroup;    /* 0x00000001 */
 /* 0x0128 */    DWORD NumSupportedD3DFormats;
 /* 0x012c */    DWORD NumSupportedD3DExtendedFormats;
 /* 0x0130 */    D3DDISPLAYMODE* pSupportedD3DFormats;
 /* 0x0134 */    D3DDISPLAYMODE* pSupportedD3DExtendedFormats;
 /* 0x0138 */    DWORD unknown000009;
-/* 0x013c */    DWORD unknown000010;    /* D3D9_DRIVERCAPS? */
-/* 0x0140 */    DWORD unknown000011;
-/* 0x0144 */    DWORD unknown000012;
-/* 0x0148 */    DWORD unknown000013;
-/* 0x014c */    DWORD unknown000014;
-/* 0x0150 */    DWORD unknown000015;
-/* 0x0154 */    DWORD unknown000016;
-/* 0x0158 */    DWORD unknown000017;
-/* 0x015c */    DWORD unknown000018;
-/* 0x0160 */    DWORD unknown000019;
-/* 0x0164 */    DWORD unknown000020;
-/* 0x0168 */    DWORD unknown000021;
-/* 0x016c */    DWORD unknown000022;
-/* 0x0170 */    DWORD unknown000023;
-/* 0x0174 */    DWORD unknown000024;
-/* 0x0178 */    DWORD unknown000025;
-/* 0x017c */    DWORD unknown000026;
-/* 0x0180 */    DWORD unknown000027;
-/* 0x0184 */    DWORD unknown000028;
-/* 0x0188 */    DWORD unknown000029;
-/* 0x018c */    DWORD unknown000030;
-/* 0x0190 */    DWORD unknown000031;
-/* 0x0194 */    DWORD unknown000032;
-/* 0x0198 */    DWORD unknown000033;
-/* 0x019c */    DWORD unknown000034;
-/* 0x01a0 */    DWORD unknown000035;
-/* 0x01a4 */    DWORD unknown000036;
-/* 0x01a8 */    DWORD unknown000037;
-/* 0x01ac */    DWORD unknown000038;
-/* 0x01b0 */    DWORD unknown000039;
-/* 0x01b4 */    DWORD unknown000040;
-/* 0x01b8 */    DWORD unknown000041;
-/* 0x01bc */    DWORD unknown000042;
-/* 0x01c0 */    DWORD unknown000043;
-/* 0x01c4 */    DWORD unknown000044;
-/* 0x01c8 */    DWORD unknown000045;
-/* 0x01cc */    DWORD unknown000046;
-/* 0x01d0 */    DWORD unknown000047;
-/* 0x01d4 */    DWORD unknown000048;
-/* 0x01d8 */    DWORD unknown000049;
-/* 0x01dc */    DWORD unknown000050;
-/* 0x01e0 */    DWORD unknown000051;
-/* 0x01e4 */    DWORD unknown000052;
-/* 0x01e8 */    DWORD unknown000053;
-/* 0x01ec */    DWORD unknown000054;
-/* 0x01f0 */    DWORD unknown000055;
-/* 0x01f4 */    DWORD unknown000056;
-/* 0x01f8 */    DWORD unknown000057;
-/* 0x01fc */    DWORD unknown000058;
-/* 0x0200 */    DWORD unknown000059;
-/* 0x0204 */    DWORD unknown000060;
-/* 0x0208 */    DWORD unknown000061;
-/* 0x020c */    DWORD unknown000062;
-/* 0x0210 */    DWORD unknown000063;
-/* 0x0214 */    DWORD unknown000064;
-/* 0x0218 */    DWORD unknown000065;
-/* 0x021c */    DWORD unknown000066;
-/* 0x0220 */    DWORD unknown000067;
-/* 0x0224 */    DWORD unknown000068;
-/* 0x0228 */    DWORD unknown000069;
-/* 0x022c */    DWORD unknown000070;
-/* 0x0230 */    DWORD unknown000071;
-/* 0x0234 */    DWORD unknown000072;
-/* 0x0238 */    DWORD unknown000073;
-/* 0x023c */    DWORD unknown000074;
-/* 0x0240 */    DWORD unknown000075;
-/* 0x0244 */    DWORD unknown000076;
-/* 0x0248 */    DWORD unknown000077;
-/* 0x024c */    DWORD unknown000078;
-/* 0x0250 */    DWORD unknown000079;
-/* 0x0254 */    DWORD unknown000080;
-/* 0x0258 */    DWORD unknown000081;
-/* 0x025c */    DWORD unknown000082;
-/* 0x0260 */    DWORD unknown000083;
-/* 0x0264 */    DWORD unknown000084;
-/* 0x0268 */    DWORD unknown000085;
+/* 0x013c */    D3D9_DRIVERCAPS DriverCaps;
 /* 0x026c */    DWORD dwDisplayWidth;   /* Current display res */
 /* 0x0270 */    DWORD dwDisplayHeight;  /* Current display res */
 /* 0x0274 */    DWORD unknown000088;    /* Current D3DFORMAT */
@@ -119,10 +49,10 @@ typedef struct _tagDIRECT3D9DisplayAdapterInfo_
 /* 0x02a4 */    DWORD unknown000100;
 /* 0x02a8 */    DWORD unknown000101;    /*? 0xf7627000 */
 /* 0x02ac */    DWORD unknown000102;    /*? 0x00000002 */
-/* 0x02b0 */    DWORD unknown000103;    /*? 0x001552A0 */
+/* 0x02b0 */    LPDWORD unknown000103;    /*? 0x001552A0 */
 /* 0x02b4 */    DWORD unknown000104;
 /* 0x02b8 */    DWORD unknown000105;
-} Direct3D9DisplayAdapterInfo_INT, *LPDIRECT3D9_DISPLAYADAPTER_INT;
+} Direct3D9DisplayAdapterInfo_INT, FAR* LPDIRECT3D9_DISPLAYADAPTER_INT;
 
 typedef struct _tagDIRECT3D9_INT_
 {