diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index 4dd16e06d54..162df0f050b 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -383,8 +383,7 @@ static HRESULT WINAPI IDirect3DDevice9Impl_StretchRect(LPDIRECT3DDEVICE9 iface IDirect3DSurface9Impl *dst = (IDirect3DSurface9Impl *) pDestSurface; TRACE("(%p)->(%p,%p,%p,%p,%d)\n" , This, src, pSourceRect, dst, pDestRect, Filter); - if(Filter != D3DTEXF_NONE) ERR("Texture filters not supported yet\n"); - return IWineD3DSurface_Blt(dst->wineD3DSurface, (RECT *) pDestRect, src->wineD3DSurface, (RECT *) pSourceRect, 0, NULL); + return IWineD3DSurface_Blt(dst->wineD3DSurface, (RECT *) pDestRect, src->wineD3DSurface, (RECT *) pSourceRect, 0, NULL, Filter); } static HRESULT WINAPI IDirect3DDevice9Impl_ColorFill(LPDIRECT3DDEVICE9 iface, IDirect3DSurface9* pSurface, CONST RECT* pRect, D3DCOLOR color) { diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index 5eca9c23b15..13f5d4d20cb 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -719,7 +719,8 @@ IDirectDrawSurfaceImpl_Blt(IDirectDrawSurface7 *iface, Src ? Src->WineD3DSurface : NULL, SrcRect, Flags, - DDBltFx); + DDBltFx, + WINED3DTEXF_NONE); } /***************************************************************************** diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index d1224e43a62..c6eb6550bad 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -4972,7 +4972,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ColorFill(IWineD3DDevice *iface, IWineD memset(&BltFx, 0, sizeof(BltFx)); BltFx.dwSize = sizeof(BltFx); BltFx.u5.dwFillColor = color; - return IWineD3DSurface_Blt(pSurface, (RECT *) pRect, NULL, NULL, DDBLT_COLORFILL, &BltFx); + return IWineD3DSurface_Blt(pSurface, (RECT *) pRect, NULL, NULL, DDBLT_COLORFILL, &BltFx, WINED3DTEXF_NONE); } /* rendertarget and deptth stencil functions */ diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 21ac1531809..1684d1a6583 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -2268,11 +2268,10 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_Flip(IWineD3DSurface *iface, IWineD3DS /* Does a direct frame buffer -> texture copy. Stretching is done * with single pixel copy calls */ -static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3DSurface *SrcSurface, IWineD3DSwapChainImpl *swapchain, WINED3DRECT *srect, WINED3DRECT *drect, BOOL upsidedown) { +static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3DSurface *SrcSurface, IWineD3DSwapChainImpl *swapchain, WINED3DRECT *srect, WINED3DRECT *drect, BOOL upsidedown, WINED3DTEXTUREFILTERTYPE Filter) { IWineD3DDeviceImpl *myDevice = This->resource.wineD3DDevice; float xrel, yrel; UINT row; - BOOL warned = FALSE; /* deliberately not static */ IWineD3DSurfaceImpl *Src = (IWineD3DSurfaceImpl *) SrcSurface; ENTER_GL(); @@ -2296,6 +2295,12 @@ static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3D if( (xrel - 1.0 < -eps) || (xrel - 1.0 > eps)) { FIXME("Doing a pixel by pixel copy from the framebuffer to a texture, expect major performance issues\n"); + + if(Filter != WINED3DTEXF_NONE) { + ERR("Texture filtering not supported in direct blit\n"); + } + } else if((Filter != WINED3DTEXF_NONE) && ((yrel - 1.0 < -eps) || (yrel - 1.0 > eps))) { + ERR("Texture filtering not supported in direct blit\n"); } if(upsidedown && @@ -2323,11 +2328,6 @@ static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3D */ UINT col; - if(!warned) { - warned = TRUE; - FIXME("Doing a pixel by pixel render target -> texture copy, expect performance issues\n"); - } - for(col = drect->x1; col < drect->x2; col++) { glCopyTexSubImage2D(This->glDescription.target, This->glDescription.level, @@ -2350,7 +2350,7 @@ static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3D } /* Uses the hardware to stretch and flip the image */ -static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWineD3DSurface *SrcSurface, IWineD3DSwapChainImpl *swapchain, WINED3DRECT *srect, WINED3DRECT *drect, BOOL upsidedown) { +static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWineD3DSurface *SrcSurface, IWineD3DSwapChainImpl *swapchain, WINED3DRECT *srect, WINED3DRECT *drect, BOOL upsidedown, WINED3DTEXTUREFILTERTYPE Filter) { GLuint src, backup = 0; IWineD3DDeviceImpl *myDevice = This->resource.wineD3DDevice; IWineD3DSurfaceImpl *Src = (IWineD3DSurfaceImpl *) SrcSurface; @@ -2408,9 +2408,11 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine checkGLcall("glCopyTexSubImage2D"); /* No issue with overriding these - the sampler is dirty due to blit usage */ - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, + stateLookup[WINELOOKUP_MAGFILTER][Filter - minLookup[WINELOOKUP_MAGFILTER]]); checkGLcall("glTexParameteri"); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + minMipLookup[Filter][WINED3DTEXF_NONE]); checkGLcall("glTexParameteri"); if(!swapchain || (IWineD3DSurface *) Src == swapchain->backBuffer[0]) { @@ -2533,7 +2535,7 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine } /* Not called from the VTable */ -static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *DestRect, IWineD3DSurface *SrcSurface, RECT *SrcRect, DWORD Flags, DDBLTFX *DDBltFx) { +static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *DestRect, IWineD3DSurface *SrcSurface, RECT *SrcRect, DWORD Flags, DDBLTFX *DDBltFx, WINED3DTEXTUREFILTERTYPE Filter) { WINED3DRECT rect; IWineD3DDeviceImpl *myDevice = This->resource.wineD3DDevice; IWineD3DSwapChainImpl *srcSwapchain = NULL, *dstSwapchain = NULL; @@ -2709,10 +2711,10 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT * } else if((!stretchx) || rect.x2 - rect.x1 > Src->currentDesc.Width || rect.y2 - rect.y1 > Src->currentDesc.Height) { TRACE("No stretching in x direction, using direct framebuffer -> texture copy\n"); - fb_copy_to_texture_direct(This, SrcSurface, srcSwapchain, &srect, &rect, upsideDown); + fb_copy_to_texture_direct(This, SrcSurface, srcSwapchain, &srect, &rect, upsideDown, Filter); } else { TRACE("Using hardware stretching to flip / stretch the texture\n"); - fb_copy_to_texture_hwstretch(This, SrcSurface, srcSwapchain, &srect, &rect, upsideDown); + fb_copy_to_texture_hwstretch(This, SrcSurface, srcSwapchain, &srect, &rect, upsideDown, Filter); } if(!(This->Flags & SFLAG_DONOTFREE)) { @@ -2799,12 +2801,12 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT * glBindTexture(GL_TEXTURE_2D, Src->glDescription.textureName); checkGLcall("glBindTexture"); - /* No filtering for blts */ + /* Filtering for StretchRect */ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, - GL_NEAREST); + stateLookup[WINELOOKUP_MAGFILTER][Filter - minLookup[WINELOOKUP_MAGFILTER]]); checkGLcall("glTexParameteri"); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, - GL_NEAREST); + minMipLookup[Filter][WINED3DTEXF_NONE]); checkGLcall("glTexParameteri"); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); @@ -2966,7 +2968,7 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT * return WINED3DERR_INVALIDCALL; } -static HRESULT WINAPI IWineD3DSurfaceImpl_Blt(IWineD3DSurface *iface, RECT *DestRect, IWineD3DSurface *SrcSurface, RECT *SrcRect, DWORD Flags, DDBLTFX *DDBltFx) { +static HRESULT WINAPI IWineD3DSurfaceImpl_Blt(IWineD3DSurface *iface, RECT *DestRect, IWineD3DSurface *SrcSurface, RECT *SrcRect, DWORD Flags, DDBLTFX *DDBltFx, WINED3DTEXTUREFILTERTYPE Filter) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; IWineD3DSurfaceImpl *Src = (IWineD3DSurfaceImpl *) SrcSurface; IWineD3DDeviceImpl *myDevice = This->resource.wineD3DDevice; @@ -2984,14 +2986,14 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_Blt(IWineD3DSurface *iface, RECT *Dest /* Special cases for RenderTargets */ if( (This->resource.usage & WINED3DUSAGE_RENDERTARGET) || ( Src && (Src->resource.usage & WINED3DUSAGE_RENDERTARGET) )) { - if(IWineD3DSurfaceImpl_BltOverride(This, DestRect, SrcSurface, SrcRect, Flags, DDBltFx) == WINED3D_OK) return WINED3D_OK; + if(IWineD3DSurfaceImpl_BltOverride(This, DestRect, SrcSurface, SrcRect, Flags, DDBltFx, Filter) == WINED3D_OK) return WINED3D_OK; } /* For the rest call the X11 surface implementation. * For RenderTargets this should be implemented OpenGL accelerated in BltOverride, * other Blts are rather rare */ - return IWineGDISurfaceImpl_Blt(iface, DestRect, SrcSurface, SrcRect, Flags, DDBltFx); + return IWineGDISurfaceImpl_Blt(iface, DestRect, SrcSurface, SrcRect, Flags, DDBltFx, Filter); } HRESULT WINAPI IWineD3DSurfaceImpl_GetBltStatus(IWineD3DSurface *iface, DWORD Flags) { @@ -3086,7 +3088,7 @@ HRESULT WINAPI IWineD3DSurfaceImpl_BltFast(IWineD3DSurface *iface, DWORD dstx, D if(trans & DDBLTFAST_DONOTWAIT) Flags |= DDBLT_DONOTWAIT; - if(IWineD3DSurfaceImpl_BltOverride(This, &DstRect, Source, &SrcRect, Flags, NULL) == WINED3D_OK) return WINED3D_OK; + if(IWineD3DSurfaceImpl_BltOverride(This, &DstRect, Source, &SrcRect, Flags, NULL, WINED3DTEXF_NONE) == WINED3D_OK) return WINED3D_OK; } diff --git a/dlls/wined3d/surface_gdi.c b/dlls/wined3d/surface_gdi.c index 3c2981e28e0..a61fc626346 100644 --- a/dlls/wined3d/surface_gdi.c +++ b/dlls/wined3d/surface_gdi.c @@ -491,7 +491,8 @@ IWineGDISurfaceImpl_Blt(IWineD3DSurface *iface, IWineD3DSurface *SrcSurface, RECT *SrcRect, DWORD Flags, - DDBLTFX *DDBltFx) + DDBLTFX *DDBltFx, + WINED3DTEXTUREFILTERTYPE Filter) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface; IWineD3DSurfaceImpl *Src = (IWineD3DSurfaceImpl *) SrcSurface; @@ -528,6 +529,11 @@ IWineGDISurfaceImpl_Blt(IWineD3DSurface *iface, return DDERR_SURFACEBUSY; } + if(Filter != WINED3DTEXF_NONE) { + /* Can happen when d3d9 apps do a StretchRect call which isn't handled in gl */ + FIXME("Filters not supported in software blit\n"); + } + if (Src == This) { IWineD3DSurface_LockRect(iface, &dlock, NULL, 0); diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index d46067d41a7..83506e96cec 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -191,7 +191,7 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO if (This->presentParms.Windowed) { MapWindowPoints(NULL, This->win_handle, (LPPOINT)&destRect, 2); } - IWineD3DSurface_Blt(This->backBuffer[0], &destRect, (IWineD3DSurface *) &cursor, NULL, DDBLT_KEYSRC, NULL); + IWineD3DSurface_Blt(This->backBuffer[0], &destRect, (IWineD3DSurface *) &cursor, NULL, DDBLT_KEYSRC, NULL, WINED3DTEXF_NONE); } if (pSourceRect || pDestRect) FIXME("Unhandled present options %p/%p\n", pSourceRect, pDestRect); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 976b86717fb..be5818c3e14 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1087,7 +1087,7 @@ void WINAPI IWineD3DSurfaceImpl_SetGlTextureDesc(IWineD3DSurface *iface, UINT te void WINAPI IWineD3DSurfaceImpl_GetGlDesc(IWineD3DSurface *iface, glDescriptor **glDescription); const void *WINAPI IWineD3DSurfaceImpl_GetData(IWineD3DSurface *iface); HRESULT WINAPI IWineD3DSurfaceImpl_SetFormat(IWineD3DSurface *iface, WINED3DFORMAT format); -HRESULT WINAPI IWineGDISurfaceImpl_Blt(IWineD3DSurface *iface, RECT *DestRect, IWineD3DSurface *SrcSurface, RECT *SrcRect, DWORD Flags, DDBLTFX *DDBltFx); +HRESULT WINAPI IWineGDISurfaceImpl_Blt(IWineD3DSurface *iface, RECT *DestRect, IWineD3DSurface *SrcSurface, RECT *SrcRect, DWORD Flags, DDBLTFX *DDBltFx, WINED3DTEXTUREFILTERTYPE Filter); HRESULT WINAPI IWineGDISurfaceImpl_BltFast(IWineD3DSurface *iface, DWORD dstx, DWORD dsty, IWineD3DSurface *Source, RECT *rsrc, DWORD trans); HRESULT WINAPI IWineD3DSurfaceImpl_SetPalette(IWineD3DSurface *iface, IWineD3DPalette *Pal); HRESULT WINAPI IWineD3DSurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHDC); diff --git a/include/wine/wined3d_interface.h b/include/wine/wined3d_interface.h index 7842076015d..229bcc6d3ec 100644 --- a/include/wine/wined3d_interface.h +++ b/include/wine/wined3d_interface.h @@ -1093,7 +1093,7 @@ DECLARE_INTERFACE_(IWineD3DSurface,IWineD3DResource) STDMETHOD(GetDC)(THIS_ HDC *pHdc) PURE; STDMETHOD(ReleaseDC)(THIS_ HDC hdc) PURE; STDMETHOD(Flip)(THIS_ IWineD3DSurface *Override, DWORD FLAGS) PURE; - STDMETHOD(Blt)(THIS_ RECT *DestRect, IWineD3DSurface *SrcSurface, RECT *SrcRect, DWORD Flags, DDBLTFX *DDBltFx) PURE; + STDMETHOD(Blt)(THIS_ RECT *DestRect, IWineD3DSurface *SrcSurface, RECT *SrcRect, DWORD Flags, DDBLTFX *DDBltFx, WINED3DTEXTUREFILTERTYPE Filter) PURE; STDMETHOD(GetBltStatus)(THIS_ DWORD Flags) PURE; STDMETHOD(GetFlipStatus)(THIS_ DWORD Flags) PURE; STDMETHOD(IsLost)(THIS) PURE; @@ -1146,7 +1146,7 @@ DECLARE_INTERFACE_(IWineD3DSurface,IWineD3DResource) #define IWineD3DSurface_GetDC(p,a) (p)->lpVtbl->GetDC(p,a) #define IWineD3DSurface_ReleaseDC(p,a) (p)->lpVtbl->ReleaseDC(p,a) #define IWineD3DSurface_Flip(p,a,b) (p)->lpVtbl->Flip(p,a,b) -#define IWineD3DSurface_Blt(p,a,b,c,d,e) (p)->lpVtbl->Blt(p,a,b,c,d,e) +#define IWineD3DSurface_Blt(p,a,b,c,d,e,f) (p)->lpVtbl->Blt(p,a,b,c,d,e,f) #define IWineD3DSurface_GetBltStatus(p,a) (p)->lpVtbl->GetBltStatus(p,a) #define IWineD3DSurface_GetFlipStatus(p,a) (p)->lpVtbl->GetFlipStatus(p,a) #define IWineD3DSurface_IsLost(p) (p)->lpVtbl->IsLost(p)