wined3d: Begin centralizing surface location management.

This commit is contained in:
Stefan Dösinger 2007-10-09 22:17:59 +02:00 committed by Alexandre Julliard
parent ee32ac575b
commit dcff7dc213
9 changed files with 63 additions and 31 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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