You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
261 lines
7.3 KiB
261 lines
7.3 KiB
#ifndef __MIPSURF_HPP__
|
|
#define __MIPSURF_HPP__
|
|
|
|
/*==========================================================================;
|
|
*
|
|
* Copyright (C) 1999-2000 Microsoft Corporation. All Rights Reserved.
|
|
*
|
|
* File: mipsurf.hpp
|
|
* Content: Class header the mipsurface class. This class acts
|
|
* as a level for the MipMap class. The base class
|
|
* assumes a system-memory allocation; while the
|
|
* Driver sub-class will call the driver for every
|
|
* lock and unlock operation.
|
|
*
|
|
*
|
|
***************************************************************************/
|
|
|
|
// Includes
|
|
#include "mipmap.hpp"
|
|
|
|
//
|
|
// Each MipSurface implements the IDirect3DSurface8 interface.
|
|
// To reduce overhead per level, we have
|
|
// put most of the "real" guts of each surface into the MipMap container
|
|
// class; i.e. most of the methods of the MipSurface really just end
|
|
// up calling something in the MipMap object.
|
|
//
|
|
// The base class implementation assumes a sys-mem allocation.
|
|
//
|
|
|
|
|
|
//
|
|
// The CMipSurface class is a special class that
|
|
// works solely with the CMipMap class. Each MipSurface
|
|
// corresponds to a single level of the mip-map. They are
|
|
// not stand-alone COM objects because they share the
|
|
// same life-time as their CMipMap parent.
|
|
//
|
|
// The CDriverMipSurface class is declared later in this file
|
|
//
|
|
|
|
class CMipSurface : public CBaseSurface
|
|
{
|
|
public:
|
|
// Constructor
|
|
CMipSurface(CMipMap *pParent,
|
|
BYTE iLevel,
|
|
HANDLE hKernelHandle
|
|
) :
|
|
m_pParent(pParent),
|
|
m_iLevel(iLevel),
|
|
m_hKernelHandle(hKernelHandle)
|
|
{
|
|
DXGASSERT(pParent);
|
|
DXGASSERT(hKernelHandle || (pParent->GetUserPool() == D3DPOOL_SCRATCH) );
|
|
#ifdef DEBUG
|
|
m_cRefDebug = 0;
|
|
#endif // DEBUG
|
|
|
|
if (m_pParent->Desc()->Usage &
|
|
(D3DUSAGE_LOCK | D3DUSAGE_LOADONCE))
|
|
{
|
|
m_isLockable = TRUE;
|
|
}
|
|
else
|
|
{
|
|
m_isLockable = FALSE;
|
|
}
|
|
|
|
return;
|
|
} // CMipSurface
|
|
|
|
~CMipSurface()
|
|
{
|
|
DXGASSERT(m_cRefDebug == 0);
|
|
//m_hKernelHandle will be 0 if this is a scratch pool.
|
|
if (m_hKernelHandle)
|
|
{
|
|
// Tell the thunk layer that we need to
|
|
// be freed.
|
|
|
|
D3D8_DESTROYSURFACEDATA DestroySurfData;
|
|
DestroySurfData.hDD = m_pParent->Device()->GetHandle();
|
|
DestroySurfData.hSurface = m_hKernelHandle;
|
|
m_pParent->Device()->GetHalCallbacks()->DestroySurface(&DestroySurfData);
|
|
}
|
|
#ifdef DEBUG
|
|
else
|
|
{
|
|
DXGASSERT(m_pParent->GetUserPool() == D3DPOOL_SCRATCH);
|
|
}
|
|
#endif //DEBUG
|
|
}; // ~CMipSurface
|
|
|
|
public:
|
|
// IUnknown methods
|
|
STDMETHOD(QueryInterface) (REFIID riid,
|
|
LPVOID FAR * ppvObj);
|
|
STDMETHOD_(ULONG,AddRef) ();
|
|
STDMETHOD_(ULONG,Release) ();
|
|
|
|
// IBuffer methods
|
|
STDMETHOD(SetPrivateData)(REFGUID riid,
|
|
CONST VOID* pvData,
|
|
DWORD cbData,
|
|
DWORD dwFlags);
|
|
|
|
STDMETHOD(GetPrivateData)(REFGUID riid,
|
|
LPVOID pvData,
|
|
LPDWORD pcbData);
|
|
|
|
STDMETHOD(FreePrivateData)(REFGUID riid);
|
|
|
|
STDMETHOD(GetContainer)(REFIID riid,
|
|
void **ppContainer);
|
|
|
|
STDMETHOD(GetDevice)(IDirect3DDevice8 **ppDevice);
|
|
|
|
|
|
// IDirect3DSurface8 methods
|
|
STDMETHOD(GetDesc)(D3DSURFACE_DESC *pDesc);
|
|
|
|
STDMETHOD(LockRect)(D3DLOCKED_RECT *pLockedRectData,
|
|
CONST RECT *pRect,
|
|
DWORD dwFlags);
|
|
|
|
STDMETHOD(UnlockRect)();
|
|
|
|
// BaseSurface methods
|
|
|
|
virtual DWORD DrawPrimHandle() const
|
|
{
|
|
return D3D8GetDrawPrimHandle(m_hKernelHandle);
|
|
} // DrawPrimHandle
|
|
|
|
virtual HANDLE KernelHandle() const
|
|
{
|
|
return m_hKernelHandle;
|
|
} // KernelHandle
|
|
|
|
virtual DWORD IncrementUseCount()
|
|
{
|
|
return m_pParent->IncrementUseCount();
|
|
} // IncrementUseCount
|
|
|
|
virtual DWORD DecrementUseCount()
|
|
{
|
|
return m_pParent->DecrementUseCount();
|
|
} // DecrementUseCount
|
|
|
|
virtual void Batch()
|
|
{
|
|
m_pParent->Batch();
|
|
return;
|
|
} // Batch
|
|
|
|
virtual void Sync()
|
|
{
|
|
m_pParent->Sync();
|
|
return;
|
|
} // Sync
|
|
|
|
// Internal lock functions bypass
|
|
// parameter checking and also whether the
|
|
// surface marked as Lockable or LockOnce
|
|
// etc. (Methods of CBaseSurface.)
|
|
virtual HRESULT InternalLockRect(D3DLOCKED_RECT *pLockedRectData,
|
|
CONST RECT *pRect,
|
|
DWORD dwFlags);
|
|
|
|
virtual HRESULT InternalUnlockRect();
|
|
|
|
virtual D3DSURFACE_DESC InternalGetDesc() const;
|
|
|
|
virtual CBaseDevice * InternalGetDevice() const
|
|
{
|
|
return m_pParent->Device();
|
|
} // InternalGetDevice
|
|
|
|
// Determines if a LOAD_ONCE surface has already
|
|
// been loaded
|
|
virtual BOOL IsLoaded() const
|
|
{
|
|
DXGASSERT(m_pParent->Desc()->Usage & D3DUSAGE_LOADONCE);
|
|
if (m_isLockable)
|
|
{
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
return TRUE;
|
|
}
|
|
} // IsLoaded
|
|
|
|
// End Of BaseSurface methods
|
|
|
|
// Quick method to avoid the virtual function call
|
|
CBaseDevice * Device() const
|
|
{
|
|
return m_pParent->Device();
|
|
} // Device
|
|
|
|
protected:
|
|
CMipMap *m_pParent;
|
|
BOOL m_isLockable;
|
|
BYTE m_iLevel;
|
|
|
|
// We'll need internal handles so that
|
|
// we can communicate call Destroy
|
|
// and so that CDriverMipMap can call
|
|
// Lock/Unlock etc.
|
|
HANDLE m_hKernelHandle;
|
|
|
|
// Debugging trick to help spew better
|
|
// information if someone over-releases a mipsurface
|
|
// (Since our ref's carry over to the parent object; it
|
|
// means that over-releases can be hard to find.)
|
|
#ifdef DEBUG
|
|
DWORD m_cRefDebug;
|
|
#endif // DEBUG
|
|
|
|
}; // CMipSurface
|
|
|
|
// The CDriverMipSurface is a modification of the base mipsurf
|
|
// class. It overrides lock and unlock and routes the call to the
|
|
// driver
|
|
class CDriverMipSurface : public CMipSurface
|
|
{
|
|
public:
|
|
// Constructor
|
|
CDriverMipSurface(CMipMap *pParent,
|
|
BYTE iLevel,
|
|
HANDLE hKernelHandle
|
|
) :
|
|
CMipSurface(pParent, iLevel, hKernelHandle)
|
|
{
|
|
} // CDriverMipSurface
|
|
|
|
public:
|
|
|
|
STDMETHOD(LockRect)(D3DLOCKED_RECT *pLockedRectData,
|
|
CONST RECT *pRect,
|
|
DWORD dwFlags);
|
|
|
|
STDMETHOD(UnlockRect)();
|
|
|
|
// Internal lock functions bypass
|
|
// parameter checking and also whether the
|
|
// surface marked as Lockable or LockOnce
|
|
// etc. (Methods of CBaseSurface.)
|
|
virtual HRESULT InternalLockRect(D3DLOCKED_RECT *pLockedRectData,
|
|
CONST RECT *pRect,
|
|
DWORD dwFlags);
|
|
|
|
virtual HRESULT InternalUnlockRect();
|
|
|
|
|
|
}; // CDriverMipSurface
|
|
|
|
|
|
#endif // __MIPSURF_HPP__
|