722 lines
19 KiB
C++
722 lines
19 KiB
C++
#ifndef __RESOURCE_HPP__
|
|
#define __RESOURCE_HPP__
|
|
|
|
/*==========================================================================;
|
|
*
|
|
* Copyright (C) 1999-2000 Microsoft Corporation. All Rights Reserved.
|
|
*
|
|
* File: resource.hpp
|
|
* Content: Base class header for resources. A resource is an non-trivial
|
|
* object that is directly used by the graphics pipeline. It
|
|
* be composed of a set of buffers; for example a mip-map is
|
|
* a resource that is composed of Surfaces (which are buffers).
|
|
*
|
|
* Since resources are non-trivial (i.e. more than few bytes),
|
|
* they may need management. The resource cooperates with the
|
|
* Resource Manager component to get management functionality.
|
|
*
|
|
***************************************************************************/
|
|
|
|
#include "d3dobj.hpp"
|
|
|
|
// Forward Decl
|
|
struct CMgmtInfo;
|
|
class CResourceManager;
|
|
|
|
// Handle for Resource Manager; internally implemented as a pointer
|
|
typedef CMgmtInfo *RMHANDLE;
|
|
|
|
// A Resource is a Base Object that additionally
|
|
// has a Priority field
|
|
class CResource : public CBaseObject
|
|
{
|
|
public:
|
|
|
|
static HRESULT RestoreDriverManagementState(CBaseDevice *pDevice);
|
|
|
|
// These methods are for the
|
|
// use of the Resource Manager
|
|
RMHANDLE RMHandle() const
|
|
{
|
|
return m_RMHandle;
|
|
}; // RMHandle
|
|
|
|
// Determine if a resource is managed or driver-managed
|
|
BOOL IsD3DManaged() const
|
|
{
|
|
// Zero is not a valid RM handle
|
|
return (m_RMHandle != 0);
|
|
}; // IsD3DManaged
|
|
|
|
// Set the device batch number that
|
|
// this resource was last used in. In this
|
|
// context; the batch refers to whether
|
|
// this resource was used in the current
|
|
// command buffer (i.e. containing unflushed commands).
|
|
void Batch();
|
|
|
|
// Same as Batch() except it batches the
|
|
// backing (or sysmem) texture rather than the
|
|
// promoted (or vidmem) one.
|
|
void BatchBase();
|
|
|
|
// Notifies the device that this resource
|
|
// is about to be modified in a way that
|
|
// may require a flush. (i.e. Whenever the bits
|
|
// could change or a surface is going away.)
|
|
void Sync();
|
|
|
|
// Sets batch number
|
|
void SetBatchNumber(ULONGLONG batch)
|
|
{
|
|
// Batch numbers should only be increasing since we
|
|
// start at zero.
|
|
DXGASSERT(batch >= m_qwBatchCount);
|
|
|
|
m_qwBatchCount = batch;
|
|
} // SetBatchNumber
|
|
|
|
// returns the batch number that this resource
|
|
// was last referred in
|
|
ULONGLONG GetBatchNumber() const
|
|
{
|
|
return m_qwBatchCount;
|
|
}
|
|
|
|
// returns the DrawPrim handle associated with
|
|
// the Driver-Accessible clone if it is Managed;
|
|
// otherwise returns the handle of itself.
|
|
DWORD DriverAccessibleDrawPrimHandle() const;
|
|
|
|
// returns the Kernel handle associated with
|
|
// the Driver-Accessible clone if it is Managed;
|
|
// otherwise returns the handle of itself.
|
|
HANDLE DriverAccessibleKernelHandle() const;
|
|
|
|
// Specifies a creation of a resource that
|
|
// looks just like the current one. The LOD parameter
|
|
// may not be relevant for all Resource types.
|
|
virtual HRESULT Clone(D3DPOOL Pool,
|
|
CResource **ppResource) const PURE;
|
|
|
|
// Provides a method to access basic structure of the
|
|
// pieces of the resource.
|
|
virtual const D3DBUFFER_DESC* GetBufferDesc() const PURE;
|
|
|
|
// Tells the resource that it should copy itself
|
|
// to the target. It is the caller's responsibility
|
|
// to make sure that Target is compatible with the
|
|
// Source. (The Target may have different number of mip-levels
|
|
// and be in a different pool; however, it must have the same size,
|
|
// faces, format, etc.)
|
|
//
|
|
// This function will clear the dirty state.
|
|
virtual HRESULT UpdateDirtyPortion(CResource *pResourceTarget) PURE;
|
|
|
|
// Allows the Resource Manager to mark the texture
|
|
// as needing to be completely updated on next
|
|
// call to UpdateDirtyPortion
|
|
virtual void MarkAllDirty() PURE;
|
|
|
|
// Indicates whether the Resource has been modified since
|
|
// the last time that UpdateDirtyPortion has been called.
|
|
// All managed resources start out in the Dirty state.
|
|
BOOL IsDirty() const
|
|
{
|
|
return m_bIsDirty;
|
|
} // IsDirty
|
|
|
|
void PreLoadImpl();
|
|
|
|
// Returns the pool which the user passed in
|
|
D3DPOOL GetUserPool() const
|
|
{
|
|
return m_poolUser;
|
|
} // GetUserPool
|
|
|
|
protected:
|
|
// The following are methods that only make sense
|
|
// to be called by derived classes
|
|
|
|
// Helper to check if a type is managed
|
|
static BOOL IsTypeD3DManaged(CBaseDevice *pDevice,
|
|
D3DRESOURCETYPE Type,
|
|
D3DPOOL Pool);
|
|
|
|
static BOOL IsTypeDriverManaged(CBaseDevice *pDevice,
|
|
D3DRESOURCETYPE Type,
|
|
D3DPOOL Pool);
|
|
|
|
// Helper to determine what the 'real' pool is
|
|
// for a managed resource.
|
|
static D3DPOOL DetermineCreationPool(CBaseDevice *pDevice,
|
|
D3DRESOURCETYPE Type,
|
|
DWORD dwUsage,
|
|
D3DPOOL Pool);
|
|
|
|
// Constructor for Resources; all resources start out dirty
|
|
CResource(CBaseDevice *pDevice, D3DPOOL Pool, REF_TYPE refType = REF_EXTERNAL) :
|
|
CBaseObject(pDevice, refType),
|
|
m_RMHandle(0),
|
|
m_qwBatchCount(0),
|
|
m_Priority(0),
|
|
m_bIsDirty(TRUE),
|
|
m_poolUser(Pool),
|
|
m_pPrev(0)
|
|
{
|
|
m_pNext = pDevice->GetResourceList();
|
|
pDevice->SetResourceList(this);
|
|
if (m_pNext != 0)
|
|
{
|
|
m_pNext->m_pPrev = this;
|
|
}
|
|
}; // CResource
|
|
|
|
virtual ~CResource();
|
|
|
|
// Priority Inlines
|
|
DWORD SetPriorityImpl(DWORD newPri);
|
|
|
|
DWORD GetPriorityImpl();
|
|
|
|
// Allows initialization of the RMHandle after
|
|
// construction is basically complete
|
|
HRESULT InitializeRMHandle();
|
|
|
|
// Allows RMHandle to be set to zero
|
|
void DeleteRMHandle();
|
|
|
|
// Helper to notify the RM that
|
|
// we are now dirty.
|
|
void OnResourceDirty();
|
|
|
|
// Helper to notify resource when it
|
|
// is all clean
|
|
void OnResourceClean();
|
|
|
|
// Resources need to implement OnDestroy by
|
|
// calling Sync; (Textures overload this
|
|
// to call OnTextureDestroy on the device before
|
|
// calling their base class.)
|
|
virtual void OnDestroy(void)
|
|
{
|
|
Sync();
|
|
return;
|
|
} // OnDestroy
|
|
|
|
// Returns the current priority
|
|
DWORD GetPriorityI() const
|
|
{
|
|
return m_Priority;
|
|
}
|
|
|
|
// Sets the current priority (but does not do any work)
|
|
DWORD SetPriorityI(DWORD Priority)
|
|
{
|
|
DWORD oldPriority = m_Priority;
|
|
m_Priority = Priority;
|
|
return oldPriority;
|
|
}
|
|
|
|
private:
|
|
|
|
RMHANDLE m_RMHandle;
|
|
ULONGLONG m_qwBatchCount;
|
|
DWORD m_Priority;
|
|
BOOL m_bIsDirty;
|
|
|
|
// Remember the pool that the user passed in
|
|
D3DPOOL m_poolUser;
|
|
|
|
// Linked list of resources
|
|
CResource *m_pPrev;
|
|
CResource *m_pNext;
|
|
|
|
friend CResourceManager;
|
|
}; // CResource
|
|
|
|
struct CMgmtInfo
|
|
{
|
|
// This is static because we assume all resources
|
|
// to be in heap zero. WHEN the resource manager
|
|
// supports multiple heaps, m_rmHeap should be
|
|
// made per object again.
|
|
static DWORD m_rmHeap;
|
|
|
|
DWORD m_priority;
|
|
DWORD m_LOD;
|
|
BOOL m_bInUse;
|
|
|
|
DWORD m_rmHeapIndex;
|
|
DWORD m_scene;
|
|
DWORD m_ticks;
|
|
CResource *m_pRes;
|
|
CResource *m_pBackup;
|
|
|
|
CMgmtInfo(CResource*);
|
|
~CMgmtInfo();
|
|
|
|
ULONGLONG Cost() const
|
|
{
|
|
#ifdef _X86_
|
|
ULONGLONG retval;
|
|
_asm
|
|
{
|
|
mov ebx, this;
|
|
mov edx, [ebx]CMgmtInfo.m_bInUse;
|
|
shl edx, 31;
|
|
mov eax, [ebx]CMgmtInfo.m_priority;
|
|
mov ecx, eax;
|
|
shr eax, 1;
|
|
or edx, eax;
|
|
mov DWORD PTR retval + 4, edx;
|
|
shl ecx, 31;
|
|
mov eax, [ebx]CMgmtInfo.m_ticks;
|
|
shr eax, 1;
|
|
or eax, ecx;
|
|
mov DWORD PTR retval, eax;
|
|
}
|
|
return retval;
|
|
#else
|
|
return ((ULONGLONG)m_bInUse << 63) + ((ULONGLONG)m_priority << 31) + ((ULONGLONG)(m_ticks >> 1));
|
|
#endif
|
|
}
|
|
}; // CMgmtInfo
|
|
|
|
inline CMgmtInfo::CMgmtInfo(CResource *pBackup)
|
|
{
|
|
m_priority = 0;
|
|
m_LOD = 0;
|
|
m_bInUse = FALSE;
|
|
m_rmHeap = 0;
|
|
m_rmHeapIndex = 0;
|
|
m_scene = 0;
|
|
m_ticks = 0;
|
|
m_pRes = 0;
|
|
m_pBackup = pBackup;
|
|
} // CMgmtInfo::CMgmtInfo
|
|
|
|
inline CMgmtInfo::~CMgmtInfo()
|
|
{
|
|
if (m_pRes != 0)
|
|
{
|
|
m_pRes->DecrementUseCount();
|
|
}
|
|
} // CMgmtInfo::~CMgmtInfo
|
|
|
|
class CRMHeap
|
|
{
|
|
|
|
private:
|
|
|
|
enum { InitialSize = 1023 };
|
|
|
|
DWORD m_next, m_size;
|
|
CMgmtInfo **m_data_p;
|
|
|
|
DWORD parent(DWORD k) const { return k / 2; }
|
|
DWORD lchild(DWORD k) const { return k * 2; }
|
|
DWORD rchild(DWORD k) const { return k * 2 + 1; }
|
|
void heapify(DWORD k);
|
|
|
|
public:
|
|
|
|
CRMHeap(DWORD size = InitialSize);
|
|
~CRMHeap();
|
|
BOOL Initialize();
|
|
|
|
DWORD length() const { return m_next - 1; }
|
|
CMgmtInfo* minCost() const { return m_data_p[1]; }
|
|
|
|
BOOL add(CMgmtInfo*);
|
|
CMgmtInfo* extractMin();
|
|
CMgmtInfo* extractMax();
|
|
CMgmtInfo* extractNotInScene(DWORD dwScene);
|
|
void del(CMgmtInfo*);
|
|
void update(CMgmtInfo*, BOOL inuse, DWORD priority, DWORD ticks);
|
|
void resetAllTimeStamps(DWORD ticks);
|
|
}; // class CRMHeap
|
|
|
|
inline CRMHeap::CRMHeap(DWORD size)
|
|
{
|
|
m_next = 1;
|
|
m_size = size + 1;
|
|
} // CRMHeap::CRMHeap
|
|
|
|
inline CRMHeap::~CRMHeap()
|
|
{
|
|
delete[] m_data_p;
|
|
} // CRMHeap::~CRMHeap
|
|
|
|
class CResourceManager
|
|
{
|
|
|
|
public:
|
|
|
|
CResourceManager();
|
|
~CResourceManager();
|
|
|
|
// Need to call before using the manager
|
|
HRESULT Init(CBaseDevice *pD3D8);
|
|
|
|
// Check to see if a type is going to driver managed
|
|
// or going to be D3D managed
|
|
BOOL IsDriverManaged(D3DRESOURCETYPE Type) const;
|
|
|
|
// Specify that a resource needs to be managed
|
|
//
|
|
// Error indicates that we don't support management for this
|
|
// resource type.
|
|
HRESULT Manage(CResource *pResource, RMHANDLE *pHandle);
|
|
|
|
// Stop managing a resouce; called when a managed resource
|
|
// is going away
|
|
void UnManage(RMHANDLE hRMHandle);
|
|
|
|
// The RM manages Priority and LOD for the resource
|
|
DWORD SetPriority(RMHANDLE hRMHandle, DWORD newPriority);
|
|
DWORD SetLOD(RMHANDLE hRMHandle, DWORD dwLodNew);
|
|
|
|
// Preloads resource into video memory
|
|
void PreLoad(RMHANDLE hRMHandle);
|
|
|
|
// Checks if the resource is in video memory
|
|
BOOL InVidmem(RMHANDLE hRMHandle) const;
|
|
|
|
// This is called when DrawPrimitive needs to
|
|
// make sure that all resources used in the
|
|
// current call are in video memory and are
|
|
// uptodate.
|
|
HRESULT UpdateVideo(RMHANDLE hRMHandle, BOOL *bDirty);
|
|
HRESULT UpdateVideoInternal(CMgmtInfo *pMgmtInfo);
|
|
|
|
// This returns the appropriate handle for a
|
|
// managed resource
|
|
DWORD DrawPrimHandle(RMHANDLE hRMHandle) const;
|
|
|
|
// This returns the appropriate kernel handle for a
|
|
// managed resource
|
|
HANDLE KernelHandle(RMHANDLE hRMHandle) const;
|
|
|
|
// This call will batch the appropriate resource
|
|
// for the purpose of syncing
|
|
void Batch(RMHANDLE hRMHandle, ULONGLONG batch) const;
|
|
|
|
// Called from outside when a managed resource becomes dirty
|
|
void OnResourceDirty(RMHANDLE hRMHandle) const;
|
|
|
|
void DiscardBytes(DWORD cbBytes);
|
|
|
|
void SceneStamp() { ++m_dwScene; }
|
|
|
|
private:
|
|
|
|
CBaseDevice *m_pD3D8;
|
|
unsigned tcm_ticks, m_dwScene, m_dwNumHeaps;
|
|
BOOL m_PreLoading;
|
|
CRMHeap *m_heap_p;
|
|
|
|
BOOL FreeResources(DWORD dwHeap, DWORD dwBytes);
|
|
|
|
void Lock(RMHANDLE hRMHandle);
|
|
void Unlock(RMHANDLE hRMHandle);
|
|
|
|
void TimeStamp(CMgmtInfo *pMgmtInfo);
|
|
|
|
}; // class CResourceManager
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CResource::IsTypeD3DManaged"
|
|
|
|
inline BOOL CResource::IsTypeD3DManaged(CBaseDevice *pDevice,
|
|
D3DRESOURCETYPE Type,
|
|
D3DPOOL Pool)
|
|
{
|
|
if (Pool == D3DPOOL_MANAGED)
|
|
{
|
|
return !IsTypeDriverManaged(pDevice, Type, Pool);
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}; // IsTypeD3DManaged
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CResource::IsTypeDriverManaged"
|
|
|
|
inline BOOL CResource::IsTypeDriverManaged(CBaseDevice *pDevice,
|
|
D3DRESOURCETYPE Type,
|
|
D3DPOOL Pool)
|
|
{
|
|
if (Pool == D3DPOOL_MANAGED)
|
|
{
|
|
if (pDevice->ResourceManager()->IsDriverManaged(Type))
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}; // IsTypeDriverManaged
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CResource::DetermineCreationPool"
|
|
|
|
inline D3DPOOL CResource::DetermineCreationPool(CBaseDevice *pDevice,
|
|
D3DRESOURCETYPE Type,
|
|
DWORD dwUsage,
|
|
D3DPOOL Pool)
|
|
{
|
|
if (Pool == D3DPOOL_MANAGED)
|
|
{
|
|
if (IsTypeDriverManaged(pDevice, Type, Pool))
|
|
{
|
|
// This pool is used by the thunk layer
|
|
// to use the driver management flag during
|
|
// create
|
|
return D3DPOOL_MANAGED;
|
|
}
|
|
else
|
|
{
|
|
// If it is not driver managed; then it
|
|
// becomes D3DMANAGED
|
|
return D3DPOOL_SYSTEMMEM;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Not managed at all; so we just
|
|
// use the same pool we started with
|
|
return Pool;
|
|
}
|
|
} // DetermineCreationPool
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CResource::~CResource"
|
|
|
|
inline CResource::~CResource()
|
|
{
|
|
// If managed, we need to notify
|
|
// the ResourceManager that we are going away
|
|
if (IsD3DManaged())
|
|
{
|
|
Device()->ResourceManager()->UnManage(m_RMHandle);
|
|
}
|
|
// Unlink from the resource list
|
|
if (m_pNext != 0)
|
|
{
|
|
m_pNext->m_pPrev = m_pPrev;
|
|
}
|
|
if (m_pPrev != 0)
|
|
{
|
|
m_pPrev->m_pNext = m_pNext;
|
|
DXGASSERT(Device()->GetResourceList() != this);
|
|
}
|
|
else
|
|
{
|
|
DXGASSERT(Device()->GetResourceList() == this);
|
|
Device()->SetResourceList(m_pNext);
|
|
}
|
|
}; // ~CResource
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CResource::InitializeRMHandle"
|
|
|
|
// Allows initialization of the RMHandle after
|
|
// construction is basically complete
|
|
inline HRESULT CResource::InitializeRMHandle()
|
|
{
|
|
// We should not already have a handle
|
|
DXGASSERT(m_RMHandle == 0);
|
|
|
|
// Get a handle from the resource manager
|
|
return Device()->ResourceManager()->Manage(this, &m_RMHandle);
|
|
}; // InitializeRMHandle
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CResource::DeleteRMHandle"
|
|
|
|
inline void CResource::DeleteRMHandle()
|
|
{
|
|
// We should already have a handle
|
|
DXGASSERT(m_RMHandle != 0);
|
|
|
|
Device()->ResourceManager()->UnManage(m_RMHandle);
|
|
m_RMHandle = 0;
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CResource::OnResourceDirty"
|
|
|
|
// Add a helper to notify the RM that
|
|
// we are now dirty.
|
|
inline void CResource::OnResourceDirty()
|
|
{
|
|
// Update our state
|
|
m_bIsDirty = TRUE;
|
|
|
|
// Only need to notify RM for managed textures
|
|
// that have been been set through SetTexture
|
|
if (IsD3DManaged() && IsInUse())
|
|
{
|
|
Device()->ResourceManager()->OnResourceDirty(m_RMHandle);
|
|
}
|
|
|
|
return;
|
|
}; // OnResourceDirty
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CResource::OnResourceClean"
|
|
|
|
// Add a helper to help maintain m_bIsDirty bit
|
|
inline void CResource::OnResourceClean()
|
|
{
|
|
DXGASSERT(m_bIsDirty == TRUE);
|
|
m_bIsDirty = FALSE;
|
|
return;
|
|
}; // OnResourceDirty
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CResource::DriverAccessibleDrawPrimHandle"
|
|
|
|
inline DWORD CResource::DriverAccessibleDrawPrimHandle() const
|
|
{
|
|
if (IsD3DManaged())
|
|
{
|
|
// Return the DrawPrim handle of my clone
|
|
return Device()->ResourceManager()->DrawPrimHandle(RMHandle());
|
|
}
|
|
else
|
|
{
|
|
return BaseDrawPrimHandle();
|
|
}
|
|
} // CResource::DriverAccessibleDrawPrimHandle
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CResource::DriverAccessibleKernelHandle"
|
|
|
|
inline HANDLE CResource::DriverAccessibleKernelHandle() const
|
|
{
|
|
if (IsD3DManaged())
|
|
{
|
|
// Return the DrawPrim handle of my clone
|
|
HANDLE h = Device()->ResourceManager()->KernelHandle(RMHandle());
|
|
|
|
// If this handle is NULL, then it means it was called
|
|
// without calling UpdateVideo which isn't allowed/sane
|
|
DXGASSERT(h != NULL);
|
|
|
|
return h;
|
|
}
|
|
else
|
|
{
|
|
return BaseKernelHandle();
|
|
}
|
|
} // CResource::DriverAccessibleKernelHandle
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CResourceManager::CResourceManager"
|
|
|
|
inline CResourceManager::CResourceManager()
|
|
{
|
|
m_pD3D8 = 0;
|
|
tcm_ticks = m_dwScene = m_dwNumHeaps = 0;
|
|
m_heap_p = 0;
|
|
m_PreLoading = FALSE;
|
|
} // CResourceManager::CResourceManager
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CResourceManager::~CResourceManager"
|
|
|
|
inline CResourceManager::~CResourceManager()
|
|
{
|
|
// We should not call DiscardBytes here
|
|
// because this destructor can be called via
|
|
// the device destructor chain. In this situation
|
|
// DiscardBytes will access bad or already freed
|
|
// data.
|
|
delete[] m_heap_p;
|
|
} // CResourceManager::~CResourceManager
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CResourceManager::DrawPrimHandle"
|
|
|
|
inline DWORD CResourceManager::DrawPrimHandle(RMHANDLE hRMHandle) const
|
|
{
|
|
if (InVidmem(hRMHandle))
|
|
{
|
|
CMgmtInfo* &pMgmtInfo = hRMHandle;
|
|
return pMgmtInfo->m_pRes->BaseDrawPrimHandle();
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
} // CResourceManager::DrawPrimHandle
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CResourceManager::KernelHandle"
|
|
|
|
inline HANDLE CResourceManager::KernelHandle(RMHANDLE hRMHandle) const
|
|
{
|
|
if (InVidmem(hRMHandle))
|
|
{
|
|
CMgmtInfo* &pMgmtInfo = hRMHandle;
|
|
return pMgmtInfo->m_pRes->BaseKernelHandle();
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
} // CResourceManager::Kernelhandle
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CResourceManager::InVidmem"
|
|
|
|
inline BOOL CResourceManager::InVidmem(RMHANDLE hRMHandle) const
|
|
{
|
|
CMgmtInfo* &pMgmtInfo = hRMHandle;
|
|
DXGASSERT(pMgmtInfo != 0);
|
|
return pMgmtInfo->m_pRes != 0;
|
|
} // CResourceManager::InVidmem
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CResourceManager::Batch"
|
|
|
|
inline void CResourceManager::Batch(RMHANDLE hRMHandle, ULONGLONG batch) const
|
|
{
|
|
if (InVidmem(hRMHandle))
|
|
{
|
|
CMgmtInfo* &pMgmtInfo = hRMHandle;
|
|
pMgmtInfo->m_pRes->SetBatchNumber(batch);
|
|
}
|
|
} // CResourceManager::Batch
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CResourceManager::UpdateVideo"
|
|
|
|
inline HRESULT CResourceManager::UpdateVideo(RMHANDLE hRMHandle, BOOL *bDirty)
|
|
{
|
|
HRESULT ddrval = S_OK;
|
|
CMgmtInfo* &pMgmtInfo = hRMHandle;
|
|
if (!InVidmem(hRMHandle))
|
|
{
|
|
ddrval = UpdateVideoInternal(pMgmtInfo);
|
|
*bDirty = TRUE;
|
|
}
|
|
else
|
|
{
|
|
if (pMgmtInfo->m_pBackup->IsDirty())
|
|
{
|
|
ddrval = pMgmtInfo->m_pBackup->UpdateDirtyPortion(pMgmtInfo->m_pRes);
|
|
}
|
|
TimeStamp(pMgmtInfo);
|
|
}
|
|
return ddrval;
|
|
}
|
|
|
|
#endif // __RESOURCE_HPP__
|