wined3d: Add Filtering to IWineD3DSurface::Blt and handle it.

This is to allow StretchRect to pass the texture filter to WineD3D.
DirectDraw sets the texture filter to WINED3DTEXF_NONE, simmilar to all
other functions which do not need filtering.
This commit is contained in:
Stefan Dösinger 2007-04-03 12:00:15 +02:00 committed by Alexandre Julliard
parent 1c1fdbe96a
commit 290f2eb146
8 changed files with 37 additions and 29 deletions

View file

@ -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) {

View file

@ -719,7 +719,8 @@ IDirectDrawSurfaceImpl_Blt(IDirectDrawSurface7 *iface,
Src ? Src->WineD3DSurface : NULL,
SrcRect,
Flags,
DDBltFx);
DDBltFx,
WINED3DTEXF_NONE);
}
/*****************************************************************************

View file

@ -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 */

View file

@ -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;
}

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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)