|
|
///////////////////////////////////////////////////////////////////////////////
// Copyright (C) Microsoft Corporation, 2000.
//
// refdev.hpp
//
// Direct3D Reference Device - Main Header File
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _REFDEV_HPP
#define _REFDEV_HPP
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <windows.h>
#pragma warning( disable: 4056) // fp constant
#pragma warning( disable: 4244) // fp DOUBLE->FLOAT
#include <ddraw.h>
#include <ddrawi.h>
#include <d3dhal.h>
#include "d3d8ddi.h"
//@@BEGIN_MSINTERNAL
#include "d3d8p.h"
//@@END_MSINTERNAL
#include <rdcomm.hpp>
// forward declarations
class D3DDebugMonitor; class RDDebugMonitor; class RDSurfaceManager; class RDSurface2D; class RDSurface; class RDRenderTarget; class RDTextureStageState; class RDBSpline; class RDNPatch; class RefDev;
#include <rddmon.hpp>
#include <templarr.hpp>
#include <vshader.h>
#include <vstream.h>
#include <reftnl.hpp>
#include <refrast.hpp>
#include <pshader.h>
//-----------------------------------------------------------------------------
//
// 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<RDSurfaceHandle> 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<UINT8> 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<RDVertex>& 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<RDVertex>& VtxArray, DWORD dwStartVertex, D3DPRIMITIVETYPE PrimType, UINT cVertices ); HRESULT DrawOneIndexedPrimitive( GArrayT<RDVertex>& VtxArray, int StartVertexIndex, LPWORD pIndices, DWORD StartIndex, UINT cIndices, D3DPRIMITIVETYPE PrimType ); HRESULT DrawOneIndexedPrimitive( GArrayT<RDVertex>& VtxArray, int StartVertexIndex, LPDWORD pIndices, DWORD StartIndex, UINT cIndices, D3DPRIMITIVETYPE PrimType ); HRESULT DrawOneEdgeFlagTriangleFan( GArrayT<RDVertex>& 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<RDVertex>& 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<RDPaletteHandle> 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<RDVertex> m_TLVArray;
// Vertex shader state
GArrayT<RDVShaderHandle> 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<RDHOCoeffs> 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<UINT8> StateSetData
TemplArray<LPStateSetData> m_pStateSets;
// pixel shader state
DWORD m_CurrentPShaderHandle; GArrayT<RDPShaderHandle> m_PShaderHandleArray;
// Buffer used to process clear rects
GArrayT<BYTE> 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
|