2004-10-14 02:32:04 +02:00
/*
* IWineD3DResource Implementation
*
* Copyright 2002 - 2004 Jason Edmeades
* Copyright 2003 - 2004 Raphael Junqueira
* Copyright 2004 Christian Costa
2005-07-13 16:15:54 +02:00
* Copyright 2005 Oliver Stieber
2004-10-14 02:32:04 +02:00
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2.1 of the License , or ( at your option ) any later version .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library ; if not , write to the Free Software
2006-05-18 14:49:52 +02:00
* Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 , USA
2004-10-14 02:32:04 +02:00
*/
# include "config.h"
# include "wined3d_private.h"
WINE_DEFAULT_DEBUG_CHANNEL ( d3d ) ;
2004-11-28 16:04:41 +01:00
# define GLINFO_LOCATION ((IWineD3DImpl *)(((IWineD3DDeviceImpl *)This->resource.wineD3DDevice)->wineD3D))->gl_info
2004-10-14 02:32:04 +02:00
2005-07-13 16:15:54 +02:00
/* IWineD3DResource IUnknown parts follow: */
2004-10-14 02:32:04 +02:00
HRESULT WINAPI IWineD3DResourceImpl_QueryInterface ( IWineD3DResource * iface , REFIID riid , LPVOID * ppobj )
{
IWineD3DResourceImpl * This = ( IWineD3DResourceImpl * ) iface ;
2005-03-02 14:44:58 +01:00
TRACE ( " (%p)->(%s,%p) \n " , This , debugstr_guid ( riid ) , ppobj ) ;
if ( IsEqualGUID ( riid , & IID_IUnknown )
2006-02-06 11:32:41 +01:00
| | IsEqualGUID ( riid , & IID_IWineD3DBase )
2005-03-02 14:44:58 +01:00
| | IsEqualGUID ( riid , & IID_IWineD3DResource ) ) {
IUnknown_AddRef ( iface ) ;
* ppobj = This ;
2006-04-25 23:59:12 +02:00
return S_OK ;
2005-03-02 14:44:58 +01:00
}
2006-04-25 23:59:12 +02:00
* ppobj = NULL ;
2004-10-14 02:32:04 +02:00
return E_NOINTERFACE ;
}
ULONG WINAPI IWineD3DResourceImpl_AddRef ( IWineD3DResource * iface ) {
IWineD3DResourceImpl * This = ( IWineD3DResourceImpl * ) iface ;
2005-01-19 17:59:01 +01:00
ULONG ref = InterlockedIncrement ( & This - > resource . ref ) ;
2006-10-01 05:20:10 +02:00
TRACE ( " (%p) : AddRef increasing from %d \n " , This , ref - 1 ) ;
2005-01-19 17:59:01 +01:00
return ref ;
2004-10-14 02:32:04 +02:00
}
ULONG WINAPI IWineD3DResourceImpl_Release ( IWineD3DResource * iface ) {
IWineD3DResourceImpl * This = ( IWineD3DResourceImpl * ) iface ;
2005-01-19 17:59:01 +01:00
ULONG ref = InterlockedDecrement ( & This - > resource . ref ) ;
2006-10-01 05:20:10 +02:00
TRACE ( " (%p) : Releasing from %d \n " , This , ref + 1 ) ;
2004-10-14 02:32:04 +02:00
if ( ref = = 0 ) {
2005-03-29 21:01:00 +02:00
IWineD3DResourceImpl_CleanUp ( iface ) ;
2004-10-14 02:32:04 +02:00
HeapFree ( GetProcessHeap ( ) , 0 , This ) ;
}
return ref ;
}
2005-03-29 21:01:00 +02:00
/* class static (not in vtable) */
void IWineD3DResourceImpl_CleanUp ( IWineD3DResource * iface ) {
IWineD3DResourceImpl * This = ( IWineD3DResourceImpl * ) iface ;
2007-05-11 00:09:35 +02:00
struct list * e1 , * e2 ;
PrivateData * data ;
HRESULT hr ;
2005-07-13 13:34:55 +02:00
TRACE ( " (%p) Cleaning up resource \n " , This ) ;
2006-03-28 14:20:47 +02:00
if ( This - > resource . pool = = WINED3DPOOL_DEFAULT ) {
2005-07-13 13:34:55 +02:00
TRACE ( " Decrementing device memory pool by %u \n " , This - > resource . size ) ;
2007-09-23 00:46:21 +02:00
WineD3DAdapterChangeGLRam ( This - > resource . wineD3DDevice , - This - > resource . size ) ;
2005-07-13 13:34:55 +02:00
}
2005-03-29 21:01:00 +02:00
2007-05-11 00:09:35 +02:00
LIST_FOR_EACH_SAFE ( e1 , e2 , & This - > resource . privateData ) {
data = LIST_ENTRY ( e1 , PrivateData , entry ) ;
hr = IWineD3DResourceImpl_FreePrivateData ( iface , & data - > tag ) ;
if ( hr ! = WINED3D_OK ) {
ERR ( " Failed to free private data when destroying resource %p, hr = %08x \n " , This , hr ) ;
}
}
2007-10-22 13:02:03 +02:00
HeapFree ( GetProcessHeap ( ) , 0 , This - > resource . heapMemory ) ;
2005-03-29 21:01:00 +02:00
This - > resource . allocatedMemory = 0 ;
2007-10-22 13:02:03 +02:00
This - > resource . heapMemory = 0 ;
2005-07-26 12:34:15 +02:00
if ( This - > resource . wineD3DDevice ! = NULL ) {
IWineD3DDevice_ResourceReleased ( ( IWineD3DDevice * ) This - > resource . wineD3DDevice , iface ) ;
} /* NOTE: this is not really an error for systemmem resoruces */
return ;
2005-03-29 21:01:00 +02:00
}
2005-07-13 16:15:54 +02:00
/* IWineD3DResource Interface follow: */
2004-10-14 02:32:04 +02:00
HRESULT WINAPI IWineD3DResourceImpl_GetDevice ( IWineD3DResource * iface , IWineD3DDevice * * ppDevice ) {
IWineD3DResourceImpl * This = ( IWineD3DResourceImpl * ) iface ;
TRACE ( " (%p) : returning %p \n " , This , This - > resource . wineD3DDevice ) ;
* ppDevice = ( IWineD3DDevice * ) This - > resource . wineD3DDevice ;
IWineD3DDevice_AddRef ( * ppDevice ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-10-14 02:32:04 +02:00
}
2007-05-07 20:46:24 +02:00
static PrivateData * IWineD3DResourceImpl_FindPrivateData ( IWineD3DResourceImpl * This ,
2005-07-15 11:54:57 +02:00
REFGUID tag )
{
2007-05-07 20:46:24 +02:00
PrivateData * data ;
struct list * entry ;
TRACE ( " Searching for private data %s \n " , debugstr_guid ( tag ) ) ;
LIST_FOR_EACH ( entry , & This - > resource . privateData )
2005-07-15 11:54:57 +02:00
{
2007-05-07 20:46:24 +02:00
data = LIST_ENTRY ( entry , PrivateData , entry ) ;
if ( IsEqualGUID ( & data - > tag , tag ) ) {
TRACE ( " Found %p \n " , data ) ;
return data ;
}
2005-07-15 11:54:57 +02:00
}
2007-05-07 20:46:24 +02:00
TRACE ( " Not found \n " ) ;
return NULL ;
2005-07-15 11:54:57 +02:00
}
2004-10-14 02:32:04 +02:00
HRESULT WINAPI IWineD3DResourceImpl_SetPrivateData ( IWineD3DResource * iface , REFGUID refguid , CONST void * pData , DWORD SizeOfData , DWORD Flags ) {
IWineD3DResourceImpl * This = ( IWineD3DResourceImpl * ) iface ;
2007-05-07 20:46:24 +02:00
PrivateData * data ;
2005-07-15 11:54:57 +02:00
2007-05-07 20:46:24 +02:00
TRACE ( " (%p) : %s %p %d %d \n " , This , debugstr_guid ( refguid ) , pData , SizeOfData , Flags ) ;
2007-05-11 00:09:35 +02:00
IWineD3DResourceImpl_FreePrivateData ( iface , refguid ) ;
2005-07-15 11:54:57 +02:00
2007-05-11 00:09:35 +02:00
data = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( * data ) ) ;
if ( NULL = = data ) return E_OUTOFMEMORY ;
data - > tag = * refguid ;
data - > flags = Flags ;
2005-07-15 11:54:57 +02:00
#if 0
( * data ) - > uniquenessValue = This - > uniquenessValue ;
# endif
2007-05-11 00:09:35 +02:00
if ( Flags & WINED3DSPD_IUNKNOWN ) {
if ( SizeOfData ! = sizeof ( IUnknown * ) ) {
WARN ( " IUnknown data with size %d, returning WINED3DERR_INVALIDCALL \n " , SizeOfData ) ;
2007-10-08 21:52:17 +02:00
HeapFree ( GetProcessHeap ( ) , 0 , data ) ;
2007-05-11 00:09:35 +02:00
return WINED3DERR_INVALIDCALL ;
2005-07-15 11:54:57 +02:00
}
2007-05-11 00:09:35 +02:00
data - > ptr . object = ( LPUNKNOWN ) pData ;
data - > size = sizeof ( LPUNKNOWN ) ;
IUnknown_AddRef ( data - > ptr . object ) ;
}
else
{
data - > ptr . data = HeapAlloc ( GetProcessHeap ( ) , 0 , SizeOfData ) ;
if ( NULL = = data - > ptr . data ) {
HeapFree ( GetProcessHeap ( ) , 0 , data ) ;
return E_OUTOFMEMORY ;
2005-07-15 11:54:57 +02:00
}
2007-05-11 00:09:35 +02:00
data - > size = SizeOfData ;
memcpy ( data - > ptr . data , pData , SizeOfData ) ;
2005-07-15 11:54:57 +02:00
}
2007-05-11 00:09:35 +02:00
list_add_tail ( & This - > resource . privateData , & data - > entry ) ;
2005-07-15 11:54:57 +02:00
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-10-14 02:32:04 +02:00
}
2005-07-15 11:54:57 +02:00
2004-10-14 02:32:04 +02:00
HRESULT WINAPI IWineD3DResourceImpl_GetPrivateData ( IWineD3DResource * iface , REFGUID refguid , void * pData , DWORD * pSizeOfData ) {
IWineD3DResourceImpl * This = ( IWineD3DResourceImpl * ) iface ;
2007-05-07 20:46:24 +02:00
PrivateData * data ;
2005-07-15 11:54:57 +02:00
TRACE ( " (%p) : %p %p %p \n " , This , refguid , pData , pSizeOfData ) ;
data = IWineD3DResourceImpl_FindPrivateData ( This , refguid ) ;
2007-05-07 20:46:24 +02:00
if ( data = = NULL ) return WINED3DERR_NOTFOUND ;
2005-07-15 11:54:57 +02:00
#if 0 /* This may not be right. */
2007-02-15 13:32:00 +01:00
if ( ( ( * data ) - > flags & WINED3DSPD_VOLATILE )
2005-07-15 11:54:57 +02:00
& & ( * data ) - > uniquenessValue ! = This - > uniquenessValue )
return DDERR_EXPIRED ;
# endif
2007-05-07 20:46:24 +02:00
if ( * pSizeOfData < data - > size ) {
* pSizeOfData = data - > size ;
2006-04-07 12:51:12 +02:00
return WINED3DERR_MOREDATA ;
2005-07-15 11:54:57 +02:00
}
2007-05-07 20:46:24 +02:00
if ( data - > flags & WINED3DSPD_IUNKNOWN ) {
* ( LPUNKNOWN * ) pData = data - > ptr . object ;
2007-05-11 00:09:35 +02:00
if ( ( ( IWineD3DImpl * ) This - > resource . wineD3DDevice - > wineD3D ) - > dxVersion ! = 7 ) {
/* D3D8 and D3D9 addref the private data, DDraw does not. This can't be handled in
* ddraw because it doesn ' t know if the pointer returned is an IUnknown * or just a
* Blob
*/
IUnknown_AddRef ( data - > ptr . object ) ;
}
2005-07-15 11:54:57 +02:00
}
else {
2007-05-07 20:46:24 +02:00
memcpy ( pData , data - > ptr . data , data - > size ) ;
2005-07-15 11:54:57 +02:00
}
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-10-14 02:32:04 +02:00
}
HRESULT WINAPI IWineD3DResourceImpl_FreePrivateData ( IWineD3DResource * iface , REFGUID refguid ) {
IWineD3DResourceImpl * This = ( IWineD3DResourceImpl * ) iface ;
2007-05-07 20:46:24 +02:00
PrivateData * data ;
2005-07-15 11:54:57 +02:00
2007-05-07 20:46:24 +02:00
TRACE ( " (%p) : %s \n " , This , debugstr_guid ( refguid ) ) ;
2005-07-15 11:54:57 +02:00
data = IWineD3DResourceImpl_FindPrivateData ( This , refguid ) ;
2007-05-07 20:46:24 +02:00
if ( data = = NULL ) return WINED3DERR_NOTFOUND ;
2005-07-15 11:54:57 +02:00
2007-05-07 20:46:24 +02:00
if ( data - > flags & WINED3DSPD_IUNKNOWN )
2005-07-15 11:54:57 +02:00
{
2007-05-07 20:46:24 +02:00
if ( data - > ptr . object ! = NULL )
IUnknown_Release ( data - > ptr . object ) ;
2005-07-15 11:54:57 +02:00
} else {
2007-05-07 20:46:24 +02:00
HeapFree ( GetProcessHeap ( ) , 0 , data - > ptr . data ) ;
2005-07-15 11:54:57 +02:00
}
2007-05-07 20:46:24 +02:00
list_remove ( & data - > entry ) ;
2005-07-15 11:54:57 +02:00
2007-05-07 20:46:24 +02:00
HeapFree ( GetProcessHeap ( ) , 0 , data ) ;
2005-07-15 11:54:57 +02:00
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-10-14 02:32:04 +02:00
}
/* Priority support is not implemented yet */
DWORD WINAPI IWineD3DResourceImpl_SetPriority ( IWineD3DResource * iface , DWORD PriorityNew ) {
IWineD3DResourceImpl * This = ( IWineD3DResourceImpl * ) iface ;
FIXME ( " (%p) : stub \n " , This ) ;
return 0 ;
}
DWORD WINAPI IWineD3DResourceImpl_GetPriority ( IWineD3DResource * iface ) {
IWineD3DResourceImpl * This = ( IWineD3DResourceImpl * ) iface ;
FIXME ( " (%p) : stub \n " , This ) ;
return 0 ;
}
/* Preloading of resources is not supported yet */
void WINAPI IWineD3DResourceImpl_PreLoad ( IWineD3DResource * iface ) {
IWineD3DResourceImpl * This = ( IWineD3DResourceImpl * ) iface ;
FIXME ( " (%p) : stub \n " , This ) ;
}
2006-03-09 23:21:16 +01:00
WINED3DRESOURCETYPE WINAPI IWineD3DResourceImpl_GetType ( IWineD3DResource * iface ) {
2004-10-14 02:32:04 +02:00
IWineD3DResourceImpl * This = ( IWineD3DResourceImpl * ) iface ;
TRACE ( " (%p) : returning %d \n " , This , This - > resource . resourceType ) ;
return This - > resource . resourceType ;
}
2004-11-23 14:52:46 +01:00
HRESULT WINAPI IWineD3DResourceImpl_GetParent ( IWineD3DResource * iface , IUnknown * * pParent ) {
IWineD3DResourceImpl * This = ( IWineD3DResourceImpl * ) iface ;
IUnknown_AddRef ( This - > resource . parent ) ;
* pParent = This - > resource . parent ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-11-23 14:52:46 +01:00
}
2007-11-16 20:28:45 +01:00
void dumpResources ( struct list * list ) {
IWineD3DResourceImpl * resource ;
2006-04-10 19:39:53 +02:00
2007-11-16 20:28:45 +01:00
LIST_FOR_EACH_ENTRY ( resource , list , IWineD3DResourceImpl , resource . resource_list_entry ) {
FIXME ( " Leftover resource %p with type %d,%s \n " , resource , IWineD3DResource_GetType ( ( IWineD3DResource * ) resource ) , debug_d3dresourcetype ( IWineD3DResource_GetType ( ( IWineD3DResource * ) resource ) ) ) ;
2006-04-10 19:39:53 +02:00
}
}
2004-11-23 14:52:46 +01:00
2005-06-06 21:50:35 +02:00
static const IWineD3DResourceVtbl IWineD3DResource_Vtbl =
2004-10-14 02:32:04 +02:00
{
2005-07-13 16:15:54 +02:00
/* IUnknown */
2004-10-14 02:32:04 +02:00
IWineD3DResourceImpl_QueryInterface ,
IWineD3DResourceImpl_AddRef ,
IWineD3DResourceImpl_Release ,
2005-07-13 16:15:54 +02:00
/* IWineD3DResource */
2004-11-23 14:52:46 +01:00
IWineD3DResourceImpl_GetParent ,
2004-10-14 02:32:04 +02:00
IWineD3DResourceImpl_GetDevice ,
IWineD3DResourceImpl_SetPrivateData ,
IWineD3DResourceImpl_GetPrivateData ,
IWineD3DResourceImpl_FreePrivateData ,
IWineD3DResourceImpl_SetPriority ,
IWineD3DResourceImpl_GetPriority ,
IWineD3DResourceImpl_PreLoad ,
IWineD3DResourceImpl_GetType
} ;