From 4941a3aff2825137918c590d67c4e18beb51ccaa Mon Sep 17 00:00:00 2001 From: Lionel Ulmer Date: Wed, 27 Nov 2002 21:38:28 +0000 Subject: [PATCH] - fix texture snooping (plus adds snoop for 1555 format) - add texture memory usage tracking --- dlls/ddraw/d3d_private.h | 1 + dlls/ddraw/d3dtexture.c | 55 +++++++++++++++++++++++++++++++++----- dlls/ddraw/ddraw/main.c | 32 ++++++++++++++++++++-- dlls/ddraw/ddraw_private.h | 13 ++++++++- dlls/ddraw/dsurface/main.c | 5 +++- 5 files changed, 95 insertions(+), 11 deletions(-) diff --git a/dlls/ddraw/d3d_private.h b/dlls/ddraw/d3d_private.h index 284b5f9700f..d4b103cca22 100644 --- a/dlls/ddraw/d3d_private.h +++ b/dlls/ddraw/d3d_private.h @@ -106,6 +106,7 @@ struct IDirect3DTextureImpl IDirect3DImpl *d3d; IDirect3DDeviceImpl *d3ddevice; IDirectDrawSurfaceImpl *surface; + BOOL loaded; }; /***************************************************************************** diff --git a/dlls/ddraw/d3dtexture.c b/dlls/ddraw/d3dtexture.c index c14ba0c2235..2f4c2763b90 100644 --- a/dlls/ddraw/d3dtexture.c +++ b/dlls/ddraw/d3dtexture.c @@ -47,12 +47,12 @@ WINE_DEFAULT_DEBUG_CHANNEL(ddraw); char buf[32]; \ int x, y; \ \ - sprintf(buf, "%ld.pnm", dtpriv->tex_name); \ + sprintf(buf, "%ld.pnm", glThis->tex_name); \ f = fopen(buf, "wb"); \ fprintf(f, "P6\n%ld %ld\n255\n", src_d->dwWidth, src_d->dwHeight); \ for (y = 0; y < src_d->dwHeight; y++) { \ for (x = 0; x < src_d->dwWidth; x++) { \ - unsigned char c = ((unsigned char *) src_d->y.lpSurface)[y * src_d->dwWidth + x]; \ + unsigned char c = ((unsigned char *) src_d->lpSurface)[y * src_d->dwWidth + x]; \ fputc(table[c][0], f); \ fputc(table[c][1], f); \ fputc(table[c][2], f); \ @@ -67,12 +67,12 @@ WINE_DEFAULT_DEBUG_CHANNEL(ddraw); char buf[32]; \ int x, y; \ \ - sprintf(buf, "%ld.pnm", dtpriv->tex_name); \ + sprintf(buf, "%ld.pnm", glThis->tex_name); \ f = fopen(buf, "wb"); \ fprintf(f, "P6\n%ld %ld\n255\n", src_d->dwWidth, src_d->dwHeight); \ for (y = 0; y < src_d->dwHeight; y++) { \ for (x = 0; x < src_d->dwWidth; x++) { \ - unsigned short c = ((unsigned short *) src_d->y.lpSurface)[y * src_d->dwWidth + x]; \ + unsigned short c = ((unsigned short *) src_d->lpSurface)[y * src_d->dwWidth + x]; \ fputc((c & 0xF800) >> 8, f); \ fputc((c & 0x07E0) >> 3, f); \ fputc((c & 0x001F) << 3, f); \ @@ -87,12 +87,12 @@ WINE_DEFAULT_DEBUG_CHANNEL(ddraw); char buf[32]; \ int x, y; \ \ - sprintf(buf, "%ld.pnm", dtpriv->tex_name); \ + sprintf(buf, "%ld.pnm", glThis->tex_name); \ f = fopen(buf, "wb"); \ fprintf(f, "P6\n%ld %ld\n255\n", src_d->dwWidth, src_d->dwHeight); \ for (y = 0; y < src_d->dwHeight; y++) { \ for (x = 0; x < src_d->dwWidth; x++) { \ - unsigned short c = ((unsigned short *) src_d->y.lpSurface)[y * src_d->dwWidth + x]; \ + unsigned short c = ((unsigned short *) src_d->lpSurface)[y * src_d->dwWidth + x]; \ fputc((c & 0xF800) >> 8, f); \ fputc((c & 0x07C0) >> 3, f); \ fputc((c & 0x003E) << 2, f); \ @@ -100,10 +100,31 @@ WINE_DEFAULT_DEBUG_CHANNEL(ddraw); } \ fclose(f); \ } + +#define SNOOP_1555() \ + { \ + FILE *f; \ + char buf[32]; \ + int x, y; \ + \ + sprintf(buf, "%ld.pnm", glThis->tex_name); \ + f = fopen(buf, "wb"); \ + fprintf(f, "P6\n%ld %ld\n255\n", src_d->dwWidth, src_d->dwHeight); \ + for (y = 0; y < src_d->dwHeight; y++) { \ + for (x = 0; x < src_d->dwWidth; x++) { \ + unsigned short c = ((unsigned short *) src_d->lpSurface)[y * src_d->dwWidth + x]; \ + fputc((c & 0x7C00) >> 7, f); \ + fputc((c & 0x03E0) >> 2, f); \ + fputc((c & 0x001F) << 3, f); \ + } \ + } \ + fclose(f); \ + } #else #define SNOOP_PALETTED() #define SNOOP_5650() #define SNOOP_5551() +#define SNOOP_1555() #endif /******************************************************************************* @@ -304,6 +325,8 @@ GL_IDirect3DTextureImpl_2_1T_Release(LPDIRECT3DTEXTURE2 iface) FIXME("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref); if (!--(This->ref)) { + DWORD mem_used; + /* Release surface */ IDirectDrawSurface3_Release(ICOM_INTERFACE(This->surface, IDirectDrawSurface3)); @@ -316,7 +339,13 @@ GL_IDirect3DTextureImpl_2_1T_Release(LPDIRECT3DTEXTURE2 iface) if (This->d3ddevice != NULL) if (This->d3ddevice->current_texture == This) This->d3ddevice->current_texture = NULL; - + + if (This->loaded) { + mem_used = This->surface->surface_desc.dwHeight * + This->surface->surface_desc.dwHeight * + This->surface->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount; + This->surface->ddraw_owner->free_memory(This->surface->ddraw_owner, mem_used); + } HeapFree(GetProcessHeap(),0,This); return 0; } @@ -368,6 +397,7 @@ GL_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface, ICOM_THIS_FROM(IDirect3DTextureImpl, IDirect3DTexture2, iface); IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This; IDirect3DTextureImpl *lpD3DTextureImpl = ICOM_OBJECT(IDirect3DTextureImpl, IDirect3DTexture2, lpD3DTexture2); + DWORD mem_used; DDSURFACEDESC *src_d, *dst_d; static void (*ptr_ColorTableEXT) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table) = NULL; @@ -376,6 +406,16 @@ GL_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface, #endif TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DTexture2); + + mem_used = This->surface->surface_desc.dwHeight * + This->surface->surface_desc.dwHeight * + This->surface->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount; + if (This->surface->ddraw_owner->allocate_memory(This->surface->ddraw_owner, mem_used) < 0) { + TRACE(" out of virtual memory... Warning application.\n"); + return D3DERR_TEXTURE_LOAD_FAILED; + } + This->loaded = TRUE; + TRACE("Copied surface %p to surface %p\n", lpD3DTextureImpl->surface, This->surface); if ( This->surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD ) @@ -559,6 +599,7 @@ GL_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface, ((*src & 0x7FFF) << 1)); src++; } + SNOOP_1555(); glTexImage2D(GL_TEXTURE_2D, 0, diff --git a/dlls/ddraw/ddraw/main.c b/dlls/ddraw/ddraw/main.c index 4a707f07926..89a2e7428fd 100644 --- a/dlls/ddraw/ddraw/main.c +++ b/dlls/ddraw/ddraw/main.c @@ -58,6 +58,10 @@ static void Main_DirectDraw_DeleteClippers(IDirectDrawImpl* This); static void Main_DirectDraw_DeletePalettes(IDirectDrawImpl* This); static void LosePrimarySurface(IDirectDrawImpl* This); +static INT32 allocate_memory(IDirectDrawImpl *This, DWORD mem) ; +static void free_memory(IDirectDrawImpl *This, DWORD mem) ; + + static const char ddProp[] = "WINE_DDRAW_Property"; /* Not called from the vtable. */ @@ -84,6 +88,12 @@ HRESULT Main_DirectDraw_Construct(IDirectDrawImpl *This, BOOL ex) ICOM_INIT_INTERFACE(This, IDirectDraw4, DDRAW_IDirectDraw4_VTable); /* There is no generic implementation of IDD7 */ + /* This is for the moment here... */ + This->free_memory = free_memory; + This->allocate_memory = allocate_memory; + This->total_vidmem = 16 * 1024 * 1024; + This->available_vidmem = This->total_vidmem; + return DD_OK; } @@ -177,6 +187,9 @@ HRESULT WINAPI Main_DirectDraw_QueryInterface( *obj = ICOM_INTERFACE(d3d_impl, IDirect3D); + /* And store the D3D object */ + This->d3d = d3d_impl; + TRACE(" returning Direct3D interface at %p.\n", *obj); } else if ( IsEqualGUID( &IID_IDirect3D2 , refiid ) ) @@ -1099,6 +1112,18 @@ Main_DirectDraw_GetDisplayMode(LPDIRECTDRAW7 iface, LPDDSURFACEDESC2 pDDSD) return DD_OK; } +static INT32 allocate_memory(IDirectDrawImpl *This, DWORD mem) +{ + if (mem > This->available_vidmem) return -1; + This->available_vidmem -= mem; + return This->available_vidmem; +} + +static void free_memory(IDirectDrawImpl *This, DWORD mem) +{ + This->available_vidmem += mem; +} + HRESULT WINAPI Main_DirectDraw_GetAvailableVidMem(LPDIRECTDRAW7 iface, LPDDSCAPS2 ddscaps, LPDWORD total, LPDWORD free) @@ -1107,8 +1132,11 @@ Main_DirectDraw_GetAvailableVidMem(LPDIRECTDRAW7 iface, LPDDSCAPS2 ddscaps, TRACE("(%p)->(%p,%p,%p)\n", This,ddscaps,total,free); /* We have 16 MB videomemory */ - if (total) *total= 16*1024*1024; - if (free) *free = 16*1024*1024; + if (total) *total= This->total_vidmem; + if (free) *free = This->available_vidmem; + + TRACE(" returning (total) %ld / (free) %ld\n", *total, *free); + return DD_OK; } diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index b8ce3d7ba6d..05cdbcf9c85 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -151,6 +151,14 @@ struct IDirectDrawImpl pixel_convert_func pixel_convert; palette_convert_func palette_convert; + /* Use to fool some too strict games */ + INT32 (*allocate_memory)(IDirectDrawImpl *This, DWORD mem); + void (*free_memory)(IDirectDrawImpl *This, DWORD mem); + DWORD total_vidmem, available_vidmem; + + /* This is to get the D3D object associated to this DDraw object */ + struct IDirect3DImpl *d3d; + /* This is for the fake mainWindow */ ATOM winclass; PAINTSTRUCT ps; @@ -239,6 +247,7 @@ struct IDirectDrawSurfaceImpl HDC hDC; RECT lastlockrect; + DWORD lastlocktype; BOOL dc_in_use; HRESULT (*duplicate_surface)(IDirectDrawSurfaceImpl* src, @@ -276,12 +285,14 @@ struct IDirectDrawSurfaceImpl /* Everything below here is dodgy. */ /* For Direct3D use */ - LPVOID aux_ctx, aux_data; + LPVOID aux_ctx, aux_data; void (*aux_release)(LPVOID ctx, LPVOID data); BOOL (*aux_flip)(LPVOID ctx, LPVOID data); void (*aux_unlock)(LPVOID ctx, LPVOID data, LPRECT lpRect); struct IDirect3DTextureImpl *texture; HRESULT (WINAPI *SetColorKey_cb)(struct IDirect3DTextureImpl *texture, DWORD dwFlags, LPDDCOLORKEY ckey ) ; + /* This is to get the D3DDevice object associated to this surface */ + struct IDirect3DDeviceImpl *d3ddevice; }; /***************************************************************************** diff --git a/dlls/ddraw/dsurface/main.c b/dlls/ddraw/dsurface/main.c index 0efb4302ce0..e8a2568640a 100644 --- a/dlls/ddraw/dsurface/main.c +++ b/dlls/ddraw/dsurface/main.c @@ -175,7 +175,7 @@ Main_DirectDrawSurface_QueryInterface(LPDIRECTDRAWSURFACE7 iface, REFIID riid, IDirect3DDeviceImpl *d3ddevimpl; HRESULT ret_value; - ret_value = d3ddevice_create(&d3ddevimpl, NULL, This); + ret_value = d3ddevice_create(&d3ddevimpl, This->ddraw_owner->d3d, This); if (FAILED(ret_value)) return ret_value; *ppObj = ICOM_INTERFACE(d3ddevimpl, IDirect3DDevice); @@ -991,6 +991,9 @@ Main_DirectDrawSurface_Lock(LPDIRECTDRAWSURFACE7 iface, LPRECT prect, TRACE("locked surface returning description : \n"); if (TRACE_ON(ddraw)) DDRAW_dump_surface_desc(pDDSD); + + /* Used to optimize the D3D Device locking */ + This->lastlocktype = flags & (DDLOCK_READONLY|DDLOCK_WRITEONLY); /* If asked only for a part, change the surface pointer. * (Not documented.) */