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
2009-01-13 10:31:57 +01:00
HRESULT resource_init ( struct IWineD3DResourceClass * resource , WINED3DRESOURCETYPE resource_type ,
IWineD3DDeviceImpl * device , UINT size , DWORD usage , WINED3DFORMAT format , WINED3DPOOL pool , IUnknown * parent )
{
resource - > wineD3DDevice = device ;
resource - > parent = parent ;
resource - > resourceType = resource_type ;
resource - > ref = 1 ;
resource - > pool = pool ;
resource - > format = format ;
resource - > usage = usage ;
resource - > size = size ;
resource - > priority = 0 ;
list_init ( & resource - > privateData ) ;
if ( size )
{
resource - > heapMemory = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , size + RESOURCE_ALIGNMENT ) ;
if ( ! resource - > heapMemory )
{
ERR ( " Out of memory! \n " ) ;
return WINED3DERR_OUTOFVIDEOMEMORY ;
}
}
else
{
resource - > heapMemory = NULL ;
}
resource - > allocatedMemory = ( BYTE * ) ( ( ( ULONG_PTR ) resource - > heapMemory + ( RESOURCE_ALIGNMENT - 1 ) ) & ~ ( RESOURCE_ALIGNMENT - 1 ) ) ;
/* Check that we have enough video ram left */
if ( pool = = WINED3DPOOL_DEFAULT )
{
if ( size > IWineD3DDevice_GetAvailableTextureMem ( ( IWineD3DDevice * ) device ) )
{
ERR ( " Out of adapter memory \n " ) ;
HeapFree ( GetProcessHeap ( ) , 0 , resource - > heapMemory ) ;
return WINED3DERR_OUTOFVIDEOMEMORY ;
}
WineD3DAdapterChangeGLRam ( device , size ) ;
}
return WINED3D_OK ;
}
2008-12-02 18:41:33 +01:00
void resource_cleanup ( IWineD3DResource * iface )
{
2005-03-29 21:01:00 +02:00
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 ) ;
2008-12-02 18:41:33 +01:00
hr = resource_free_private_data ( iface , & data - > tag ) ;
2007-05-11 00:09:35 +02:00
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 ) ;
2008-01-23 15:16:30 +01:00
} /* NOTE: this is not really an error for system memory resources */
2005-07-26 12:34:15 +02:00
return ;
2005-03-29 21:01:00 +02:00
}
2008-12-02 18:41:33 +01:00
HRESULT resource_get_device ( IWineD3DResource * iface , IWineD3DDevice * * ppDevice )
{
2004-10-14 02:32:04 +02:00
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
}
2008-12-02 18:41:33 +01:00
static PrivateData * resource_find_private_data ( IWineD3DResourceImpl * This , REFGUID tag )
2005-07-15 11:54:57 +02:00
{
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
}
2008-12-02 18:41:33 +01:00
HRESULT resource_set_private_data ( IWineD3DResource * iface , REFGUID refguid ,
const void * pData , DWORD SizeOfData , DWORD Flags )
{
2004-10-14 02:32:04 +02:00
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 ) ;
2008-12-02 18:41:33 +01:00
resource_free_private_data ( 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 ;
2008-12-01 15:32:15 +01:00
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
2008-12-02 18:41:33 +01:00
HRESULT resource_get_private_data ( IWineD3DResource * iface , REFGUID refguid , void * pData , DWORD * pSizeOfData )
{
2004-10-14 02:32:04 +02:00
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 ) ;
2008-12-02 18:41:33 +01:00
data = resource_find_private_data ( 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 ( * 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
}
2008-12-02 18:41:33 +01:00
HRESULT resource_free_private_data ( IWineD3DResource * iface , REFGUID refguid )
{
2004-10-14 02:32:04 +02:00
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 ) ) ;
2008-12-02 18:41:33 +01:00
data = resource_find_private_data ( 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
}
2008-12-02 18:41:33 +01:00
DWORD resource_set_priority ( IWineD3DResource * iface , DWORD PriorityNew )
{
2004-10-14 02:32:04 +02:00
IWineD3DResourceImpl * This = ( IWineD3DResourceImpl * ) iface ;
2008-09-29 19:52:18 +02:00
DWORD PriorityOld = This - > resource . priority ;
This - > resource . priority = PriorityNew ;
TRACE ( " (%p) : new priority %d, returning old priority %d \n " , This , PriorityNew , PriorityOld ) ;
return PriorityOld ;
2004-10-14 02:32:04 +02:00
}
2008-09-29 19:52:18 +02:00
2008-12-02 18:41:33 +01:00
DWORD resource_get_priority ( IWineD3DResource * iface )
{
2004-10-14 02:32:04 +02:00
IWineD3DResourceImpl * This = ( IWineD3DResourceImpl * ) iface ;
2008-09-29 19:52:18 +02:00
TRACE ( " (%p) : returning %d \n " , This , This - > resource . priority ) ;
return This - > resource . priority ;
2004-10-14 02:32:04 +02:00
}
2008-12-02 18:41:33 +01:00
WINED3DRESOURCETYPE resource_get_type ( 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 ;
}
2008-12-02 18:41:33 +01:00
HRESULT resource_get_parent ( IWineD3DResource * iface , IUnknown * * pParent )
{
2004-11-23 14:52:46 +01:00
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
}
}