Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

265 lines
7.4 KiB

#ifndef __CUBESURF_HPP__
#define __CUBESURF_HPP__
/*==========================================================================;
*
* Copyright (C) 1999-2000 Microsoft Corporation. All Rights Reserved.
*
* File: cubesurf.hpp
* Content: Class header the cubesurface class. This class acts
* as a level for the CubeMap 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 "cubemap.hpp"
//
// The CCubeSurface class is a special class that
// works solely with the CCubeMap class. Each CubeSurface
// corresponds to a single level and face of the cube-map. They are
// not stand-alone COM objects because they share the
// same life-time as their CCubeMap parent.
//
// The CDriverCubeSurface class handles
// the driver-managed and vid-mem versions of this
// class.
//
class CCubeSurface : public CBaseSurface
{
public:
// Constructor
CCubeSurface(CCubeMap *pParent,
BYTE iFace,
BYTE iLevel,
HANDLE hKernelHandle)
:
m_pParent(pParent),
m_iFace(iFace),
m_iLevel(iLevel),
m_hKernelHandle(hKernelHandle)
{
DXGASSERT(hKernelHandle || (pParent->GetUserPool() == D3DPOOL_SCRATCH) );
DXGASSERT(m_pParent);
#ifdef DEBUG
m_cRefDebug = 0;
#endif // DEBUG
if (m_pParent->Desc()->Usage &
(D3DUSAGE_LOCK | D3DUSAGE_LOADONCE))
{
m_isLockable = TRUE;
}
else
{
m_isLockable = FALSE;
}
} // CCubeSurface
~CCubeSurface()
{
DXGASSERT(m_pParent);
DXGASSERT(m_cRefDebug == 0);
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
}; // ~CCubeSurface
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 ** ppvObj);
// 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);
} // GetDrawPrimHandle
virtual HANDLE KernelHandle() const
{
return m_hKernelHandle;
} // GetKernelHandle
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;
// Access the device of the surface
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 accessor for the device
// Access the device of the surface
CBaseDevice *Device() const
{
return m_pParent->Device();
} // Device
protected:
CCubeMap *m_pParent;
BOOL m_isLockable;
BYTE m_iLevel;
BYTE m_iFace;
// Helper function so that we can put all
// the private data into the same list. This
// returns a value that can be used to tag
// each of the private datas that are held
// by the master cubemap. Also, the value
// of (m_cLevel) is used as the tag for
// the CubeMap's private data itself
BYTE CombinedFaceLevel()
{
DXGASSERT(m_iLevel < (1<<5));
DXGASSERT(m_iFace < (1<<3));
return (m_iFace << 5) + m_iLevel;
} // CombinedFaceLevel
// We'll need a kernel handle so that
// we can communicate to the kernel for
// the Destroy call
HANDLE m_hKernelHandle;
// Debugging trick to help spew better
// information if someone over-releases a cubesurface
// (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
}; // CCubeSurface
// The CDriverCubeSurface is a modification of the base Cube-map
// class. It keeps track some additional information and overrides
// some of the methods. It implements Lock/Unlock by calling the
// driver; hence it is used for both driver-managed and vid-mem
// surface
class CDriverCubeSurface : public CCubeSurface
{
public:
// Constructor
CDriverCubeSurface(CCubeMap *pParent,
BYTE iFace,
BYTE iLevel,
HANDLE hKernelHandle)
:
CCubeSurface(pParent, iFace, iLevel, hKernelHandle)
{
} // Init
STDMETHOD(LockRect)(D3DLOCKED_RECT *pLockedRectData,
CONST RECT *pRect,
DWORD dwFlags);
STDMETHOD(UnlockRect)(THIS);
// 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();
}; // CDriverCubeSurface
#endif // __CUBESURF_HPP__