/////////////////////////////////////////////////////////////////////////////// // Copyright (C) Microsoft Corporation, 2000. // // refdev.hpp // // Direct3D Reference Device - Main Header File // /////////////////////////////////////////////////////////////////////////////// #ifndef _REFDEV_HPP #define _REFDEV_HPP #include #include #include #include #pragma warning( disable: 4056) // fp constant #pragma warning( disable: 4244) // fp DOUBLE->FLOAT #include #include #include #include "d3d8ddi.h" //@@BEGIN_MSINTERNAL #include "d3d8p.h" //@@END_MSINTERNAL #include // forward declarations class D3DDebugMonitor; class RDDebugMonitor; class RDSurfaceManager; class RDSurface2D; class RDSurface; class RDRenderTarget; class RDTextureStageState; class RDBSpline; class RDNPatch; class RefDev; #include #include #include #include #include #include #include //----------------------------------------------------------------------------- // // A special legacy (pre-DX6) texture op we can't easily map into the new // texture ops. // //----------------------------------------------------------------------------- #define D3DTOP_LEGACY_ALPHAOVR (0x7fffffff) //----------------------------------------------------------------------------- // // Constants // //----------------------------------------------------------------------------- const DWORD RD_MAX_NUM_TEXTURE_FORMATS = 50; const DWORD RD_MAX_CLOD = 13*6; // base texture up to 4kx4k for 6 Cubemaps //----------------------------------------------------------------------------- // // RefRastSetMemif - Routine to set memory allocation interface for reference // rasterizer - takes pointers to functions to use for malloc, free, and realloc. // // These must be set prior to new'ing any RefDev objects. // //----------------------------------------------------------------------------- void RefRastSetMemif( LPVOID( _cdecl* pfnMemAlloc )( size_t ), void( _cdecl* pfnMemFree )( PVOID ), LPVOID( _cdecl* pfnMemReAlloc )( PVOID, size_t ) ); //----------------------------------------------------------------------------- // // RDRenderTarget - Class which encompasses all information about rendering // target, including size, type/pointer/stride for color and depth/stencil // buffers, guard band clip info, W range info. // // Usage is to instantiate, fill out public members, and install into a // RefDev object via RefDev::SetRenderTarget. // //----------------------------------------------------------------------------- class RDRenderTarget : public RDAlloc { public: /////////////////////////////////////////////////////////////////////////// // // public interface // /////////////////////////////////////////////////////////////////////////// RDRenderTarget( void ); ~RDRenderTarget( void ); // // these need to be filled in by the user before installing in a // RefDev object // RECT m_Clip; // clipping bounds FLOAT m_fWRange[2]; // range of device W (W at near and far clip planes) RDSurface2D* m_pColor; RDSurface2D* m_pDepth; // This boolean indicates that the DDI used to set render target // is a pre-DX7. This is used by the destructor to free up the // color and depth buffers. BOOL m_bPreDX7DDI; /////////////////////////////////////////////////////////////////////////// // // internal state and methods // /////////////////////////////////////////////////////////////////////////// friend class RefDev; HRESULT Initialize( LPDDRAWI_DIRECTDRAW_LCL pDDLcl, DWORD dwColorHandle, DWORD dwDepthHandle ); HRESULT Initialize( LPDDRAWI_DIRECTDRAW_LCL pDDLcl, LPDDRAWI_DDRAWSURFACE_LCL pLclColor, LPDDRAWI_DDRAWSURFACE_LCL pLclZ ); HRESULT Initialize( LPDDRAWI_DDRAWSURFACE_LCL pLclColor, LPDDRAWI_DDRAWSURFACE_LCL pLclZ ); // read/write specific sample void ReadPixelColor ( INT32 iX, INT32 iY, UINT Sample, RDColor& Color ); void WritePixelColor ( INT32 iX, INT32 iY, UINT Sample, const RDColor& Color, BOOL bDither ); void WritePixelDepth ( INT32 iX, INT32 iY, UINT Sample, const RDDepth& Depth ); void ReadPixelDepth ( INT32 iX, INT32 iY, UINT Sample, RDDepth& Depth ); void WritePixelStencil( INT32 iX, INT32 iY, UINT Sample, UINT8 uStencil ); void ReadPixelStencil ( INT32 iX, INT32 iY, UINT Sample, UINT8& uStencil ); // write all samples void WritePixelColor ( INT32 iX, INT32 iY, const RDColor& Color, BOOL bDither ); void WritePixelDepth ( INT32 iX, INT32 iY, const RDDepth& Depth ); void WritePixelStencil( INT32 iX, INT32 iY, UINT8 uStencil ); void Clear ( RDColor fillColor, LPD3DHAL_DP2COMMAND pCmd ); void ClearDepth ( RDDepth fillDepth, LPD3DHAL_DP2COMMAND pCmd ); void ClearStencil ( UINT8 uStencil, LPD3DHAL_DP2COMMAND pCmd ); void ClearDepthStencil( RDDepth fillDepth, UINT8 uStencil, LPD3DHAL_DP2COMMAND pCmd ); }; //----------------------------------------------------------------------------- // // RDTextureStageState - This holds the per-stage state for texture mapping. // An array of these are instanced in the RefDev object. // // Store texture matrix at the end of the texture stage state. // //----------------------------------------------------------------------------- class RDTextureStageState { public: union { DWORD m_dwVal[D3DTSS_MAX]; // state array (unsigned) FLOAT m_fVal[D3DTSS_MAX]; // state array (float) }; }; //----------------------------------------------------------------------------- // // RDSurface - Class instanced once per surface which encompasses information // about a chain of surfaces used either as a mipmap, cubemap, render-target, // depth-buffer, vertex buffer or an index buffer. Includes size and type // (assumed same for each level of detail) and pointer/stride for each LOD. // // Created by CreateSurfaceEx DDI call. // //----------------------------------------------------------------------------- // Surface type flags. Some combination of them are legal const DWORD RR_ST_UNKNOWN = 0; const DWORD RR_ST_TEXTURE = (1<<0); const DWORD RR_ST_RENDERTARGETCOLOR = (1<<2); const DWORD RR_ST_RENDERTARGETDEPTH = (1<<3); const DWORD RR_ST_VERTEXBUFFER = (1<<4); const DWORD RR_ST_INDEXBUFFER = (1<<5); // The following flags track the surface status const DWORD RRSURFACE_STATUS_INITCALLED = (1<<0); const DWORD RRSURFACE_STATUS_REFCREATED = (1<<1); const DWORD RRSURFACE_STATUS_ISLOCKED = (1<<2); class RDSurface { public: RDSurface() { m_dwStatus = 0; m_MemPool = D3DPOOL_FORCE_DWORD; m_SurfType = RR_ST_UNKNOWN; m_iLockCount = 0; } virtual HRESULT Initialize( LPDDRAWI_DDRAWSURFACE_LCL pDDSLcl ) = 0; virtual ~RDSurface() { return; } BOOL IsInitialized(){ return (m_dwStatus & RRSURFACE_STATUS_INITCALLED); } void SetInitialized(){ m_dwStatus |= RRSURFACE_STATUS_INITCALLED; } BOOL IsRefCreated() { return (m_dwStatus & RRSURFACE_STATUS_REFCREATED); } void SetRefCreated(){ m_dwStatus |= RRSURFACE_STATUS_REFCREATED; } BOOL IsLocked() { return (m_dwStatus & RRSURFACE_STATUS_ISLOCKED); } void Lock() { m_iLockCount++; } void Unlock() { if( m_iLockCount > 0 ) m_iLockCount--; } DWORD GetSurfaceType() { return m_SurfType; } D3DPOOL GetMemPool() { return m_MemPool; } protected: D3DPOOL m_MemPool; // Where is this allocated DWORD m_SurfType; // the type of surface DWORD m_dwStatus; int m_iLockCount; }; //----------------------------------------------------------------------------- // // RDCREATESURFPRIVATE // PrivateData stored in SurfaceGbl->dwReserved1 at CreateSurface call // //----------------------------------------------------------------------------- class RDCREATESURFPRIVATE { public: RDCREATESURFPRIVATE() { dwPitch = 0; dwLockCount = 0; pBits = NULL; wSamples = 1; dwMultiSamplePitch = 0; pMultiSampleBits = NULL; SurfaceFormat = RD_SF_NULL; } ~RDCREATESURFPRIVATE() { _ASSERT( dwLockCount == 0, "Surface being deleted has some" "outstanding locks" ); delete [] pBits; delete [] pMultiSampleBits; } void Lock() { dwLockCount++; } void Unlock() { if( dwLockCount > 0) dwLockCount--; } DWORD dwLockCount; union { DWORD dwPitch; DWORD dwVBSize; }; BYTE* pBits; WORD wSamples; DWORD dwMultiSamplePitch; BYTE* pMultiSampleBits; RDSurfaceFormat SurfaceFormat; }; //--------------------------------------------------------------------------- // RDDSurfaceArrayNode // // This is a node in the linked list of the growable array of RefSurfaces // maintained per ddraw lcl. //--------------------------------------------------------------------------- struct RDSurfaceHandle { RDSurfaceHandle() { m_pSurf = NULL; #if DBG m_tag = 0; #endif } RDSurface* m_pSurf; #if DBG // Non zero means that it has been allocated DWORD m_tag; #endif }; class RDSurfaceArrayNode : public RDListEntry { public: RDSurfaceArrayNode(LPDDRAWI_DIRECTDRAW_LCL pDDLcl); ~RDSurfaceArrayNode(); HRESULT AddSurface( LPDDRAWI_DDRAWSURFACE_LCL pDDSLcl, RDSurface** ppSurf ); RDSurface* GetSurface( DWORD dwHandle ); HRESULT RemoveSurface( DWORD dwHandle ); private: LPDDRAWI_DIRECTDRAW_LCL m_pDDLcl; GArrayT m_SurfHandleArray; RDSurfaceArrayNode* m_pNext; friend class RDSurfaceManager; }; //--------------------------------------------------------------------------- // RDSurfaceManager // // This class maintains a linked list of all the // surface handle tables for each DD_LCL //--------------------------------------------------------------------------- class RDSurfaceManager { public: RDSurfaceManager() {m_pFirstNode = NULL;} ~RDSurfaceManager() { RDSurfaceArrayNode *pNode = m_pFirstNode; while( pNode ) { RDSurfaceArrayNode *pTmp = pNode; pNode = pNode->m_pNext; delete pTmp; } } RDSurfaceArrayNode* AddLclNode( LPDDRAWI_DIRECTDRAW_LCL pDDLcl ); RDSurfaceArrayNode* GetLclNode( LPDDRAWI_DIRECTDRAW_LCL pDDLcl ); HRESULT AddSurfToList( LPDDRAWI_DIRECTDRAW_LCL pDDLcl, LPDDRAWI_DDRAWSURFACE_LCL pDDSLcl, RDSurface** ppSurf ); RDSurface* GetSurfFromList( LPDDRAWI_DIRECTDRAW_LCL pDDLcl, DWORD dwHandle ); HRESULT RemoveSurfFromList( LPDDRAWI_DIRECTDRAW_LCL pDDLcl, LPDDRAWI_DDRAWSURFACE_LCL pDDSLcl); HRESULT RemoveSurfFromList( LPDDRAWI_DIRECTDRAW_LCL pDDLcl, DWORD dwHandle ); private: RDSurfaceArrayNode *m_pFirstNode; }; extern RDSurfaceManager g_SurfMgr; //----------------------------------------------------------------------------- // // RDVertexBuffer - The RefDev's representation of the VertexBuffer. It gets // created on a CreateSurfaceEx call. // //----------------------------------------------------------------------------- class RDVertexBuffer : public RDSurface { public: RDVertexBuffer() { m_pBits = NULL; m_cbSize = 0; m_FVF = 0; } virtual ~RDVertexBuffer() { return; } HRESULT Initialize( LPDDRAWI_DDRAWSURFACE_LCL pLcl ); LPBYTE GetBits() { return m_pBits; } int GetFVF() { return m_FVF; } int GetSize() { return m_cbSize; } protected: DWORD m_FVF; BYTE* m_pBits; DWORD m_cbSize; }; //----------------------------------------------------------------------------- // // RDPalette - Class for representing and managing palettes in RefDev // //----------------------------------------------------------------------------- class RDPalette { public: RDPalette() { m_dwFlags = 0; memset( m_Entries, 0, sizeof( m_Entries ) ); } D3DCOLOR* GetEntries() { return m_Entries; } static const DWORD RDPAL_ALPHAINPALETTE; static const DWORD m_dwNumEntries; HRESULT Update( WORD StartIndex, WORD wNumEntries, PALETTEENTRY* pEntries ); BOOL HasAlpha() { return (m_dwFlags & RDPAL_ALPHAINPALETTE); } DWORD m_dwFlags; D3DCOLOR m_Entries[256]; }; struct RDPaletteHandle { RDPaletteHandle() { m_pPal = NULL; #if DBG m_tag = 0; #endif } RDPalette* m_pPal; #if DBG // Non zero means that it has been allocated DWORD m_tag; #endif }; //----------------------------------------------------------------------------- // // RDSurface2D - Class instanced once per 2D surface which could be either // texture, color render target or depth buffer information // about a chain of surfaces. Includes size and type // (assumed same for each level of detail) and pointer/stride for each LOD. // // Also includes pointer to palette, and colorkey value (legacy support only). // //----------------------------------------------------------------------------- class RDSurface2D : public RDSurface { public: /////////////////////////////////////////////////////////////////////////// // // public interface // /////////////////////////////////////////////////////////////////////////// RDSurface2D( void ); ~RDSurface2D( void ); friend class RefDev; class RefDev * m_pRefDev; // refdev which created this - used only when this is bound as a texture void SetRefDev( RefDev* pRefDev) { m_pRefDev = pRefDev; } DWORD m_uFlags; // RR_TEXTURE_* bitdefs // bit definitions for RDSurface2D::uFlags #define RR_TEXTURE_HAS_CK (1L<< 0) // set if texture has colorkey #define RR_TEXTURE_ALPHAINPALETTE (1L<< 1) // set if alpha channel in palette #define RR_TEXTURE_CUBEMAP (1L<< 2) // set if texture is Cubemap with 6 times the number of surfaces #define RR_TEXTURE_VOLUME (1L<< 4) // set if texture is volume // basic info UINT m_iSamples; int m_iWidth; // size of top-level map int m_iHeight; int m_iDepth; // depth of volume texture BYTE* m_pBits[RD_MAX_CLOD]; // pointer to surface bits int m_iPitch[RD_MAX_CLOD]; // pitch in bytes int m_iSlicePitch[RD_MAX_CLOD]; // slice pitch in bytes // for volume texture int m_cLOD; // 0..(n-1) count of LODs currently available RDSurfaceFormat m_SurfFormat; // format of pixel DWORD m_dwColorKey; // D3DCOLOR colorkey value DWORD m_dwEmptyFaceColor; // D3DCOLOR empty cubemap empty face value DWORD* m_pPalette; // pointer to D3DCOLOR palette (may be NULL) RDPalette* m_pPalObj; // DD surface pointers for locking/unlocking and GetSurf callback LPDDRAWI_DDRAWSURFACE_LCL m_pDDSLcl[RD_MAX_CLOD]; int m_cLODDDS; // 0..(n-1) count of LODs actually in the pDDS array D3DTEXTUREHANDLE m_hTex; // texture handle /////////////////////////////////////////////////////////////////////////// // // internal state and methods // /////////////////////////////////////////////////////////////////////////// BOOL m_bHasAlpha; // TRUE if texture has an alpha channel int m_cDimension; // 1,2,3 for 1D,2D,3D textures int m_cTexels[RD_MAX_CLOD][3]; // integer number of texels in each dimension float m_fTexels[RD_MAX_CLOD][3]; // float number of texels in each dimension HRESULT Initialize( LPDDRAWI_DDRAWSURFACE_LCL pLcl ); DWORD ComputePitch( LPDDRAWI_DDRAWSURFACE_LCL pLcl ) const; DWORD ComputePitch( LPDDRAWI_DDRAWSURFACE_LCL pLcl, RDSurfaceFormat SurfFormat, DWORD width, DWORD height ) const; void SetPalette( RDPalette* pPal ) { m_pPalObj = pPal; } void UpdatePalette(); BOOL Validate( void ); void ReadColor( INT32 iX, INT32 iY, INT32 iZ, INT32 iLOD, RDColor& Texel, BOOL &bColorKeyKill ); inline int GetPitch( DWORD level = 0 ) { return m_iPitch[level]; } inline LPBYTE GetBits( DWORD level = 0) { return m_pBits[level]; } inline int GetWidth() { return m_iWidth; } inline int GetHeight() { return m_iHeight; } inline int GetSamples() { return m_iSamples; } HRESULT SetLod( DWORD dwLOD ) { return S_OK; } inline RDSurfaceFormat GetSurfaceFormat() { return m_SurfFormat; } friend class RDRenderTarget; }; #define RD_STATESET_GROWDELTA 1 #define RRSTATEOVERRIDE_DWORD_BITS 32 #define RRSTATEOVERRIDE_DWORD_SHIFT 5 typedef TemplArray StateSetData; typedef StateSetData *LPStateSetData; typedef HRESULT (*PFN_DP2REFOPERATION)(RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd); typedef HRESULT (*PFN_DP2REFOPERATIONUPDATE)(RefDev *pRefDev, LPD3DHAL_DP2COMMAND* ppCmd); typedef HRESULT (*PFN_DP2REFSETRENDERSTATES)(RefDev *pRefDev, DWORD dwFvf, LPD3DHAL_DP2COMMAND pCmd, LPDWORD lpdwRuntimeRStates); typedef HRESULT (*PFN_DP2REFTEXTURESTAGESTATE)(RefDev *pRefDev, DWORD dwFvf, LPD3DHAL_DP2COMMAND pCmd); typedef HRESULT (*PFN_DP2REFSETLIGHT)(RefDev *pRefDev, LPD3DHAL_DP2COMMAND pCmd, LPDWORD pdwStride); typedef HRESULT (*PFN_DP2REFSETVERTEXSHADEDCONSTS) (RefDev *pRefDev, DWORD StartReg, DWORD dwCount, LPDWORD pData ); typedef HRESULT (*PFN_DP2REFSETPIXELSHADEDCONSTS) (RefDev *pRefDev, DWORD StartReg, DWORD dwCount, LPDWORD pData ); typedef struct _RD_STATESETFUNCTIONTBL { DWORD dwSize; // size of struct PFN_DP2REFSETRENDERSTATES pfnDp2SetRenderStates; PFN_DP2REFTEXTURESTAGESTATE pfnDp2TextureStageState; PFN_DP2REFOPERATION pfnDp2SetViewport; PFN_DP2REFOPERATION pfnDp2SetWRange; PFN_DP2REFOPERATION pfnDp2SetMaterial; PFN_DP2REFOPERATION pfnDp2SetZRange; PFN_DP2REFSETLIGHT pfnDp2SetLight; PFN_DP2REFOPERATION pfnDp2CreateLight; PFN_DP2REFOPERATION pfnDp2SetTransform; PFN_DP2REFOPERATION pfnDp2SetExtention; PFN_DP2REFOPERATION pfnDp2SetClipPlane; PFN_DP2REFOPERATION pfnDp2SetVertexShader; PFN_DP2REFSETVERTEXSHADEDCONSTS pfnDp2SetVertexShaderConsts; PFN_DP2REFOPERATION pfnDp2SetPixelShader; PFN_DP2REFSETPIXELSHADEDCONSTS pfnDp2SetPixelShaderConsts; PFN_DP2REFOPERATION pfnDp2SetStreamSource; PFN_DP2REFOPERATION pfnDp2SetIndices; PFN_DP2REFOPERATION pfnDp2MultiplyTransform; } RD_STATESETFUNCTIONTBL, *LPRD_STATESETFUNCTIONTBL; // // The device type that the RefDev should emulate // typedef enum { RDDDI_UNKNOWN = 0, RDDDI_OLDHAL = 1, RDDDI_DPHAL, RDDDI_DP2HAL, // DX6 HAL RDDDI_DX7HAL, // DX7 HAL w/out T&L, with state sets RDDDI_DX7TLHAL, RDDDI_DX8HAL, RDDDI_DX8TLHAL, RDDDI_FORCE_DWORD = 0xffffffff } RDDDITYPE; typedef struct _RRSTATEOVERRIDES { DWORD bits[D3DSTATE_OVERRIDE_BIAS >> RRSTATEOVERRIDE_DWORD_SHIFT]; } RRSTATEOVERRIDES; struct RDHOCoeffs { RDHOCoeffs() { m_pNumSegs = 0; for(unsigned i = 0; i < RD_MAX_NUMSTREAMS; m_pData[i++] = 0); } ~RDHOCoeffs() { delete[] m_pNumSegs; for(unsigned i = 0; i < RD_MAX_NUMSTREAMS; delete[] m_pData[i++]); } RDHOCoeffs& operator=(const RDHOCoeffs &coeffs); UINT m_Width; UINT m_Height; UINT m_Stride; D3DBASISTYPE m_Basis; D3DORDERTYPE m_Order; FLOAT *m_pNumSegs; BYTE *m_pData[RD_MAX_NUMSTREAMS]; UINT m_DataSize[RD_MAX_NUMSTREAMS]; }; //----------------------------------------------------------------------------- // // RefDev - Primary object for reference rasterizer. Each instance // of this corresponds to a D3D device. // // Usage is to instantiate, install RDRenderTarget (and optional RDSurface2D's), // and set state and draw primitives. // //----------------------------------------------------------------------------- class RefDev : public RDAlloc { public: friend class RDDebugMonitor; friend class RefRast; friend class RDPShader; /////////////////////////////////////////////////////////////////////////// // // public interface // /////////////////////////////////////////////////////////////////////////// RDDebugMonitor* m_pDbgMon; RefDev( LPDDRAWI_DIRECTDRAW_LCL pDDLcl, DWORD dwInterfaceType, RDDDITYPE dwDDIType, D3DCAPS8* pCaps8 ); ~RefDev( void ); LPDDRAWI_DIRECTDRAW_LCL GetDDLcl() { return m_pDDLcl; } // Methods to get embedded objects RefVP& GetVP() { return m_RefVP; } RefVM& GetVM() { return m_RefVM; } RefClipper& GetClipper() { return m_Clipper; } RefRast& GetRast() { return m_Rast; } // DDI methods HRESULT DrawPrimitives2( PUINT8 pUMVtx, UINT16 dwStride, DWORD dwFvf, DWORD dwNumVertices, LPD3DHAL_DP2COMMAND *ppCmd, LPDWORD lpdwRStates ); // Dp2 token handling functions HRESULT Dp2RecRenderStates(DWORD dwFvf, LPD3DHAL_DP2COMMAND pCmd, LPDWORD lpdwRuntimeRStates); HRESULT Dp2RecTextureStageState(DWORD dwFvf, LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2RecViewport(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2RecWRange(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2RecMaterial(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2RecZRange(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2RecSetLight(LPD3DHAL_DP2COMMAND pCmd, LPDWORD pdwStride); HRESULT Dp2RecCreateLight(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2RecTransform(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2RecExtention(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2RecClipPlane(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2RecSetVertexShader(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2RecSetVertexShaderConsts(DWORD StartReg, DWORD dwCount, LPDWORD pData); HRESULT Dp2RecSetPixelShader(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2RecSetPixelShaderConsts(DWORD StartReg, DWORD dwCount, LPDWORD pData); HRESULT Dp2RecSetStreamSource(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2RecSetIndices(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2SetRenderStates(DWORD dwFvf, LPD3DHAL_DP2COMMAND pCmd, LPDWORD lpdwRuntimeRStates); HRESULT Dp2SetTextureStageState(DWORD dwFvf, LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2SetViewport(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2SetWRange(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2SetMaterial(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2SetZRange(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2SetLight(LPD3DHAL_DP2COMMAND pCmd, PDWORD pdwStride); HRESULT Dp2CreateLight(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2SetTransform(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2MultiplyTransform(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2SetExtention(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2SetRenderTarget(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2SetClipPlane(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2DrawPrimitive(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2DrawPrimitive2(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2DrawIndexedPrimitive(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2DrawIndexedPrimitive2(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2DrawClippedTriFan(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2CreateVertexShader(DWORD handle, DWORD dwDeclSize, LPDWORD pDecl, DWORD dwCodeSize, LPDWORD pCode); HRESULT Dp2DeleteVertexShader(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2SetVertexShader(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2SetVertexShaderConsts(DWORD StartReg, DWORD dwCount, LPDWORD pData); HRESULT Dp2SetStreamSource(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2SetStreamSourceUM(LPD3DHAL_DP2COMMAND pCmd, PUINT8 pUMVtx ); HRESULT Dp2SetIndices(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2CreatePixelShader(DWORD handle, DWORD dwCodeSize, LPDWORD pCode); HRESULT Dp2DeletePixelShader(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2SetPixelShader(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2SetPixelShaderConsts(DWORD StartReg, DWORD dwCount, LPDWORD pData); HRESULT Dp2SetPalette(LPD3DHAL_DP2COMMAND pCmd); HRESULT Dp2UpdatePalette(LPD3DHAL_DP2UPDATEPALETTE pUP, PALETTEENTRY *pEntries); HRESULT Dp2SetTexLod(LPD3DHAL_DP2COMMAND pCmd); // StateSet related functions void SetRecStateFunctions(void); void SetSetStateFunctions(void); HRESULT BeginStateSet(DWORD dwHandle); HRESULT EndStateSet(void); HRESULT ExecuteStateSet(DWORD dwHandle); HRESULT DeleteStateSet(DWORD dwHandle); HRESULT CaptureStateSet(DWORD dwHandle); HRESULT CreateStateSet(DWORD dwHandle, D3DSTATEBLOCKTYPE sbType); HRESULT RecordAllState( DWORD dwHandle ); HRESULT RecordVertexState( DWORD dwHandle ); HRESULT RecordPixelState( DWORD dwHandle ); HRESULT RecordStates(PUINT8 pData, DWORD dwSize); HRESULT RecordLastState(LPD3DHAL_DP2COMMAND pCmd, DWORD dwUnitSize); LPRD_STATESETFUNCTIONTBL pStateSetFuncTbl; // Interface style BOOL IsInterfaceDX6AndBefore() {return (m_dwInterfaceType <= 2);} BOOL IsInterfaceDX7AndBefore() {return (m_dwInterfaceType <= 3);} // DriverStyle BOOL IsDriverDX6AndBefore() { return ((m_dwDDIType <= RDDDI_DP2HAL) && (m_dwDDIType > 0)); } BOOL IsDriverDX7AndBefore() { return ((m_dwDDIType <= RDDDI_DX7TLHAL) && (m_dwDDIType > 0)); } RDDDITYPE GetDDIType() { return m_dwDDIType; } // Last Pixel State void StoreLastPixelState(BOOL bStore); // RenderTarget control void SetRenderTarget( RDRenderTarget* pRenderTarget ); RDRenderTarget* GetRenderTarget( void ); // state management functions void SetRenderState( DWORD dwState, DWORD dwValue ); void SetTextureStageState( DWORD dwStage, DWORD dwStageState, DWORD dwValue ); void SceneCapture( DWORD dwFlags ); // texture management functions BOOL TextureCreate ( LPD3DTEXTUREHANDLE phTex, RDSurface2D** ppTexture ); BOOL TextureDestroy ( D3DTEXTUREHANDLE hTex ); DWORD TextureGetSurf( D3DTEXTUREHANDLE hTex ); // rendering functions HRESULT Clear(LPD3DHAL_DP2COMMAND pCmd); HRESULT BeginRendering( void ); HRESULT EndRendering( void ); HRESULT UpdateRastState( void ); DWORD m_dwRastFlags; // rasterizer-core specific flags #define RDRF_MULTISAMPLE_CHANGED (1L<<0) #define RDRF_PIXELSHADER_CHANGED (1L<<1) #define RDRF_LEGACYPIXELSHADER_CHANGED (1L<<2) #define RDRF_TEXTURESTAGESTATE_CHANGED (1L<<3) // Method to convert FVF vertices into the internal RDVertex. Used for // TLVertex rendering and legacy driver models. void FvfToRDVertex( PUINT8 pVtx, GArrayT& dstArray, DWORD dwFvf, DWORD dwStride, UINT cVertices ); // Rasterizer functions void DrawPoint( RDVertex* pvV0 ); void DrawLine( RDVertex* pvV0, RDVertex* pvV1, RDVertex* pvVFlat = NULL ); void DrawTriangle( RDVertex* pvV0, RDVertex* pvV1, RDVertex* pvV2, WORD wFlags = D3DTRIFLAG_EDGEENABLETRIANGLE ); HRESULT DrawOnePrimitive( GArrayT& VtxArray, DWORD dwStartVertex, D3DPRIMITIVETYPE PrimType, UINT cVertices ); HRESULT DrawOneIndexedPrimitive( GArrayT& VtxArray, int StartVertexIndex, LPWORD pIndices, DWORD StartIndex, UINT cIndices, D3DPRIMITIVETYPE PrimType ); HRESULT DrawOneIndexedPrimitive( GArrayT& VtxArray, int StartVertexIndex, LPDWORD pIndices, DWORD StartIndex, UINT cIndices, D3DPRIMITIVETYPE PrimType ); HRESULT DrawOneEdgeFlagTriangleFan( GArrayT& VtxArray, UINT cVertices, UINT32 dwEdgeFlags ); // // these are used to facilitate the way refdev is used in the D3D runtime // // functions to manipulate current set of texture int GetCurrentTextureMaps( D3DTEXTUREHANDLE* phTex, RDSurface2D** pTex ); BOOL SetTextureMap( D3DTEXTUREHANDLE hTex, RDSurface2D* pTex ); // // T&L Hal specific functions // HRESULT ProcessPrimitive( D3DPRIMITIVETYPE primType, DWORD dwStartVertex,// Index of the start vertex DWORD cVertices, DWORD dwStartIndex, DWORD cIndices ); HRESULT ProcessPrimitiveVVM( D3DPRIMITIVETYPE primType, DWORD dwStartVertex, DWORD cVertices, DWORD dwStartIndex, DWORD cIndices ); HRESULT ProcessBSpline( DWORD dwOffW, DWORD dwOffH, DWORD dwWidth, DWORD dwHeight, DWORD dwStride, DWORD order, FLOAT *pPrimSegments); HRESULT ProcessBezier ( DWORD dwOffW, DWORD dwOffH, DWORD dwWidth, DWORD dwHeight, DWORD dwStride, DWORD order, FLOAT *pPrimSegments, bool bDegenerate ); HRESULT ProcessCatRomSpline ( DWORD dwOffW, DWORD dwOffH, DWORD dwWidth, DWORD dwHeight, DWORD dwStride, FLOAT *pPrimSegments); HRESULT ProcessTessPrimitive( LPD3DHAL_DP2DRAWPRIMITIVE pDP ); HRESULT ProcessTessIndexedPrimitive( LPD3DHAL_DP2DRAWINDEXEDPRIMITIVE pDP ); HRESULT DrawTessQuad( const RDBSpline &Surf, DWORD dwOffW, DWORD dwOffH, DWORD dwStride, const unsigned *m, const unsigned *n, double u0, double v0, double u1, double v1, double tu0, double tv0, double tu1, double tv1, bool bDegenerate ); HRESULT DrawTessTri( const RDBSpline &Surf, DWORD dwOffW, DWORD dwOffH, DWORD dwStride, const unsigned *m, const unsigned *n, double u0, double v0, double u1, double v1, double u2, double v2, double tu0, double tv0, double tu1, double tv1, double tu2, double tv2, bool bDegenerate0, bool bDegenerate1, bool bDegenerate2 ); HRESULT DrawNPatch( const RDNPatch &Patch, DWORD dwStride, const unsigned *m, const unsigned *n, unsigned segs ); HRESULT ConvertLinearTriBezierToRectBezier(DWORD dwDataType, const BYTE *B, DWORD dwStride, BYTE *Q); HRESULT ConvertCubicTriBezierToRectBezier(DWORD dwDataType, const BYTE *B, DWORD dwStride, BYTE *Q); HRESULT ConvertQuinticTriBezierToRectBezier(DWORD dwDataType, const BYTE *B, DWORD dwStride, BYTE *Q); HRESULT SetupStrides(); HRESULT UpdateTLState(); HRESULT UpdateClipper(); HRESULT DrawDX8Prim( LPD3DHAL_DP2DRAWPRIMITIVE pDP ); HRESULT DrawDX8Prim2( LPD3DHAL_DP2DRAWPRIMITIVE2 pDP ); HRESULT DrawRectPatch( LPD3DHAL_DP2DRAWRECTPATCH pDP ); HRESULT DrawTriPatch( LPD3DHAL_DP2DRAWTRIPATCH pDP ); HRESULT DrawDX8IndexedPrim( LPD3DHAL_DP2DRAWINDEXEDPRIMITIVE pDIP ); HRESULT DrawDX8IndexedPrim2( LPD3DHAL_DP2DRAWINDEXEDPRIMITIVE2 pDIP ); HRESULT DrawDX8ClippedTriFan( LPD3DHAL_CLIPPEDTRIANGLEFAN pDIP ); inline RDVStream& GetVStream( DWORD index ) { return m_VStream[index]; } inline HRESULT GrowTLVArray( DWORD dwNumVerts ) { return m_TLVArray.Grow( dwNumVerts ); } inline GArrayT& GetTLVArray() { return m_TLVArray; } private: /////////////////////////////////////////////////////////////////////////// // // internal state and methods // /////////////////////////////////////////////////////////////////////////// //------------------------------------------------------------------------- // Embedded Objects //------------------------------------------------------------------------- RefVP m_RefVP; // The fixed function T&L object RefVM m_RefVM; // The programmable vertex machine object RefClipper m_Clipper; // Clipper object RefRast m_Rast; // Rasterizer object //------------------------------------------------------------------------- // state //------------------------------------------------------------------------- // Caps struct, potentially modified from static caps settings. Ref code // will behave according to settings of some of the caps in this struct. D3DCAPS8 m_Caps8; // DDraw Local, needed for the new texture handles from DX7 onwards LPDDRAWI_DIRECTDRAW_LCL m_pDDLcl; // This is obtained from CONTEXTCREATE->ddrval, indicates // what kind of emulation (DX3, DX5, DX6 or DX7) the driver should do. RDDDITYPE m_dwDDIType; // This is obtained from CONTEXTCREATE->dwhContext, indicates // which D3D Device interface called the driver. DWORD m_dwInterfaceType; // save area for floating point unit control WORD m_wSaveFP; // TRUE if in begin/end primitive sequence BOOL m_bInBegin; // TRUE if in rendering point sprite triangles BOOL m_bPointSprite; // render target (color & Z buffer) RDRenderTarget* m_pRenderTarget; FLOAT m_fWBufferNorm[2]; // { Wnear, 1/(Wfar-Wnear) } to normalize W buffer value // D3D renderstate union { DWORD m_dwRenderState[D3DHAL_MAX_RSTATES]; FLOAT m_fRenderState[D3DHAL_MAX_RSTATES]; }; // State Override flags RRSTATEOVERRIDES m_renderstate_override; // Palette handles GArrayT m_PaletteHandleArray; // texture state - per-stage state and pointer to associated texture int m_cActiveTextureStages; // count of active texture stages (range 0..D3DHAL_TSS_MAXSTAGES) DWORD m_ReferencedTexCoordMask; // which texture coordinate sets are referenced RDSurface2D* m_pTexture[D3DHAL_TSS_MAXSTAGES]; // texture maps associated with texture stages union { DWORD m_dwTextureStageState[D3DHAL_TSS_MAXSTAGES][D3DTSS_MAX]; // state array (unsigned) FLOAT m_fTextureStageState[D3DHAL_TSS_MAXSTAGES][D3DTSS_MAX]; // state array (float) RDTextureStageState m_TextureStageState[D3DHAL_TSS_MAXSTAGES]; }; DWORD* m_pTextureStageState[D3DHAL_TSS_MAXSTAGES]; // to speed GetTSS BOOL m_bOverrideTCI; DWORD m_dwTexArrayLength; // Vertex and Index streams // The extra VStream is for the Tesselator generated data. RDVStream m_VStream[RD_MAX_NUMSTREAMS + 1]; RDIStream m_IndexStream; // Buffer to store transformed vertices GArrayT m_TLVArray; // Vertex shader state GArrayT m_VShaderHandleArray; RDVShader m_FVFShader; // Declaration for the legacy (FVF) // shader DWORD m_CurrentVShaderHandle; RDVShader* m_pCurrentVShader; UINT64 m_qwFVFOut; // Desired FVF for the output // vertices // Coefficient storage for HOS GArrayT m_HOSCoeffs; // Primitive information D3DPRIMITIVETYPE m_primType; // Current primitive being drawn DWORD m_dwNumVertices; // Number of vertices to process DWORD m_dwStartVertex; DWORD m_dwNumIndices; DWORD m_dwStartIndex; // Last state DWORD m_LastState; // Array of StateSets, which are in turn implemented with TemplArray as // TemplArray StateSetData TemplArray m_pStateSets; // pixel shader state DWORD m_CurrentPShaderHandle; GArrayT m_PShaderHandleArray; // Buffer used to process clear rects GArrayT m_ClearRectBuffer; //------------------------------------------------------------------------- // methods //------------------------------------------------------------------------- // refrasti.cpp HRESULT GrowTexArray( DWORD dwHandle ); HRESULT SetTextureHandle( int iStage, DWORD dwHandle ); void MapTextureHandleToDevice( int iStage ); void UpdateActiveTexStageCount( void ); RDSurface2D* MapHandleToTexture( D3DTEXTUREHANDLE hTex ); // MapLegcy.cpp void MapLegacyTextureBlend( void ); void MapLegacyTextureFilter( void ); // primfns.cpp HRESULT GrowLightArray(const DWORD dwIndex); // pixel shader handle manipulation inline RDPShader* GetPShader( DWORD dwHandle ) { if( m_PShaderHandleArray.IsValidIndex( dwHandle ) ) return m_PShaderHandleArray[dwHandle].m_pShader; return NULL; } // drawgrid.cpp HRESULT LinkTessellatorOutput(); HRESULT LinkCachedTessellatorOutput(DWORD Handle, BYTE **pTempData); void UnlinkTessellatorOutput(); void UnlinkCachedTessellatorOutput(BYTE **pTempData); public: /////////////////////////////////////////////////////////////////////////// // // methods used by refdev objects to get at device state // /////////////////////////////////////////////////////////////////////////// inline DWORD* GetRS( void ) { return m_dwRenderState; } inline FLOAT* GetRSf( void ) { return m_fRenderState; } inline DWORD* GetTSS( DWORD Stage ) { return m_pTextureStageState[Stage]; } inline FLOAT* GetTSSf( DWORD Stage ) { return (FLOAT*)m_pTextureStageState[Stage]; } inline BOOL ColorKeyEnabled( void ) { return m_dwRenderState[D3DRENDERSTATE_COLORKEYENABLE] || m_dwRenderState[D3DRENDERSTATE_COLORKEYBLENDENABLE]; } inline D3DCAPS8* GetCaps8( void ) { return &m_Caps8; } }; //------------------------------------------------------------------------- // DXTn compressed texture formats //------------------------------------------------------------------------- // number of DXT compression formats #define NUM_DXT_FORMATS 5 // number of pixels in block #define DXT_BLOCK_PIXELS 16 // DXT block size array extern int g_DXTBlkSize[]; typedef struct { BYTE rgba[4]; } DXT_COLOR; typedef WORD RGB565; // packed color typedef DWORD PIXBM; // 2 BPP bitmap typedef struct { RGB565 rgb0; // color for index 0 RGB565 rgb1; // color for index 1 PIXBM pixbm; // pixel bitmap } DXTBlockRGB; typedef struct { WORD alphabm[4]; // alpha bitmap at 4 BPP DXTBlockRGB rgb; // color block } DXTBlockAlpha4; typedef struct { BYTE alpha0; // alpha for index 0 BYTE alpha1; // alpha for index 1 BYTE alphabm[6]; // alpha bitmap at 3 BPP DXTBlockRGB rgb; // color block } DXTBlockAlpha3; void DecodeBlockRGB (DXTBlockRGB *pblockSrc, DXT_COLOR colorDst[DXT_BLOCK_PIXELS]); void DecodeBlockAlpha4(DXTBlockAlpha4 *pblockSrc, DXT_COLOR colorDst[DXT_BLOCK_PIXELS]); void DecodeBlockAlpha3(DXTBlockAlpha3 *pblockSrc, DXT_COLOR colorDst[DXT_BLOCK_PIXELS]); /////////////////////////////////////////////////////////////////////////////// #endif // _REFDEV_HPP