From d5f05c59c7f7572a5383e2387641af4456ef3289 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Stefan=20D=C3=B6singer?= Date: Wed, 27 Aug 2008 10:42:40 -0500 Subject: [PATCH] ddraw: Beware of the surface type when checking for format support. --- dlls/d3d8/directx.c | 2 +- dlls/d3d9/directx.c | 2 +- dlls/ddraw/ddraw.c | 6 ++++- dlls/ddraw/device.c | 9 ++++--- dlls/ddraw/direct3d.c | 3 ++- dlls/wined3d/directx.c | 57 +++++++++++++++++++++++++++++++++++----- include/wine/wined3d_interface.h | 4 +-- 7 files changed, 68 insertions(+), 15 deletions(-) diff --git a/dlls/d3d8/directx.c b/dlls/d3d8/directx.c index 6bffcb14226..afcb0fe38d5 100644 --- a/dlls/d3d8/directx.c +++ b/dlls/d3d8/directx.c @@ -184,7 +184,7 @@ static HRESULT WINAPI IDirect3D8Impl_CheckDeviceFormat (LPDIRECT3D8 i EnterCriticalSection(&d3d8_cs); hr = IWineD3D_CheckDeviceFormat(This->WineD3D, Adapter, DeviceType, AdapterFormat, - Usage, RType, CheckFormat); + Usage, RType, CheckFormat, SURFACE_OPENGL); LeaveCriticalSection(&d3d8_cs); return hr; } diff --git a/dlls/d3d9/directx.c b/dlls/d3d9/directx.c index 78244ec1751..b605f44da7a 100644 --- a/dlls/d3d9/directx.c +++ b/dlls/d3d9/directx.c @@ -186,7 +186,7 @@ static HRESULT WINAPI IDirect3D9Impl_CheckDeviceFormat(LPDIRECT3D9EX iface, EnterCriticalSection(&d3d9_cs); hr = IWineD3D_CheckDeviceFormat(This->WineD3D, Adapter, DeviceType, AdapterFormat, - Usage, RType, CheckFormat); + Usage, RType, CheckFormat, SURFACE_OPENGL); LeaveCriticalSection(&d3d9_cs); return hr; } diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index 436846cb4df..1728c964867 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -887,6 +887,7 @@ IDirectDrawImpl_GetFourCCCodes(IDirectDraw7 *iface, DWORD count = 0, i, outsize; HRESULT hr; WINED3DDISPLAYMODE d3ddm; + WINED3DSURFTYPE type = This->ImplType; TRACE("(%p)->(%p, %p)\n", This, NumCodes, Codes); IWineD3DDevice_GetDisplayMode(This->wineD3DDevice, @@ -895,6 +896,8 @@ IDirectDrawImpl_GetFourCCCodes(IDirectDraw7 *iface, outsize = NumCodes && Codes ? *NumCodes : 0; + if(type == SURFACE_UNKNOWN) type = SURFACE_GDI; + for(i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) { hr = IWineD3D_CheckDeviceFormat(This->wineD3D, WINED3DADAPTER_DEFAULT, @@ -902,7 +905,8 @@ IDirectDrawImpl_GetFourCCCodes(IDirectDraw7 *iface, d3ddm.Format /* AdapterFormat */, 0 /* usage */, WINED3DRTYPE_SURFACE, - formats[i]); + formats[i], + type); if(SUCCEEDED(hr)) { if(count < outsize) { Codes[count] = formats[i]; diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c index edcb88f956e..94f394951ac 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -1210,7 +1210,8 @@ IDirect3DDeviceImpl_7_EnumTextureFormats(IDirect3DDevice7 *iface, 0 /* AdapterFormat */, 0 /* Usage */, 0 /* ResourceType */, - FormatList[i]); + FormatList[i], + SURFACE_OPENGL); if(hr == D3D_OK) { DDPIXELFORMAT pformat; @@ -1238,7 +1239,8 @@ IDirect3DDeviceImpl_7_EnumTextureFormats(IDirect3DDevice7 *iface, 0 /* AdapterFormat */, WINED3DUSAGE_QUERY_LEGACYBUMPMAP, 0 /* ResourceType */, - BumpFormatList[i]); + BumpFormatList[i], + SURFACE_OPENGL); if(hr == D3D_OK) { DDPIXELFORMAT pformat; @@ -1347,7 +1349,8 @@ IDirect3DDeviceImpl_2_EnumTextureFormats(IDirect3DDevice2 *iface, 0 /* AdapterFormat */, 0 /* Usage */, 0 /* ResourceType */, - FormatList[i]); + FormatList[i], + SURFACE_OPENGL); if(hr == D3D_OK) { DDSURFACEDESC sdesc; diff --git a/dlls/ddraw/direct3d.c b/dlls/ddraw/direct3d.c index 6c47e695a67..d3ce886c10e 100644 --- a/dlls/ddraw/direct3d.c +++ b/dlls/ddraw/direct3d.c @@ -1205,7 +1205,8 @@ IDirect3DImpl_7_EnumZBufferFormats(IDirect3D7 *iface, d3ddm.Format /* AdapterFormat */, WINED3DUSAGE_DEPTHSTENCIL /* Usage */, WINED3DRTYPE_SURFACE, - FormatList[i]); + FormatList[i], + SURFACE_OPENGL); if(hr == D3D_OK) { DDPIXELFORMAT pformat; diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 60d77f0c27c..9f48da93b12 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -148,7 +148,7 @@ static const struct { static int numAdapters = 0; static struct WineD3DAdapter Adapters[1]; -static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DFORMAT AdapterFormat, DWORD Usage, WINED3DRESOURCETYPE RType, WINED3DFORMAT CheckFormat); +static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DFORMAT AdapterFormat, DWORD Usage, WINED3DRESOURCETYPE RType, WINED3DFORMAT CheckFormat, WINED3DSURFTYPE SurfaceType); static const struct fragment_pipeline *select_fragment_implementation(UINT Adapter, WINED3DDEVTYPE DeviceType); static const shader_backend_t *select_shader_backend(UINT Adapter, WINED3DDEVTYPE DeviceType); static const struct blit_shader *select_blit_implementation(UINT Adapter, WINED3DDEVTYPE DeviceType); @@ -1954,7 +1954,7 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceType(IWineD3D *iface, UINT Adapter } /* Use CheckDeviceFormat to see if the BackBufferFormat is usable with the given DisplayFormat */ - hr = IWineD3DImpl_CheckDeviceFormat(iface, Adapter, DeviceType, DisplayFormat, WINED3DUSAGE_RENDERTARGET, WINED3DRTYPE_SURFACE, BackBufferFormat); + hr = IWineD3DImpl_CheckDeviceFormat(iface, Adapter, DeviceType, DisplayFormat, WINED3DUSAGE_RENDERTARGET, WINED3DRTYPE_SURFACE, BackBufferFormat, SURFACE_OPENGL); if(FAILED(hr)) TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s/%s\n", debug_d3dformat(DisplayFormat), debug_d3dformat(BackBufferFormat)); @@ -2421,9 +2421,37 @@ static BOOL CheckTextureCapability(UINT Adapter, WINED3DDEVTYPE DeviceType, WINE return FALSE; } -static BOOL CheckSurfaceCapability(UINT Adapter, WINED3DFORMAT AdapterFormat, WINED3DDEVTYPE DeviceType, WINED3DFORMAT CheckFormat) { +static BOOL CheckSurfaceCapability(UINT Adapter, WINED3DFORMAT AdapterFormat, WINED3DDEVTYPE DeviceType, WINED3DFORMAT CheckFormat, WINED3DSURFTYPE SurfaceType) { const struct blit_shader *blitter; + if(SurfaceType == SURFACE_GDI) { + switch(CheckFormat) { + case WINED3DFMT_R8G8B8: + case WINED3DFMT_A8R8G8B8: + case WINED3DFMT_X8R8G8B8: + case WINED3DFMT_R5G6B5: + case WINED3DFMT_X1R5G5B5: + case WINED3DFMT_A1R5G5B5: + case WINED3DFMT_A4R4G4B4: + case WINED3DFMT_R3G3B2: + case WINED3DFMT_A8: + case WINED3DFMT_A8R3G3B2: + case WINED3DFMT_X4R4G4B4: + case WINED3DFMT_A2B10G10R10: + case WINED3DFMT_A8B8G8R8: + case WINED3DFMT_X8B8G8R8: + case WINED3DFMT_G16R16: + case WINED3DFMT_A2R10G10B10: + case WINED3DFMT_A16B16G16R16: + case WINED3DFMT_P8: + TRACE_(d3d_caps)("[OK]\n"); + return TRUE; + default: + TRACE_(d3d_caps)("[FAILED] - not available on GDI surfaces\n"); + return FALSE; + } + } + /* All format that are supported for textures are supported for surfaces as well */ if(CheckTextureCapability(Adapter, DeviceType, CheckFormat)) return TRUE; /* All depth stencil formats are supported on surfaces */ @@ -2465,7 +2493,8 @@ static BOOL CheckVertexTextureCapability(UINT Adapter, WINED3DFORMAT CheckFormat } static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, - WINED3DFORMAT AdapterFormat, DWORD Usage, WINED3DRESOURCETYPE RType, WINED3DFORMAT CheckFormat) { + WINED3DFORMAT AdapterFormat, DWORD Usage, WINED3DRESOURCETYPE RType, WINED3DFORMAT CheckFormat, + WINED3DSURFTYPE SurfaceType) { IWineD3DImpl *This = (IWineD3DImpl *)iface; DWORD UsageCaps = 0; @@ -2483,6 +2512,12 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapt } if(RType == WINED3DRTYPE_CUBETEXTURE) { + + if(SurfaceType != SURFACE_OPENGL) { + TRACE("[FAILED]\n"); + return WINED3DERR_NOTAVAILABLE; + } + /* Cubetexture allows: * - D3DUSAGE_AUTOGENMIPMAP * - D3DUSAGE_DEPTHSTENCIL @@ -2596,7 +2631,7 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapt * - D3DUSAGE_RENDERTARGET */ - if(CheckSurfaceCapability(Adapter, AdapterFormat, DeviceType, CheckFormat)) { + if(CheckSurfaceCapability(Adapter, AdapterFormat, DeviceType, CheckFormat, SurfaceType)) { if(Usage & WINED3DUSAGE_DEPTHSTENCIL) { if(CheckDepthStencilCapability(Adapter, AdapterFormat, CheckFormat)) { UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL; @@ -2642,6 +2677,11 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapt * - D3DUSAGE_QUERY_WRAPANDMIP */ + if(SurfaceType != SURFACE_OPENGL) { + TRACE("[FAILED]\n"); + return WINED3DERR_NOTAVAILABLE; + } + /* Check if the texture format is around */ if(CheckTextureCapability(Adapter, DeviceType, CheckFormat)) { if(Usage & WINED3DUSAGE_AUTOGENMIPMAP) { @@ -2764,6 +2804,11 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapt * - D3DUSAGE_QUERY_WRAPANDMIP */ + if(SurfaceType != SURFACE_OPENGL) { + TRACE("[FAILED]\n"); + return WINED3DERR_NOTAVAILABLE; + } + /* Check volume texture and volume usage caps */ if(GL_SUPPORT(EXT_TEXTURE3D)) { if(CheckTextureCapability(Adapter, DeviceType, CheckFormat) == FALSE) { @@ -2896,7 +2941,7 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapt /* For instance vertexbuffer/indexbuffer aren't supported yet because no Windows drivers seem to offer it */ TRACE_(d3d_caps)("Unhandled resource type D3DRTYPE_INDEXBUFFER / D3DRTYPE_VERTEXBUFFER\n"); return WINED3DERR_NOTAVAILABLE; - } + } /* This format is nothing special and it is supported perfectly. * However, ati and nvidia driver on windows do not mark this format as diff --git a/include/wine/wined3d_interface.h b/include/wine/wined3d_interface.h index 4b960d55221..6ecab39e933 100644 --- a/include/wine/wined3d_interface.h +++ b/include/wine/wined3d_interface.h @@ -310,7 +310,7 @@ DECLARE_INTERFACE_(IWineD3D, IWineD3DBase) STDMETHOD(CheckDeviceMultiSampleType)(THIS_ UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DFORMAT SurfaceFormat, BOOL Windowed, WINED3DMULTISAMPLE_TYPE MultiSampleType, DWORD *pQuality) PURE; STDMETHOD(CheckDepthStencilMatch)(THIS_ UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DFORMAT AdapterFormat, WINED3DFORMAT RenderTargetFormat, WINED3DFORMAT DepthStencilFormat) PURE; STDMETHOD(CheckDeviceType)(THIS_ UINT Adapter, WINED3DDEVTYPE CheckType, WINED3DFORMAT DisplayFormat, WINED3DFORMAT BackBufferFormat, BOOL Windowed) PURE; - STDMETHOD(CheckDeviceFormat)(THIS_ UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DFORMAT AdapterFormat, DWORD Usage, WINED3DRESOURCETYPE RType, WINED3DFORMAT CheckFormat) PURE; + STDMETHOD(CheckDeviceFormat)(THIS_ UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DFORMAT AdapterFormat, DWORD Usage, WINED3DRESOURCETYPE RType, WINED3DFORMAT CheckFormat, WINED3DSURFTYPE SurfaceType) PURE; STDMETHOD(CheckDeviceFormatConversion)(THIS_ UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DFORMAT SourceFormat, WINED3DFORMAT TargetFormat) PURE; STDMETHOD(GetDeviceCaps)(THIS_ UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DCAPS *pCaps) PURE; STDMETHOD(CreateDevice)(THIS_ UINT Adapter, WINED3DDEVTYPE DeviceType,HWND hFocusWindow, DWORD BehaviorFlags, struct IWineD3DDevice **ppReturnedDeviceInterface, IUnknown *parent) PURE; @@ -336,7 +336,7 @@ DECLARE_INTERFACE_(IWineD3D, IWineD3DBase) #define IWineD3D_CheckDeviceMultiSampleType(p,a,b,c,d,e,f) (p)->lpVtbl->CheckDeviceMultiSampleType(p,a,b,c,d,e,f) #define IWineD3D_CheckDepthStencilMatch(p,a,b,c,d,e) (p)->lpVtbl->CheckDepthStencilMatch(p,a,b,c,d,e) #define IWineD3D_CheckDeviceType(p,a,b,c,d,e) (p)->lpVtbl->CheckDeviceType(p,a,b,c,d,e) -#define IWineD3D_CheckDeviceFormat(p,a,b,c,d,e,f) (p)->lpVtbl->CheckDeviceFormat(p,a,b,c,d,e,f) +#define IWineD3D_CheckDeviceFormat(p,a,b,c,d,e,f,g) (p)->lpVtbl->CheckDeviceFormat(p,a,b,c,d,e,f,g) #define IWineD3D_CheckDeviceFormatConversion(p,a,b,c,d) (p)->lpVtbl->CheckDeviceFormatConversion(p,a,b,c,d) #define IWineD3D_GetDeviceCaps(p,a,b,c) (p)->lpVtbl->GetDeviceCaps(p,a,b,c) #define IWineD3D_CreateDevice(p,a,b,c,d,e,f) (p)->lpVtbl->CreateDevice(p,a,b,c,d,e,f) -- 2.11.4.GIT