Commit 6a032491 authored by Oliver Stieber's avatar Oliver Stieber Committed by Alexandre Julliard

Added basic memory management and tracking to wined3d.

parent a745ca01
......@@ -61,7 +61,11 @@ ULONG WINAPI IWineD3DResourceImpl_Release(IWineD3DResource *iface) {
/* class static (not in vtable) */
void IWineD3DResourceImpl_CleanUp(IWineD3DResource *iface){
IWineD3DResourceImpl *This = (IWineD3DResourceImpl *)iface;
TRACE("(%p) : allocatedMemory(%p)\n", This, This->resource.allocatedMemory);
TRACE("(%p) Cleaning up resource\n", This);
if (This->resource.pool == D3DPOOL_DEFAULT) {
TRACE("Decrementing device memory pool by %u\n", This->resource.size);
globalChangeGlRam(-This->resource.size);
}
HeapFree(GetProcessHeap(), 0, This->resource.allocatedMemory);
This->resource.allocatedMemory = 0;
......
......@@ -306,9 +306,62 @@ HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, D3DLOCKED_RE
TRACE("Locking non-power 2 texture\n");
}
if (0 == This->resource.usage) { /* classic surface */
if (0 == This->resource.usage || This->resource.usage & D3DUSAGE_DYNAMIC) {
/* classic surface TODO: non 2d surfaces?
Thease resources may be POOL_SYSTEMMEM, so they must not access the device */
TRACE("locking an ordinarary surface\n");
/* Check to see if memory has already been allocated fro the sufrace*/
if (NULL == This->resource.allocatedMemory) { /* TODO: check to see if an update has been performed on the surface (an update could just clobber allocatedMemory */
/* Non-systemmemory surfaces */
/*Surface has no memory currently allocate to it!*/
TRACE("(%p) Locking rect\n" , This);
This->resource.allocatedMemory = HeapAlloc(GetProcessHeap() ,0 , This->pow2Size);
/*Now I have to copy thing bits back*/
This->activeLock = TRUE; /* When this flag is set to true, laoding the surface again won't free THis->resource.allocatedMemory */
/* TODO: make activeLock a bit more intelegent, maybe implement a method to purge the texture memory. */
ENTER_GL();
/* Make sure that the texture is loaded */
IWineD3DSurface_PreLoad(iface); /* Make sure there is a texture to bind! */
TRACE("(%p) glGetTexImage level(%d), fmt(%d), typ(%d), mem(%p) \n" , This, This->glDescription.level, This->glDescription.glFormat, This->glDescription.glType, This->resource.allocatedMemory);
/* TODO: DXT2 and DXT4 formats */
if (This->resource.format == WINED3DFMT_DXT1 ||
This->resource.format == WINED3DFMT_DXT3 ||
This->resource.format == WINED3DFMT_DXT5) {
TRACE("Locking a compressed texture\n");
if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) { /* we can assume this as the texture would not have been created otherwise */
GL_EXTCALL(glGetCompressedTexImageARB)(This->glDescription.target,
This->glDescription.level,
This->resource.allocatedMemory);
} else {
FIXME("(%p) attempting to lock a compressed texture when texture compression isn't supported by opengl\n", This);
}
} else {
glGetTexImage(This->glDescription.target,
This->glDescription.level,
This->glDescription.glFormat,
This->glDescription.glType,
This->resource.allocatedMemory);
vcheckGLcall("glGetTexImage");
}
LEAVE_GL();
} else { /* Nothing to do */
TRACE("Memory %p already allocted for texture\n", This->resource.allocatedMemory);
}
/* Nothing to do ;) */
if (NULL == pRect) {
pLockedRect->pBits = This->resource.allocatedMemory;
} else{
if (This->resource.format == D3DFMT_DXT1) { /* DXT1 is half byte per pixel */
pLockedRect->pBits = This->resource.allocatedMemory + (pLockedRect->Pitch * pRect->top) + ((pRect->left * This->bytesPerPixel/2));
} else {
pLockedRect->pBits = This->resource.allocatedMemory + (pLockedRect->Pitch * pRect->top) + (pRect->left * This->bytesPerPixel);
}
}
} else if (D3DUSAGE_RENDERTARGET & This->resource.usage && !(Flags&D3DLOCK_DISCARD)) { /* render surfaces */
......@@ -330,6 +383,7 @@ HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, D3DLOCKED_RE
if (This->resource.allocatedMemory == NULL)
This->resource.allocatedMemory = HeapAlloc(GetProcessHeap() ,0 ,This->resource.size);
This->activeLock = TRUE; /*When this flag is set to true, loading the surface again won't free THis->resource.allocatedMemory*/
pLockedRect->pBits = This->resource.allocatedMemory;
glFlush();
......@@ -843,6 +897,12 @@ HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface) {
checkGLcall("glCommpressedTexTexImage2D");
LEAVE_GL();
if(This->activeLock == FALSE){
HeapFree(GetProcessHeap(), 0, This->resource.allocatedMemory);
This->resource.allocatedMemory = NULL;
}
} else {
FIXME("Using DXT1/3/5 without advertized support\n");
}
......@@ -940,6 +1000,11 @@ HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface) {
*/
}
#endif
if(This->activeLock == FALSE){
HeapFree(GetProcessHeap(),0,This->resource.allocatedMemory);
This->resource.allocatedMemory = NULL;
}
}
return D3D_OK;
......
......@@ -124,7 +124,7 @@ HRESULT WINAPI IWineD3DVertexBufferImpl_GetDesc(IWineD3DVertexBuffer *if
pDesc->Usage = This->resource.usage;
pDesc->Pool = This->resource.pool;
pDesc->Size = This->resource.size;
pDesc->FVF = This->FVF;
pDesc->FVF = This->fvf;
return D3D_OK;
}
......
......@@ -33,6 +33,22 @@ void (*wine_tsx11_unlock_ptr)(void) = NULL;
int vs_mode = VS_HW; /* Hardware by default */
int ps_mode = PS_NONE; /* Disabled by default */
WineD3DGlobalStatistics *wineD3DGlobalStatistics = NULL;
CRITICAL_SECTION resourceStoreCriticalSection;
long globalChangeGlRam(long glram){
/* FIXME: replace this function with object tracking */
int result;
EnterCriticalSection(&resourceStoreCriticalSection); /* this is overkill really, but I suppose it should be thread safe */
wineD3DGlobalStatistics->glsurfaceram += glram;
TRACE("Adjusted gl ram by %ld to %d\n", glram, wineD3DGlobalStatistics->glsurfaceram);
result = wineD3DGlobalStatistics->glsurfaceram;
LeaveCriticalSection(&resourceStoreCriticalSection);
return result;
}
IWineD3D* WINAPI WineDirect3DCreate(UINT SDKVersion, UINT dxVersion, IUnknown *parent) {
IWineD3DImpl* object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DImpl));
object->lpVtbl = &IWineD3D_Vtbl;
......@@ -40,6 +56,18 @@ IWineD3D* WINAPI WineDirect3DCreate(UINT SDKVersion, UINT dxVersion, IUnknown *p
object->ref = 1;
object->parent = parent;
/* TODO: Move this off to device and possibly x11drv */
/* Create a critical section for a dll global data store */
InitializeCriticalSectionAndSpinCount(&resourceStoreCriticalSection, 0x80000400);
/*Create a structure for storing global data in*/
if(wineD3DGlobalStatistics == NULL){
TRACE("Createing global statistics store\n");
wineD3DGlobalStatistics = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wineD3DGlobalStatistics));
}
TRACE("Created WineD3D object @ %p for d3d%d support\n", object, dxVersion);
return (IWineD3D *)object;
......
......@@ -215,6 +215,23 @@ do {
typedef struct IWineD3DStateBlockImpl IWineD3DStateBlockImpl;
typedef struct IWineD3DSurfaceImpl IWineD3DSurfaceImpl;
/* Tracking */
/* TODO: Move some of this to the device */
long globalChangeGlRam(long glram);
/* Memory and object tracking */
/*Structure for holding information on all direct3d objects
usefull for making sure tracking is ok and when release is called on a device!
and probably quite handy for debuggin and dumping states out
*/
typedef struct WineD3DGlobalStatistics {
int glsurfaceram; /* The aproximate amount of glTexture memory allocated for textures */
} WineD3DGlobalStatistics;
extern WineD3DGlobalStatistics* wineD3DGlobalStatistics;
/* Global variables */
extern const float identity[16];
......@@ -469,7 +486,7 @@ typedef struct IWineD3DVertexBufferImpl
IWineD3DResourceClass resource;
/* WineD3DVertexBuffer specifics */
DWORD FVF;
DWORD fvf;
} IWineD3DVertexBufferImpl;
......@@ -636,6 +653,7 @@ struct IWineD3DSurfaceImpl
BOOL lockable;
BOOL discard;
BOOL locked;
BOOL activeLock;
RECT lockedRect;
RECT dirtyRect;
......
......@@ -819,6 +819,7 @@ typedef enum _GL_SupportedExt {
USE_GL_FUNC(PGLFNCOMPRESSEDTEXIMAGE3DPROC, glCompressedTexImage3DARB); \
USE_GL_FUNC(PGLFNCOMPRESSEDTEXSUBIMAGE2DPROC, glCompressedTexSubImage2DARB); \
USE_GL_FUNC(PGLFNCOMPRESSEDTEXSUBIMAGE3DPROC, glCompressedTexSubImage3DARB); \
USE_GL_FUNC(PGLFNGETCOMPRESSEDTEXIMAGEPROC, glGetCompressedTexImageARB); \
/* GL_ARB_vertex_blend */ \
USE_GL_FUNC(PGLFNGLWEIGHTPOINTERARB, glWeightPointerARB); \
/* GL_ARB_vertex_buffer_object */ \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment