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 ;
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 ) ;
globalChangeGlRam ( - This - > resource . size ) ;
}
2005-03-29 21:01:00 +02:00
HeapFree ( GetProcessHeap ( ) , 0 , This - > resource . allocatedMemory ) ;
This - > resource . allocatedMemory = 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
}
2005-07-15 11:54:57 +02:00
static PrivateData * * IWineD3DResourceImpl_FindPrivateData ( IWineD3DResourceImpl * This ,
REFGUID tag )
{
PrivateData * * data ;
for ( data = & This - > resource . privateData ; * data ! = NULL ; data = & ( * data ) - > next )
{
if ( IsEqualGUID ( & ( * data ) - > tag , tag ) ) break ;
}
return data ;
}
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 ;
2005-07-15 11:54:57 +02:00
PrivateData * * data ;
2006-10-01 05:20:10 +02:00
TRACE ( " (%p) : %p %p %d %d \n " , This , refguid , pData , SizeOfData , Flags ) ;
2005-07-15 11:54:57 +02:00
data = IWineD3DResourceImpl_FindPrivateData ( This , refguid ) ;
if ( * data = = NULL )
{
* data = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( * * data ) ) ;
if ( NULL = = * data ) return E_OUTOFMEMORY ;
( * data ) - > tag = * refguid ;
( * data ) - > flags = Flags ;
#if 0
( * data ) - > uniquenessValue = This - > uniquenessValue ;
# endif
if ( Flags & D3DSPD_IUNKNOWN ) {
( * 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 ;
}
2006-04-12 00:09:13 +02:00
( * data ) - > size = SizeOfData ;
memcpy ( ( * data ) - > ptr . data , pData , SizeOfData ) ;
2005-07-15 11:54:57 +02:00
}
/* link it in */
( * data ) - > next = This - > resource . privateData ;
This - > resource . privateData = * data ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-07-15 11:54:57 +02:00
} else {
/* I don't actually know how windows handles this case. The only
* reason I don ' t just call FreePrivateData is because I want to
* guarantee SetPrivateData working when using LPUNKNOWN or data
* that is no larger than the old data . */
return E_FAIL ;
}
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 ;
2005-07-15 11:54:57 +02:00
PrivateData * * data ;
TRACE ( " (%p) : %p %p %p \n " , This , refguid , pData , pSizeOfData ) ;
data = IWineD3DResourceImpl_FindPrivateData ( This , refguid ) ;
2006-04-07 12:51:12 +02:00
if ( * data = = NULL ) return WINED3DERR_NOTFOUND ;
2005-07-15 11:54:57 +02:00
#if 0 /* This may not be right. */
if ( ( ( * data ) - > flags & D3DSPD_VOLATILE )
& & ( * data ) - > uniquenessValue ! = This - > uniquenessValue )
return DDERR_EXPIRED ;
# endif
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
}
if ( ( * data ) - > flags & D3DSPD_IUNKNOWN ) {
* ( LPUNKNOWN * ) pData = ( * data ) - > ptr . object ;
IUnknown_AddRef ( ( * data ) - > ptr . object ) ;
}
else {
memcpy ( pData , ( * data ) - > ptr . data , ( * data ) - > size ) ;
}
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 ;
2005-07-15 11:54:57 +02:00
PrivateData * * data ;
TRACE ( " (%p) : %p \n " , This , refguid ) ;
/* TODO: move this code off into a linked list class */
data = IWineD3DResourceImpl_FindPrivateData ( This , refguid ) ;
2006-04-07 12:51:12 +02:00
if ( * data = = NULL ) return WINED3DERR_NOTFOUND ;
2005-07-15 11:54:57 +02:00
* data = ( * data ) - > next ;
if ( ( * data ) - > flags & D3DSPD_IUNKNOWN )
{
if ( ( * data ) - > ptr . object ! = NULL )
IUnknown_Release ( ( * data ) - > ptr . object ) ;
} else {
HeapFree ( GetProcessHeap ( ) , 0 , ( * data ) - > ptr . data ) ;
}
HeapFree ( GetProcessHeap ( ) , 0 , * data ) ;
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
}
2006-04-10 19:39:53 +02:00
void dumpResources ( ResourceList * resources ) {
ResourceList * iterator = resources ;
while ( iterator ) {
FIXME ( " Leftover resource %p with type %d,%s \n " , iterator - > resource , IWineD3DResource_GetType ( iterator - > resource ) , debug_d3dresourcetype ( IWineD3DResource_GetType ( iterator - > resource ) ) ) ;
iterator = iterator - > next ;
}
}
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
} ;