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.
 
 
 
 
 
 

1132 lines
40 KiB

///////////////////////////////////////////////////////////////////////////////
// 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