From dcff7dc213cfcc9541803dedd16ab2298837f416 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Tue, 9 Oct 2007 22:17:59 +0200 Subject: [PATCH] wined3d: Begin centralizing surface location management. --- dlls/wined3d/context.c | 2 +- dlls/wined3d/device.c | 10 ++++---- dlls/wined3d/drawprim.c | 14 +++++------ dlls/wined3d/surface.c | 41 ++++++++++++++++++++++---------- dlls/wined3d/surface_base.c | 2 +- dlls/wined3d/surface_gdi.c | 16 ++++++++++++- dlls/wined3d/swapchain.c | 4 ++-- dlls/wined3d/wined3d_private.h | 3 +++ include/wine/wined3d_interface.h | 2 ++ 9 files changed, 63 insertions(+), 31 deletions(-) diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 245770ead96..dc64a5cb0ea 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -819,7 +819,7 @@ static inline WineD3DContext *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurf IWineD3DSurface_PreLoad(This->lastActiveRenderTarget); /* Assume that the drawable will be modified by some other things now */ - ((IWineD3DSurfaceImpl *) This->lastActiveRenderTarget)->Flags &= ~SFLAG_INDRAWABLE; + IWineD3DSurface_ModifyLocation(This->lastActiveRenderTarget, SFLAG_INDRAWABLE, FALSE); This->isInDraw = oldInDraw; } diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index bbde40cb95d..2aca0cf73e0 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1441,6 +1441,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevic &object->frontBuffer, NULL /* pShared (always null)*/); if (object->frontBuffer != NULL) { + IWineD3DSurface_ModifyLocation(object->frontBuffer, SFLAG_INDRAWABLE, TRUE); IWineD3DSurface_SetContainer(object->frontBuffer, (IWineD3DBase *)object); } else { ERR("Failed to create the front buffer\n"); @@ -4841,12 +4842,10 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Clear(IWineD3DDevice *iface, DWORD Coun /* Dirtify the target surface for now. If the surface is locked regularly, and an up to date sysmem copy exists, * it is most likely more efficient to perform a clear on the sysmem copy too instead of downloading it */ + IWineD3DSurface_ModifyLocation(This->lastActiveRenderTarget, SFLAG_INDRAWABLE, TRUE); + /* TODO: Move the fbo logic into ModifyLocation() */ if(This->render_offscreen && wined3d_settings.offscreen_rendering_mode == ORM_FBO) { target->Flags |= SFLAG_INTEXTURE; - target->Flags &= ~SFLAG_INSYSMEM; - } else { - target->Flags |= SFLAG_INDRAWABLE; - target->Flags &= ~(SFLAG_INTEXTURE | SFLAG_INSYSMEM); } return WINED3D_OK; } @@ -5540,8 +5539,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface, LEAVE_GL(); - ((IWineD3DSurfaceImpl *)pDestinationSurface)->Flags &= ~SFLAG_INSYSMEM; - ((IWineD3DSurfaceImpl *)pDestinationSurface)->Flags |= SFLAG_INTEXTURE; + IWineD3DSurface_ModifyLocation(pDestinationSurface, SFLAG_INTEXTURE, TRUE); IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(0)); return WINED3D_OK; diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c index cca8c939ddd..ae61dbbb68c 100644 --- a/dlls/wined3d/drawprim.c +++ b/dlls/wined3d/drawprim.c @@ -1078,29 +1078,27 @@ void drawPrimitive(IWineD3DDevice *iface, blt_to_drawable(This, target); } + /* TODO: Move fbo logic to ModifyLocation */ + IWineD3DSurface_ModifyLocation((IWineD3DSurface *) target, SFLAG_INDRAWABLE, TRUE); if(swapchain) { /* Onscreen target. Invalidate system memory copy and texture copy */ - target->Flags &= ~(SFLAG_INSYSMEM | SFLAG_INTEXTURE); - target->Flags |= SFLAG_INDRAWABLE; IWineD3DSwapChain_Release(swapchain); } else if(wined3d_settings.offscreen_rendering_mode != ORM_FBO) { /* Non-FBO target: Invalidate system copy, texture copy and dirtify the container */ + /* TODO: Move container dirtification to ModifyLocation */ IWineD3DSurface_GetContainer((IWineD3DSurface *) target, &IID_IWineD3DBaseTexture, (void **)&texture); if(texture) { IWineD3DBaseTexture_SetDirty(texture, TRUE); IWineD3DTexture_Release(texture); } - - target->Flags &= ~(SFLAG_INSYSMEM | SFLAG_INTEXTURE); - target->Flags |= SFLAG_INDRAWABLE; } else { - /* FBO offscreen target. Invalidate system memory copy */ - target->Flags &= ~SFLAG_INSYSMEM; + /* FBO offscreen target. Texture == Drawable */ + target->Flags |= SFLAG_INTEXTURE; } } else { /* Must be an fbo render target */ - target->Flags &= ~SFLAG_INSYSMEM; + IWineD3DSurface_ModifyLocation((IWineD3DSurface *) target, SFLAG_INDRAWABLE, TRUE); target->Flags |= SFLAG_INTEXTURE; } } diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index f729b3928a5..5fc00a69bdf 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -451,7 +451,7 @@ void WINAPI IWineD3DSurfaceImpl_SetGlTextureDesc(IWineD3DSurface *iface, UINT te IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; TRACE("(%p) : setting textureName %u, target %i\n", This, textureName, target); if (This->glDescription.textureName == 0 && textureName != 0) { - This->Flags &= ~SFLAG_INTEXTURE; + IWineD3DSurface_ModifyLocation(iface, SFLAG_INTEXTURE, FALSE); IWineD3DSurface_AddDirtyRect(iface, NULL); } This->glDescription.textureName = textureName; @@ -650,7 +650,9 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED */ if(!(This->resource.allocatedMemory || This->Flags & SFLAG_PBO)) { This->resource.allocatedMemory = HeapAlloc(GetProcessHeap() ,0 , This->resource.size + 4); - This->Flags &= ~SFLAG_INSYSMEM; /* This is the marker that surface data has to be downloaded */ + if(This->Flags & SFLAG_INSYSMEM) { + ERR("Surface without memory or pbo has SFLAG_INSYSMEM set!\n"); + } } /* Create a PBO for dynamically locked surfaces but don't do it for converted or non-pow2 surfaces. @@ -2267,7 +2269,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface, BO if (!(This->Flags & SFLAG_DONOTFREE)) { HeapFree(GetProcessHeap(), 0, This->resource.allocatedMemory); This->resource.allocatedMemory = NULL; - This->Flags &= ~SFLAG_INSYSMEM; + IWineD3DSurface_ModifyLocation(iface, SFLAG_INSYSMEM, FALSE); } return WINED3D_OK; @@ -2427,7 +2429,7 @@ extern HRESULT WINAPI IWineD3DSurfaceImpl_AddDirtyRect(IWineD3DSurface *iface, C if (!(This->Flags & SFLAG_INSYSMEM) && (This->Flags & SFLAG_INTEXTURE)) surface_download_data(This); - This->Flags &= ~(SFLAG_INTEXTURE | SFLAG_INDRAWABLE); + IWineD3DSurface_ModifyLocation(iface, SFLAG_INSYSMEM, TRUE); if (NULL != pDirtyRect) { This->dirtyRect.left = min(This->dirtyRect.left, pDirtyRect->left); This->dirtyRect.top = min(This->dirtyRect.top, pDirtyRect->top); @@ -2503,7 +2505,7 @@ HRESULT WINAPI IWineD3DSurfaceImpl_SetMem(IWineD3DSurface *iface, void *Mem) { This->Flags |= SFLAG_USERPTR | SFLAG_INSYSMEM; /* Now the surface memory is most up do date. Invalidate drawable and texture */ - This->Flags &= ~(SFLAG_INDRAWABLE | SFLAG_INTEXTURE); + IWineD3DSurface_ModifyLocation(iface, SFLAG_INSYSMEM, TRUE); /* For client textures opengl has to be notified */ if(This->Flags & SFLAG_CLIENT) { @@ -3087,7 +3089,7 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT * /* The texture is now most up to date - If the surface is a render target and has a drawable, this * path is never entered */ - This->Flags |= SFLAG_INTEXTURE; + IWineD3DSurface_ModifyLocation((IWineD3DSurface *) This, SFLAG_INTEXTURE, TRUE); return WINED3D_OK; } else if(Src) { @@ -3231,14 +3233,12 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT * LEAVE_GL(); /* TODO: If the surface is locked often, perform the Blt in software on the memory instead */ - This->Flags &= ~SFLAG_INSYSMEM; /* The surface is now in the drawable. On onscreen surfaces or without fbos the texture * is outdated now */ - if(dstSwapchain || wined3d_settings.offscreen_rendering_mode != ORM_FBO) { - This->Flags |= SFLAG_INDRAWABLE; - This->Flags &= ~SFLAG_INTEXTURE; - } else { + IWineD3DSurface_ModifyLocation((IWineD3DSurface *) This, SFLAG_INDRAWABLE, TRUE); + /* TODO: This should be moved to ModifyLocation() */ + if(!(dstSwapchain || wined3d_settings.offscreen_rendering_mode != ORM_FBO)) { This->Flags |= SFLAG_INTEXTURE; } @@ -3533,6 +3533,22 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_PrivateSetup(IWineD3DSurface *iface) { return WINED3D_OK; } +static void WINAPI IWineD3DSurfaceImpl_ModifyLocation(IWineD3DSurface *iface, DWORD flag, BOOL persistent) { + IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface; + + TRACE("(%p)->(%s, %s)\n", iface, + flag == SFLAG_INSYSMEM ? "SFLAG_INSYSMEM" : flag == SFLAG_INDRAWABLE ? "SFLAG_INDRAWABLE" : "SFLAG_INTEXTURE", + persistent ? "TRUE" : "FALSE"); + + /* TODO: For offscreen textures with fbo offscreen rendering the drawable is the same as the texture.*/ + if(persistent) { + This->Flags &= ~SFLAG_LOCATIONS; + This->Flags |= flag; + } else { + This->Flags &= ~flag; + } +} + const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl = { /* IUnknown */ @@ -3584,5 +3600,6 @@ const IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl = IWineD3DSurfaceImpl_GetGlDesc, IWineD3DSurfaceImpl_GetData, IWineD3DSurfaceImpl_SetFormat, - IWineD3DSurfaceImpl_PrivateSetup + IWineD3DSurfaceImpl_PrivateSetup, + IWineD3DSurfaceImpl_ModifyLocation }; diff --git a/dlls/wined3d/surface_base.c b/dlls/wined3d/surface_base.c index 58c4013414c..598c9325982 100644 --- a/dlls/wined3d/surface_base.c +++ b/dlls/wined3d/surface_base.c @@ -301,7 +301,7 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_RealizePalette(IWineD3DSurface *iface) { FIXME("Palette changed with surface that does not have an up to date system memory copy\n"); } TRACE("Dirtifying surface\n"); - This->Flags &= ~(SFLAG_INTEXTURE | SFLAG_INDRAWABLE); + IWineD3DSurface_ModifyLocation(iface, SFLAG_INSYSMEM, TRUE); } if(This->Flags & SFLAG_DIBSECTION) { diff --git a/dlls/wined3d/surface_gdi.c b/dlls/wined3d/surface_gdi.c index c198dbb29d5..19c7ea31a6a 100644 --- a/dlls/wined3d/surface_gdi.c +++ b/dlls/wined3d/surface_gdi.c @@ -783,6 +783,19 @@ HRESULT WINAPI IWineGDISurfaceImpl_SetMem(IWineD3DSurface *iface, void *Mem) { return WINED3D_OK; } +/*************************** + * + ***************************/ +static void WINAPI IWineGDISurfaceImpl_ModifyLocation(IWineD3DSurface *iface, DWORD flag, BOOL persistent) { + TRACE("(%p)->(%s, %s)\n", iface, + flag == SFLAG_INSYSMEM ? "SFLAG_INSYSMEM" : flag == SFLAG_INDRAWABLE ? "SFLAG_INDRAWABLE" : "SFLAG_INTEXTURE", + persistent ? "TRUE" : "FALSE"); + /* GDI surfaces can be in system memory only */ + if(flag != SFLAG_INSYSMEM) { + ERR("GDI Surface requested in gl %s memory\n", flag == SFLAG_INDRAWABLE ? "drawable" : "texture"); + } +} + /* FIXME: This vtable should not use any IWineD3DSurface* implementation functions, * only IWineD3DBaseSurface and IWineGDISurface ones. */ @@ -837,5 +850,6 @@ const IWineD3DSurfaceVtbl IWineGDISurface_Vtbl = IWineGDISurfaceImpl_GetGlDesc, IWineD3DSurfaceImpl_GetData, IWineD3DBaseSurfaceImpl_SetFormat, - IWineGDISurfaceImpl_PrivateSetup + IWineGDISurfaceImpl_PrivateSetup, + IWineGDISurfaceImpl_ModifyLocation }; diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index e302f56fa91..330f928e945 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -355,8 +355,8 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO if(backuptodate) front->Flags |= SFLAG_INSYSMEM; else front->Flags &= ~SFLAG_INSYSMEM; } else { - back->Flags &= ~SFLAG_INSYSMEM; - front->Flags &= ~SFLAG_INSYSMEM; + IWineD3DSurface_ModifyLocation((IWineD3DSurface *) front, SFLAG_INDRAWABLE, TRUE); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *) back, SFLAG_INDRAWABLE, TRUE); } } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 2d73e7f0609..bee917d06a0 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1209,6 +1209,9 @@ const void *WINAPI IWineD3DSurfaceImpl_GetData(IWineD3DSurface *iface); SFLAG_PBO | \ SFLAG_CLIENT) +#define SFLAG_LOCATIONS (SFLAG_INSYSMEM | \ + SFLAG_INTEXTURE | \ + SFLAG_INDRAWABLE) BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]); typedef enum { diff --git a/include/wine/wined3d_interface.h b/include/wine/wined3d_interface.h index 895ba667d52..92032009657 100644 --- a/include/wine/wined3d_interface.h +++ b/include/wine/wined3d_interface.h @@ -1141,6 +1141,7 @@ DECLARE_INTERFACE_(IWineD3DSurface,IWineD3DResource) STDMETHOD_(CONST void *, GetData)(THIS) PURE; STDMETHOD(SetFormat)(THIS_ WINED3DFORMAT format) PURE; STDMETHOD(PrivateSetup)(THIS) PURE; + STDMETHOD_(void,ModifyLocation)(THIS_ DWORD flag, BOOL persistent); }; #undef INTERFACE @@ -1196,6 +1197,7 @@ DECLARE_INTERFACE_(IWineD3DSurface,IWineD3DResource) #define IWineD3DSurface_GetData(p) (p)->lpVtbl->GetData(p) #define IWineD3DSurface_SetFormat(p,a) (p)->lpVtbl->SetFormat(p,a) #define IWineD3DSurface_PrivateSetup(p) (p)->lpVtbl->PrivateSetup(p) +#define IWineD3DSurface_ModifyLocation(p,a,b) (p)->lpVtbl->ModifyLocation(p,a,b) #endif /*****************************************************************************