windows-nt/Source/XPSP1/NT/multimedia/directx/dxg/d3d8/inc/d3di.hpp
2020-09-26 16:20:57 +08:00

1376 lines
59 KiB
C++

/*==========================================================================;
*
* Copyright (C) 1995-1997 Microsoft Corporation. All Rights Reserved.
*
* File: d3di.hpp
* Content: Direct3D internal include file
*
*
***************************************************************************/
#ifndef _D3DI_HPP
#define _D3DI_HPP
// Allow fast path
#define FAST_PATH
#include "ddrawp.h"
#include "d3d8p.h"
#include "d3dmem.h"
#if !defined(BUILD_DDDDK)
extern "C" {
#include "ddrawi.h"
};
#include "lists.hpp"
#include <d3ditype.h>
#include <d3dutil.h>
#include <d3dfe.hpp>
#include <vshader.hpp>
#include <pshader.hpp>
#include <rtdmon.hpp>
#include "ddi.h"
//--------------------------------------------------------------------
const DWORD __INIT_VERTEX_NUMBER = 1024;// Initial number of vertices in TL and
// clip flag buffers
//--------------------------------------------------------------------
/*
* Registry defines
*/
#define RESPATH "Software\\Microsoft\\Direct3D\\Drivers"
#define RESPATH_D3D "Software\\Microsoft\\Direct3D"
#define STATS_FONT_FACE "Terminal"
#define STATS_FONT_SIZE 9
extern HINSTANCE hGeometryDLL;
/*
* CPU family and features flags
*/
extern DWORD dwCPUFamily, dwCPUFeatures;
extern char szCPUString[];
// MMX available
#define D3DCPU_MMX 0x00000001L
// FCOMI and CMOV are both supported
#define D3DCPU_FCOMICMOV 0x00000002L
// Reads block until satisfied
#define D3DCPU_BLOCKINGREAD 0x00000004L
// Extended 3D support available
#define D3DCPU_X3D 0x00000008L
// Pentium II CPU
#define D3DCPU_PII 0x000000010L
// Streaming SIMD Extensions (aka Katmai) CPU
#define D3DCPU_SSE 0x000000020L
// Streaming SIMD2 Extensions (aka Willamete) CPU
#define D3DCPU_WLMT 0x000000040L
#define DEFAULT_GAMMA DTOVAL(1.4)
/*
INDEX_BATCH_SCALE is the constant which is used by DrawIndexedPrim
to deterimine if the number of primitives being drawn is small
relative to the number of vertices being passed. If it is then
the prims are dereferenced in batches and sent to DrawPrim.
*/
#define INDEX_BATCH_SCALE 2
#endif // BUILD_DDDDK
#if !defined(BUILD_DDDDK)
class CD3DHal;
class CStateSets;
class CVertexVM;
class CBaseTexture;
class CD3DDDI;
typedef CD3DDDI* LPD3DDDI;
typedef class CD3DHal *LPD3DHAL;
typedef class DIRECT3DLIGHTI *LPDIRECT3DLIGHTI;
BOOL ValidatePixelShaderInternal( const DWORD* pCode, const D3DCAPS8* pCaps );
BOOL ValidateVertexShaderInternal( const DWORD* pCode, const DWORD* pDecl,
const D3DCAPS8* pCaps );
#include "d3dhalp.h"
//-----------------------------------------------------------------------------
// Helper class to hold vertex element pointers and strides
//
class CVertexPointer
{
public:
BYTE* pData[__NUMELEMENTS];
static UINT Stride[__NUMELEMENTS];
static UINT NumUsedElements;
static UINT DataType[__NUMELEMENTS];
CVertexPointer() {}
// Copy constructor
CVertexPointer(CVertexPointer& vp)
{
for (UINT i=0; i < NumUsedElements; i++)
{
pData[i] = vp.pData[i];
}
}
// Copy constructor
void operator=(CVertexPointer& vp)
{
for (UINT i=0; i < NumUsedElements; i++)
{
pData[i] = vp.pData[i];
}
}
void SetVertex(CVertexPointer& base, UINT index)
{
for (UINT i=0; i < NumUsedElements; i++)
pData[i] = base.pData[i] + index * Stride[i];
}
CVertexPointer& operator++(int)
{
for (UINT i=0; i < NumUsedElements; i++)
pData[i] += Stride[i];
return *this;
}
};
//-----------------------------------------------------------------------------
// Class to convert NPatches to RTPatches
//
class CNPatch2TriPatch
{
public:
CNPatch2TriPatch();
~CNPatch2TriPatch();
void MakeRectPatch(const CVertexPointer& pV0,
const CVertexPointer& pV1,
const CVertexPointer& pV2);
CVStream m_InpStream[__NUMELEMENTS]; // Original vertex streams
CTLStream* m_pOutStream[__NUMELEMENTS]; // Computed output vertex streams
BYTE* m_pInpStreamMem[__NUMELEMENTS]; // Input stream memory
BYTE* m_pOutStreamMem[__NUMELEMENTS]; // Output stream memory
CVertexPointer m_InpVertex; // Pointers to elements of the first input vertex
CVertexPointer m_OutVertex; // Pointers to elements of the first output vertex
UINT m_PositionIndex; // Index in vertex element array
UINT m_NormalIndex; // Index in vertex element array
D3DORDERTYPE m_PositionOrder;
D3DORDERTYPE m_NormalOrder;
UINT m_FirstVertex; // Index of the first vertex in the
// output buffer
DWORD m_bNormalizeNormals;
};
//-----------------------------------------------------------------------------
// Function to compute lighting
//
typedef struct _LIGHT_VERTEX_FUNC_TABLE
{
LIGHT_VERTEX_FUNC pfnDirectional;
LIGHT_VERTEX_FUNC pfnPointSpot;
// Used in multi-loop pipeline
PFN_LIGHTLOOP pfnDirectionalFirst;
PFN_LIGHTLOOP pfnDirectionalNext;
PFN_LIGHTLOOP pfnPointSpotFirst;
PFN_LIGHTLOOP pfnPointSpotNext;
} LIGHT_VERTEX_FUNC_TABLE;
//---------------------------------------------------------------------
class DIRECT3DLIGHTI : public CD3DBaseObj
{
public:
DIRECT3DLIGHTI() {m_LightI.flags = 0;} // VALID bit is not set
HRESULT SetInternalData();
BOOL Enabled() {return (m_LightI.flags & D3DLIGHTI_ENABLED);}
// TRUE is we need to send the light to the driver when switching
// to the hardware vertex processing mode
BOOL DirtyForDDI() {return (m_LightI.flags & D3DLIGHTI_UPDATEDDI);}
void SetDirtyForDDI() {m_LightI.flags |= D3DLIGHTI_UPDATEDDI;}
void ClearDirtyForDDI() {m_LightI.flags &= ~D3DLIGHTI_UPDATEDDI;}
// TRUE is we need to send the "enable" state of the light to the driver
// when switching to the hardware vertex processing mode
BOOL EnableDirtyForDDI() {return (m_LightI.flags & D3DLIGHTI_UPDATE_ENABLE_DDI);}
void SetEnableDirtyForDDI() {m_LightI.flags |= D3DLIGHTI_UPDATE_ENABLE_DDI;}
void ClearEnableDirtyForDDI() {m_LightI.flags &= ~D3DLIGHTI_UPDATE_ENABLE_DDI;}
LIST_MEMBER(DIRECT3DLIGHTI) m_List; // Active light list member
D3DLIGHT8 m_Light;
D3DI_LIGHT m_LightI;
};
//---------------------------------------------------------------------
struct CPalette : public CD3DBaseObj
{
CPalette()
{
m_dirty = TRUE;
}
BOOL m_dirty;
PALETTEENTRY m_pEntries[256];
};
#if DBG
//---------------------------------------------------------------------
struct CRTPatchValidationInfo : public CD3DBaseObj
{
CRTPatchValidationInfo()
{
m_ShaderHandle = __INVALIDHANDLE;
}
DWORD m_ShaderHandle;
};
#endif // DBG
//---------------------------------------------------------------------
//
// Bits for Runtime state flags (m_dwRuntimeFlags in CD3DBase)
//
// This bit set if UpdateManagedTextures() needs to be called
const DWORD D3DRT_NEED_TEXTURE_UPDATE = 1 << 1;
// We are in recording state set mode
const DWORD D3DRT_RECORDSTATEMODE = 1 << 2;
// We are in execution state set mode
// In this mode the front-and executes recorded states but does not pass
// them to the driver (the states will be passed using a set state handle)
const DWORD D3DRT_EXECUTESTATEMODE = 1 << 3;
//
const DWORD D3DRT_LOSTSURFACES = 1 << 4;
// Set when D3DRS_SOFTWAREVERTEXPROCESSING is TRUE
const DWORD D3DRT_RSSOFTWAREPROCESSING = 1 << 5;
// Set when device does not support point sprites
const DWORD D3DRT_DOPOINTSPRITEEMULATION = 1 << 6;
// Set when input stream has point size. It is computed in the SetVertexShaderI
const DWORD D3DRT_POINTSIZEINVERTEX = 1 << 7;
// Set when D3DRS_POINTSIZE != 1.0
const DWORD D3DRT_POINTSIZEINRS = 1 << 8;
// Set when
// - shader has been changed.
// - when ForceFVFRecompute has been called
const DWORD D3DRT_SHADERDIRTY = 1 << 9;
// This bit set if UpdateDirtyStreams() needs to be called
const DWORD D3DRT_NEED_VB_UPDATE = 1 << 11;
// This bit set if we need to update vertex shader constants in the driver
const DWORD D3DRT_NEED_VSCONST_UPDATE = 1 << 12;
// Set if device can handle only 2 floats per texture coord set
const DWORD D3DRT_ONLY2FLOATSPERTEXTURE = 1 << 13;
// Set if device cannot handle projected textures, so we need to emulate them
const DWORD D3DRT_EMULATEPROJECTEDTEXTURE = 1 << 14;
// Set if a directional light is present in the active light list
const DWORD D3DRT_DIRECTIONALIGHTPRESENT = 1 << 15;
// Set if a point/spot light is present in the active light list
const DWORD D3DRT_POINTLIGHTPRESENT = 1 << 16;
// Set if current primitive is user memory primitive
const DWORD D3DRT_USERMEMPRIMITIVE = 1 << 17;
// Set if reg key to disallow Non-Versioned (FF.FF) pixel shaders was set on device create
const DWORD D3DRT_DISALLOWNVPSHADERS = 1 << 18;
// Set when MaxPointSize in the device is greater than 1.0
const DWORD D3DRT_SUPPORTSPOINTSPRITES = 1 << 19;
// Set when we need to do NPatch to RTPatch conversion
const DWORD D3DRT_DONPATCHCONVERSION = 1 << 20;
const DWORD D3DRT_POINTSIZEPRESENT = D3DRT_POINTSIZEINRS |
D3DRT_POINTSIZEINVERTEX;
//---------------------------------------------------------------------
//
// Bits for D3DFRONTEND flags (dwFEFlags in CD3DHal)
//
const DWORD D3DFE_WORLDMATRIX_DIRTY = 1 << 0; // World matrix dirty bits
const DWORD D3DFE_TLVERTEX = 1 << 5;
const DWORD D3DFE_PROJMATRIX_DIRTY = 1 << 8;
const DWORD D3DFE_VIEWMATRIX_DIRTY = 1 << 9;
// Set when we need to check world-view matrix for orthogonality
const DWORD D3DFE_NEEDCHECKWORLDVIEWVMATRIX = 1 << 10;
// Set when some state has been changed and we have to go through the slow path
// to update state.
// Currently the bit is set when one of the following bits is set:
// D3DFE_PROJMATRIX_DIRTY
// D3DFE_VIEWMATRIX_DIRTY
// D3DFE_WORLDMATRIX_DIRTY
// D3DFE_VERTEXBLEND_DIRTY
// D3DFE_LIGHTS_DIRTY
// D3DFE_MATERIAL_DIRTY
// D3DFE_FVF_DIRTY
// D3DFE_CLIPPLANES_DIRTY
// OutputFVF has been changed
//
const DWORD D3DFE_FRONTEND_DIRTY = 1 << 11;
const DWORD D3DFE_NEED_TRANSFORM_LIGHTS = 1 << 14;
const DWORD D3DFE_MATERIAL_DIRTY = 1 << 15;
const DWORD D3DFE_CLIPPLANES_DIRTY = 1 << 16;
const DWORD D3DFE_LIGHTS_DIRTY = 1 << 18;
// This bit is set when vertex blending state is dirty
const DWORD D3DFE_VERTEXBLEND_DIRTY = 1 << 19;
// Set if the Current Transformation Matrix has been changed
// Reset when frustum planes in the model space have been computed
const DWORD D3DFE_FRUSTUMPLANES_DIRTY = 1 << 20;
const DWORD D3DFE_WORLDVIEWMATRIX_DIRTY = 1 << 21;
const DWORD D3DFE_FVF_DIRTY = 1 << 22;
// This bit set if mapping DX6 texture blend modes to renderstates is desired
const DWORD D3DFE_MAP_TSS_TO_RS = 1 << 24;
const DWORD D3DFE_INVWORLDVIEWMATRIX_DIRTY = 1 << 25;
// This bit set if texturing is disabled
const DWORD D3DFE_DISABLE_TEXTURES = 1 << 28;
// Clip matrix is used to transform user clipping planes
// to the clipping space
const DWORD D3DFE_CLIPMATRIX_DIRTY = 1 << 29;
// HAL supports Transformation and Lighting
const DWORD D3DFE_TLHAL = 1 << 30;
const DWORD D3DFE_TRANSFORM_DIRTY = D3DFE_PROJMATRIX_DIRTY |
D3DFE_VIEWMATRIX_DIRTY |
D3DFE_WORLDMATRIX_DIRTY |
D3DFE_VERTEXBLEND_DIRTY;
// Are we in a scene?
const DWORD D3DDEVBOOL_HINTFLAGS_INSCENE = 1 << 0;
// Means the FPU is already in preferred state.
const DWORD D3DDEVBOOL_HINTFLAGS_FPUSETUP = 1 << 3;
//---------------------------------------------------------------------
// Bits for transform.dwFlags
//
//---------------------------------------------------------------------
typedef struct _D3DFE_TRANSFORM
{
D3DMATRIXI proj;
D3DMATRIXI mPC; // Mproj * Mclip
D3DMATRIXI mVPCI; // Inverse Mview * PC, used to transform clipping planes
D3DVECTORH userClipPlane[D3DMAXUSERCLIPPLANES];
} D3DFE_TRANSFORM;
typedef void (*D3DFEDestroyProc)(LPD3DHAL lpD3DDevI);
//---------------------------------------------------------------------
#ifdef _IA64_ // Removes IA64 compiler alignment warnings
#pragma pack(16)
#endif
#ifdef _AXP64_ // Removes AXP64 compiler alignment warnings
#pragma pack(16)
#endif
// We modify the compiler generated VTable for CD3DHal object. To make
// life easy, all virtual functions are defined in CD3DHal. Also since
// DEVICEI has multiple inheritance, there are more than 1 VTable.
// Currently we assume that it only inherits from IDirect3DDevice7 and
// D3DFE_PROCESSVERTICES and, in that order! Thus IDirect3DDevice7 and
// CD3DHal share the same vtable. This is the VTable we copy and
// modify. The define below is the total entries in this vtable. It is the
// sum of the methods in IDirect3DDevice7 (incl. IUnknown) (49) and all the
// virtual methods in CD3DHal ()
#define D3D_NUM_API_FUNCTIONS (49)
#define D3D_NUM_VIRTUAL_FUNCTIONS (D3D_NUM_API_FUNCTIONS+38)
// These constants are based on the assumption that rsVec array is an array
// of 32-bit intergers
const D3D_RSVEC_SHIFT = 5; // log2(sizeof(DWORD)*8);
const D3D_RSVEC_MASK = sizeof(DWORD) * 8 - 1;
//-----------------------------------------------------------------------------
// The class is used to maintain a packed array of bits
//
class CPackedBitArray
{
public:
CPackedBitArray() {m_pArray = NULL;}
~CPackedBitArray() {delete m_pArray;}
// This function could be called to re-allocate the array. All data from the
// previous array is copied into new array
HRESULT Init(UINT size)
{
// Size in bytes
UINT allocsize = ((size + D3D_RSVEC_MASK) >> D3D_RSVEC_SHIFT) << 2;
DWORD* pNew = (DWORD*)new BYTE[allocsize];
if (pNew == NULL)
return E_OUTOFMEMORY;
memset(pNew, 0, allocsize);
if (m_pArray)
{
// User asks to re-allocate the array
memcpy(pNew, m_pArray, m_sizeInBytes);
delete m_pArray;
}
m_pArray = pNew;
m_size = size;
m_sizeInBytes = allocsize;
return S_OK;
}
UINT GetSize() {return m_size;}
void ClearBit(DWORD index)
{
#if DBG
CheckIndex(index);
#endif
m_pArray[index >> D3D_RSVEC_SHIFT] &= ~(1 << (index & D3D_RSVEC_MASK));
}
void SetBit(DWORD index)
{
#if DBG
CheckIndex(index);
#endif
m_pArray[index >> D3D_RSVEC_SHIFT] |= 1 << (index & D3D_RSVEC_MASK);
}
BOOL IsBitSet(DWORD index)
{
#if DBG
CheckIndex(index);
#endif
return (m_pArray[index >> D3D_RSVEC_SHIFT] &
(1ul << (index & D3D_RSVEC_MASK))) != 0;
}
private:
DWORD* m_pArray;
UINT m_sizeInBytes;
UINT m_size; // Number of elements (bits) in the array
#if DBG
void CheckIndex(UINT index);
#endif // DBG
};
//-----------------------------------------------------------------------------
// Map DX8 texture filter enum to D3DTEXTUREMAGFILTER
const texf2texfg[] = {
D3DTFG_POINT, // D3DTEXF_NONE = 0,
D3DTFG_POINT, // D3DTEXF_POINT = 1,
D3DTFG_LINEAR, // D3DTEXF_LINEAR = 2,
D3DTFG_ANISOTROPIC, // D3DTEXF_ANISOTROPIC = 3,
D3DTFG_FLATCUBIC, // D3DTEXF_FLATCUBIC = 4,
D3DTFG_GAUSSIANCUBIC, // D3DTEXF_GAUSSIANCUBIC = 5,
};
// Map DX8 texture filter enum to D3DTEXTUREMINFILTER
const texf2texfn[] = {
D3DTFN_POINT, // D3DTEXF_NONE = 0,
D3DTFN_POINT, // D3DTEXF_POINT = 1,
D3DTFN_LINEAR, // D3DTEXF_LINEAR = 2,
D3DTFN_ANISOTROPIC, // D3DTEXF_ANISOTROPIC = 3,
D3DTFN_LINEAR, // D3DTEXF_FLATCUBIC = 4,
D3DTFN_LINEAR, // D3DTEXF_GAUSSIANCUBIC = 5,
};
// Map DX8 texture filter enum to D3DTEXTUREMIPFILTER
const texf2texfp[] = {
D3DTFP_NONE, // D3DTEXF_NONE = 0,
D3DTFP_POINT, // D3DTEXF_POINT = 1,
D3DTFP_LINEAR, // D3DTEXF_LINEAR = 2,
D3DTFP_LINEAR, // D3DTEXF_ANISOTROPIC = 3,
D3DTFP_LINEAR, // D3DTEXF_FLATCUBIC = 4,
D3DTFP_LINEAR, // D3DTEXF_GAUSSIANCUBIC = 5,
};
/////////////////////////////////////////////////////////////////////////////
// //
// CD3DBase //
// //
/////////////////////////////////////////////////////////////////////////////
class CD3DBase : public CBaseDevice
{
public:
// IDirect3DDevice8 Methods
HRESULT D3DAPI ResourceManagerDiscardBytes(DWORD cbBytes); // 5
HRESULT D3DAPI SetRenderTarget(IDirect3DSurface8 *pRenderTarget, IDirect3DSurface8 *pZStencil); // 31
HRESULT D3DAPI GetRenderTarget(IDirect3DSurface8 **ppRenderTarget); // 32
HRESULT D3DAPI GetDepthStencilSurface(IDirect3DSurface8 **ppZStencil); // 33
HRESULT D3DAPI BeginScene(); // 34
HRESULT D3DAPI EndScene(); // 35
HRESULT D3DAPI Clear( DWORD dwCount, CONST D3DRECT* rects, DWORD dwFlags,
D3DCOLOR dwColor, D3DVALUE dvZ, DWORD dwStencil); // 36
HRESULT D3DAPI SetTransform(D3DTRANSFORMSTATETYPE, CONST D3DMATRIX*); // 37
HRESULT D3DAPI GetTransform(D3DTRANSFORMSTATETYPE, LPD3DMATRIX); // 38
HRESULT D3DAPI MultiplyTransform(D3DTRANSFORMSTATETYPE, CONST D3DMATRIX*); // 39
HRESULT D3DAPI SetViewport(CONST D3DVIEWPORT8*); // 40
HRESULT D3DAPI GetViewport(D3DVIEWPORT8*); // 41
HRESULT D3DAPI SetMaterial(CONST D3DMATERIAL8*); // 42
HRESULT D3DAPI GetMaterial(D3DMATERIAL8*); // 43
HRESULT D3DAPI SetLight(DWORD, CONST D3DLIGHT8*); // 44
HRESULT D3DAPI GetLight(DWORD, D3DLIGHT8*); // 45
HRESULT D3DAPI LightEnable(DWORD dwLightIndex, BOOL); // 46
HRESULT D3DAPI GetLightEnable(DWORD dwLightIndex, BOOL*); // 47
HRESULT D3DAPI SetClipPlane(DWORD dwPlaneIndex, CONST D3DVALUE* pPlaneEquation); // 48
HRESULT D3DAPI GetClipPlane(DWORD dwPlaneIndex, D3DVALUE* pPlaneEquation); // 49
HRESULT D3DAPI SetRenderState(D3DRENDERSTATETYPE, DWORD); // 50
HRESULT D3DAPI GetRenderState(D3DRENDERSTATETYPE, LPDWORD); // 51
HRESULT D3DAPI BeginStateBlock(); // 52
HRESULT D3DAPI EndStateBlock(LPDWORD); // 53
HRESULT D3DAPI ApplyStateBlock(DWORD); // 54
HRESULT D3DAPI CaptureStateBlock(DWORD Handle); // 55
HRESULT D3DAPI DeleteStateBlock(DWORD); // 56
HRESULT D3DAPI CreateStateBlock(D3DSTATEBLOCKTYPE sbt, LPDWORD pdwHandle); // 57
HRESULT D3DAPI SetClipStatus(CONST D3DCLIPSTATUS8*); // 58
HRESULT D3DAPI GetClipStatus(D3DCLIPSTATUS8*); // 59
HRESULT D3DAPI GetTexture(DWORD, IDirect3DBaseTexture8**); // 60
HRESULT D3DAPI SetTexture(DWORD, IDirect3DBaseTexture8*); // 61
HRESULT D3DAPI GetTextureStageState(DWORD, D3DTEXTURESTAGESTATETYPE, LPDWORD); // 62
HRESULT D3DAPI SetTextureStageState(DWORD dwStage,
D3DTEXTURESTAGESTATETYPE dwState,
DWORD dwValue); // 63
HRESULT D3DAPI ValidateDevice(LPDWORD lpdwNumPasses); // 64
HRESULT D3DAPI GetInfo(DWORD dwDevInfoID, LPVOID pDevInfoStruct,
DWORD dwSize); // 65
HRESULT D3DAPI SetPaletteEntries(UINT PaletteNumber, CONST PALETTEENTRY *pEntries); // 66
HRESULT D3DAPI GetPaletteEntries(UINT PaletteNumber, PALETTEENTRY *pEntries); // 67
HRESULT D3DAPI SetCurrentTexturePalette(UINT PaletteNumber); // 68
HRESULT D3DAPI GetCurrentTexturePalette(UINT *PaletteNumber); // 69
HRESULT D3DAPI DrawPrimitive(D3DPRIMITIVETYPE PrimType,
UINT StartVertex, UINT VertexCount); // 70
HRESULT D3DAPI DrawIndexedPrimitive(D3DPRIMITIVETYPE, UINT minIndex,
UINT maxIndex, UINT startIndex,
UINT count); // 71
HRESULT D3DAPI DrawPrimitiveUP(
D3DPRIMITIVETYPE PrimitiveType,
UINT PrimitiveCount,
CONST VOID *pVertexStreamZeroData,
UINT VertexStreamZeroStride); // 72
HRESULT D3DAPI DrawIndexedPrimitiveUP(
D3DPRIMITIVETYPE PrimitiveType,
UINT MinVertexIndex, UINT NumVertexIndices,
UINT PrimitiveCount,
CONST VOID *pIndexData, D3DFORMAT IndexDataFormat,
CONST VOID *pVertexStreamZeroData, UINT VertexStreamZeroStride); // 73
HRESULT D3DAPI ProcessVertices(UINT SrcStartIndex, UINT DestIndex,
UINT VertexCount,
IDirect3DVertexBuffer8 *pDestBuffer,
DWORD Flags); // 74
HRESULT D3DAPI CreateVertexShader(CONST DWORD* pdwDeclaration,
CONST DWORD* pdwFunction,
DWORD* pdwHandle, DWORD dwUsage); // 75
HRESULT D3DAPI SetVertexShader(DWORD dwHandle); // 76
HRESULT D3DAPI GetVertexShader(LPDWORD pdwHandle); // 77
HRESULT D3DAPI DeleteVertexShader(DWORD dwHandle); // 78
HRESULT D3DAPI SetVertexShaderConstant(DWORD dwRegisterAddress,
CONST VOID* lpvConstantData,
DWORD dwConstantCount); // 79
HRESULT D3DAPI GetVertexShaderConstant(DWORD dwRegisterAddress,
LPVOID lpvConstantData,
DWORD dwConstantCount); // 80
HRESULT D3DAPI GetVertexShaderDeclaration(DWORD dwHandle, void *pData,
DWORD *pSizeOfData); // 81
HRESULT D3DAPI GetVertexShaderFunction(DWORD dwHandle, void *pData,
DWORD *pSizeOfData); // 82
HRESULT D3DAPI SetStreamSource(UINT StreamNumber,
IDirect3DVertexBuffer8 *pStreamData,
UINT Stride); // 83
HRESULT D3DAPI GetStreamSource(UINT StreamNumber,
IDirect3DVertexBuffer8 **ppStreamData,
UINT* pStride); // 84
HRESULT D3DAPI SetIndices(IDirect3DIndexBuffer8 *pIndexData,
UINT BaseVertexIndex); // 85
HRESULT D3DAPI GetIndices(IDirect3DIndexBuffer8 **ppIndexData,
UINT* pBaseVertexIndex); // 86
HRESULT D3DAPI CreatePixelShader(CONST DWORD* pdwFunction,
LPDWORD pdwHandle); // 87
HRESULT D3DAPI SetPixelShader(DWORD dwHandle); // 88
HRESULT D3DAPI GetPixelShader(LPDWORD pdwHandle); // 89
HRESULT D3DAPI DeletePixelShader(DWORD dwHandle); // 90
HRESULT D3DAPI SetPixelShaderConstant(DWORD dwRegisterAddress,
CONST VOID* lpvConstantData,
DWORD dwConstantCount); // 91
HRESULT D3DAPI GetPixelShaderConstant(DWORD dwRegisterAddress,
LPVOID lpvConstantData,
DWORD dwConstantCount); // 92
HRESULT D3DAPI GetPixelShaderFunction(DWORD dwHandle, void *pData,
DWORD *pSizeOfData); // 93
HRESULT D3DAPI DrawRectPatch(UINT Handle, CONST FLOAT *pNumSegs,
CONST D3DRECTPATCH_INFO *pSurf); // 94
HRESULT D3DAPI DrawTriPatch(UINT Handle, CONST FLOAT *pNumSegs,
CONST D3DTRIPATCH_INFO *pSurf); // 95
HRESULT D3DAPI DeletePatch(UINT Handle); // 96
public:
// Flags to indicate runtime state
DWORD m_dwRuntimeFlags;
// D3DDEVBOOL flags
DWORD m_dwHintFlags;
// This should only be accessed through
// CurrentBatch and IncrementBatchCount
ULONGLONG m_qwBatch;
// The object encapsulating the DDI styles
// At the minimum this is a DX6 driver.
LPD3DDDIDX6 m_pDDI;
#if DBG
// Debug Monitor
D3DDebugMonitor* m_pDbgMonBase; // base class only
RTDebugMonitor* m_pDbgMon; // runtime monitor
BOOL m_bDbgMonConnectionEnabled;
void DebugEvent( UINT32 EventType )
{
if (m_pDbgMon) m_pDbgMon->NextEvent( EventType );
}
void DebugStateChanged( UINT32 StateType )
{
if (m_pDbgMon) m_pDbgMon->StateChanged( StateType );
}
#else
void DebugEvent( UINT32 ) { };
void DebugStateChanged( UINT32 ) { };
#endif
// Pointer to texture objects for currently installed textures.
// NULL indicates that the texture is either not set (rstate NULL) or that
// the handle to tex3 pointer mapping is not done. This mapping is
// expensive, so it is deferred until needed. This is needed for finding
// the WRAPU,V mode for texture index clipping (since the WRAPU,V state is
// part of the device).
CBaseTexture* m_lpD3DMappedTexI[D3DHAL_TSS_MAXSTAGES];
DWORD m_dwDDITexHandle[D3DHAL_TSS_MAXSTAGES];
// Max number of blend stages supported by a driver
DWORD m_dwMaxTextureBlendStages;
DWORD m_dwStageDirty, m_dwStreamDirty;
// Object to record state sets
CStateSets* m_pStateSets;
//
// The following is for validation only
//
// Max TSS that can be passed to the driver
D3DTEXTURESTAGESTATETYPE m_tssMax;
// Max RS that can be passed to the driver, used for CanHandleRenderState
D3DRENDERSTATETYPE m_rsMax;
#if defined(PROFILE4) || defined(PROFILE)
DWORD m_dwProfStart, m_dwProfStop;
#endif
// This bit array is used to tell if a light has been created or not
CPackedBitArray* m_pCreatedLights;
// DX8 related stuff from here -------------------------------------
// The current shader handle. It is initialized to Zero.
// Zero means that there is no current shader. User always has to
// initialize the shader.
// It is used only by non-pure device
DWORD m_dwCurrentShaderHandle;
// The current pixel shader handle. It is initialized to zero, and
// is set to zero for legacy pixel processing
// It is used only by non-pure device
DWORD m_dwCurrentPixelShaderHandle;
// This object gives us pixel shader handles
CHandleFactory* m_pPShaderArray;
// This object gives us vertex shader handles
CVShaderHandleFactory* m_pVShaderArray;
// Vertex sctreams
CVStream* m_pStream;
// Index stream
CVIndexStream* m_pIndexStream;
// Max number of streams allowed. For D3D software it is __NUMSTREAMS
// For hardware T&L it could be smaller
DWORD m_dwNumStreams;
// Max number of user clipping streams supported
DWORD m_dwMaxUserClipPlanes;
// Currently set palette
DWORD m_dwPalette;
// Palette array
CHandleArray *m_pPaletteArray;
#if DBG
// Needed for RT-Patch validation
CHandleArray *m_pRTPatchValidationInfo;
// Needed for VB warnings
DWORD m_SceneStamp;
#endif // DBG
// Function pointers for DrawPrimitive processing
PFN_DRAWPRIMFAST m_pfnDrawPrim;
PFN_DRAWINDEXEDPRIMFAST m_pfnDrawIndexedPrim;
// Function pointers for DrawPrimitive processing from NPatch
// conversion function in case of point or line primitives
PFN_DRAWPRIMFAST m_pfnDrawPrimFromNPatch;
PFN_DRAWINDEXEDPRIMFAST m_pfnDrawIndexedPrimFromNPatch;
// Number of constant register. This could be different for software and
// hardware vertex processing
UINT m_MaxVertexShaderConst;
#ifdef FAST_PATH
#define NUMVTBLENTRIES 135
VOID **m_pOrigVtbl;
VOID *m_pVtbl[NUMVTBLENTRIES];
void FastPathSetRenderStateExecute()
{
if((BehaviorFlags() & D3DCREATE_MULTITHREADED) == 0)
{
m_pVtbl[50] = m_pVtbl[98];
}
else
{
DXGASSERT(m_pVtbl[50] == m_pOrigVtbl[50]);
}
}
void FastPathSetRenderStateRecord()
{
m_pVtbl[50] = m_pOrigVtbl[50];
}
void FastPathSetTextureStageStateExecute()
{
if((BehaviorFlags() & D3DCREATE_MULTITHREADED) == 0)
{
m_pVtbl[63] = m_pVtbl[99];
}
else
{
DXGASSERT(m_pVtbl[63] == m_pOrigVtbl[63]);
}
}
void FastPathSetTextureStageStateRecord()
{
m_pVtbl[63] = m_pOrigVtbl[63];
}
void FastPathSetTextureExecute()
{
if((BehaviorFlags() & D3DCREATE_MULTITHREADED) == 0)
{
m_pVtbl[61] = m_pVtbl[100];
}
else
{
DXGASSERT(m_pVtbl[61] == m_pOrigVtbl[61]);
}
}
void FastPathSetTextureRecord()
{
m_pVtbl[61] = m_pOrigVtbl[61];
}
void FastPathApplyStateBlockExecute()
{
if((BehaviorFlags() & D3DCREATE_MULTITHREADED) == 0)
{
m_pVtbl[54] = m_pVtbl[101];
}
else
{
DXGASSERT(m_pVtbl[54] == m_pOrigVtbl[54]);
}
}
void FastPathApplyStateBlockRecord()
{
m_pVtbl[54] = m_pOrigVtbl[54];
}
void FastPathSetVertexShaderFast()
{
if((m_dwRuntimeFlags & (D3DRT_RECORDSTATEMODE | D3DRT_RSSOFTWAREPROCESSING)) == 0 &&
(BehaviorFlags() & D3DCREATE_MULTITHREADED) == 0)
{
m_pVtbl[76] = m_pVtbl[102];
}
else
{
DXGASSERT(m_pVtbl[76] == m_pOrigVtbl[76]);
}
}
void FastPathSetVertexShaderSlow()
{
m_pVtbl[76] = m_pOrigVtbl[76];
}
void FastPathSetStreamSourceFast()
{
if((m_dwRuntimeFlags & (D3DRT_RECORDSTATEMODE | D3DRT_RSSOFTWAREPROCESSING)) == 0 &&
(BehaviorFlags() & D3DCREATE_MULTITHREADED) == 0)
{
m_pVtbl[83] = m_pVtbl[103];
}
else
{
DXGASSERT(m_pVtbl[83] == m_pOrigVtbl[83]);
}
}
void FastPathSetStreamSourceSlow()
{
m_pVtbl[83] = m_pOrigVtbl[83];
}
void FastPathSetIndicesFast()
{
if((m_dwRuntimeFlags & (D3DRT_RECORDSTATEMODE | D3DRT_RSSOFTWAREPROCESSING)) == 0 &&
(BehaviorFlags() & D3DCREATE_MULTITHREADED) == 0)
{
m_pVtbl[85] = m_pVtbl[104];
}
else
{
DXGASSERT(m_pVtbl[85] == m_pOrigVtbl[85]);
}
}
void FastPathSetIndicesSlow()
{
m_pVtbl[85] = m_pOrigVtbl[85];
}
void FastPathSetTransformExecute()
{
if((BehaviorFlags() & D3DCREATE_MULTITHREADED) == 0 &&
(BehaviorFlags() & D3DCREATE_PUREDEVICE) != 0)
{
m_pVtbl[37] = m_pVtbl[105];
}
else
{
DXGASSERT(m_pVtbl[37] == m_pOrigVtbl[37]);
}
}
void FastPathSetTransformRecord()
{
m_pVtbl[37] = m_pOrigVtbl[37];
}
void FastPathMultiplyTransformExecute()
{
if((BehaviorFlags() & D3DCREATE_MULTITHREADED) == 0 &&
(BehaviorFlags() & D3DCREATE_PUREDEVICE) != 0)
{
m_pVtbl[39] = m_pVtbl[106];
}
else
{
DXGASSERT(m_pVtbl[39] == m_pOrigVtbl[39]);
}
}
void FastPathMultiplyTransformRecord()
{
m_pVtbl[39] = m_pOrigVtbl[39];
}
void FastPathSetMaterialExecute()
{
if((BehaviorFlags() & D3DCREATE_MULTITHREADED) == 0)
{
m_pVtbl[42] = m_pVtbl[107];
}
else
{
DXGASSERT(m_pVtbl[42] == m_pOrigVtbl[42]);
}
}
void FastPathSetMaterialRecord()
{
m_pVtbl[42] = m_pOrigVtbl[42];
}
void FastPathSetPixelShaderExecute()
{
if((BehaviorFlags() & D3DCREATE_MULTITHREADED) == 0)
{
m_pVtbl[88] = m_pVtbl[108];
}
else
{
DXGASSERT(m_pVtbl[88] == m_pOrigVtbl[88]);
}
}
void FastPathSetPixelShaderRecord()
{
m_pVtbl[88] = m_pOrigVtbl[88];
}
void FastPathSetPixelShaderConstantExecute()
{
if((BehaviorFlags() & D3DCREATE_MULTITHREADED) == 0)
{
m_pVtbl[91] = m_pVtbl[109];
}
else
{
DXGASSERT(m_pVtbl[91] == m_pOrigVtbl[91]);
}
}
void FastPathSetPixelShaderConstantRecord()
{
m_pVtbl[91] = m_pOrigVtbl[91];
}
void FastPathSetVertexShaderConstantExecute()
{
if((BehaviorFlags() & D3DCREATE_MULTITHREADED) == 0 &&
(BehaviorFlags() & D3DCREATE_PUREDEVICE) != 0)
{
m_pVtbl[79] = m_pVtbl[110];
}
else
{
DXGASSERT(m_pVtbl[79] == m_pOrigVtbl[79]);
}
}
void FastPathSetVertexShaderConstantRecord()
{
m_pVtbl[79] = m_pOrigVtbl[79];
}
#endif // FAST_PATH
public:
CD3DBase();
virtual ~CD3DBase(); // 97
virtual HRESULT D3DAPI SetRenderStateFast(D3DRENDERSTATETYPE dwState, DWORD value); // 98
virtual HRESULT D3DAPI SetTextureStageStateFast(DWORD dwStage, D3DTEXTURESTAGESTATETYPE dwState, DWORD dwValue); // 99
virtual HRESULT D3DAPI SetTextureFast(DWORD, IDirect3DBaseTexture8 *lpTex); // 100
virtual HRESULT D3DAPI ApplyStateBlockFast(DWORD); // 101
#ifdef FAST_PATH
virtual HRESULT D3DAPI SetVertexShaderFast(DWORD); // 102
virtual HRESULT D3DAPI SetStreamSourceFast(UINT StreamNumber, IDirect3DVertexBuffer8 *pStreamData, UINT Stride); // 103
virtual HRESULT D3DAPI SetIndicesFast(IDirect3DIndexBuffer8 *pIndexData, UINT BaseVertexIndex); // 104
virtual HRESULT D3DAPI SetTransformFast(D3DTRANSFORMSTATETYPE, CONST D3DMATRIX*); // 105
virtual HRESULT D3DAPI MultiplyTransformFast(D3DTRANSFORMSTATETYPE, CONST D3DMATRIX*); // 106
#endif // FAST_PATH
virtual HRESULT D3DAPI SetMaterialFast(CONST D3DMATERIAL8*); // 107
virtual HRESULT D3DAPI SetPixelShaderFast(DWORD dwHandle); // 108
virtual HRESULT D3DAPI SetPixelShaderConstantFast(DWORD dwRegisterAddress, // 109
CONST VOID* lpvConstantData,
DWORD dwConstantCount);
virtual HRESULT D3DAPI SetVertexShaderConstantFast(DWORD dwRegisterAddress, // 110
CONST VOID* lpvConstantData,
DWORD dwConstantCount);
virtual void Destroy(); // 111
// Virtual methods for CBaseDevice
virtual HRESULT InitDevice(); // 112
virtual void StateInitialize(BOOL bZEnable); // 113
virtual void UpdateRenderState(DWORD dwStateType, DWORD value) {} // 114
virtual void SetTransformI(D3DTRANSFORMSTATETYPE, CONST D3DMATRIX*); // 115
virtual void MultiplyTransformI(D3DTRANSFORMSTATETYPE, CONST D3DMATRIX*); // 116
virtual void SetClipPlaneI(DWORD dwPlaneIndex, // 117
CONST D3DVALUE* pPlaneEquation);
virtual void UpdateDriverStates(){ DDASSERT( FALSE ); } // 118
virtual void SetViewportI(CONST D3DVIEWPORT8*); // 119
virtual void SetStreamSourceI(CVStream*); // 120
virtual void SetIndicesI(CVIndexStream*); // 121
virtual void CreateVertexShaderI(CONST DWORD* pdwDeclaration, // 122
DWORD dwDeclSize,
CONST DWORD* pdwFunction,
DWORD dwCodeSize,
DWORD dwHandle);
virtual void SetVertexShaderI(DWORD dwHandle); // 123
virtual void DeleteVertexShaderI(DWORD dwHandle); // 124
virtual void SetVertexShaderConstantI(DWORD dwRegisterAddress, // 125
CONST VOID* lpvConstantData,
DWORD dwConstantCount);
virtual void DrawPointsI(D3DPRIMITIVETYPE PrimitiveType, // 126
UINT StartVertex,
UINT PrimitiveCount);
virtual void SetLightI(DWORD dwLightIndex, CONST D3DLIGHT8*); // 127
virtual void LightEnableI(DWORD dwLightIndex, BOOL); // 128
virtual void SetRenderStateInternal(D3DRENDERSTATETYPE, DWORD); // 129
virtual void DrawPrimitiveUPI(D3DPRIMITIVETYPE PrimitiveType, // 130
UINT PrimitiveCount);
virtual void DrawIndexedPrimitiveUPI(D3DPRIMITIVETYPE PrimitiveType, // 131
UINT MinVertexIndex,
UINT NumVertexIndices,
UINT PrimitiveCount);
virtual void GetPixelShaderConstantI(DWORD Register, DWORD count, // 132
LPVOID pData );
virtual void ClearI( DWORD dwCount, CONST D3DRECT* rects, DWORD dwFlags, // 133
D3DCOLOR dwColor, D3DVALUE dvZ, DWORD dwStencil);
// Picks the right DrawPrimitive and DrawIndexedPrimitive function to
// execute
// Call this function when
// - vertex shader is changed
// - stream source is changed
// - D3DRS_CLIPPING is changed
// - resource has been changed
//
// Base device implementation is empty, because the function pointers are
// initialized in the constructor and do not change
virtual void __declspec(nothrow) PickDrawPrimFn() {}; // 134
protected:
void ValidateDraw(D3DPRIMITIVETYPE primType, UINT StartVertex,
UINT PrimitiveCount, UINT NumVertices,
BOOL bIndexPrimitive, BOOL bUsedMemPrimitive);
void CheckIndices(CONST BYTE* pIndices, UINT NumIndices, UINT StartIndex,
UINT MinIndex, UINT NumVertices, UINT IndexStride);
void CheckViewport(CONST D3DVIEWPORT8* lpData);
void CheckVertexShaderHandle(DWORD dwHandle);
void CheckPixelShaderHandle(DWORD dwHandle);
inline void ClearVertexShaderHandle()
{
m_dwCurrentShaderHandle = 0;
}
public:
// non virtual methods
HRESULT __declspec(nothrow) Init();
HRESULT VerifyTexture(DWORD dwStage, IDirect3DBaseTexture8 *lpTex);
HRESULT CalcDDSurfInfo(BOOL bUpdateZBufferFields);
// Re-creates hardware pixel and vertex shaders after device is reset
HRESULT ResetShaders();
void __declspec(nothrow) NeedResourceStateUpdate()
{
this->m_dwRuntimeFlags |= (D3DRT_NEED_TEXTURE_UPDATE | D3DRT_NEED_VB_UPDATE);
// We shouldn't call PickDrawPrimFn when the device is being destroyed
if (m_pDDI)
PickDrawPrimFn();
}
HRESULT __declspec(nothrow) SetRenderTargetI(CBaseSurface* pTarget,
CBaseSurface* pZ);
// Checks if we can pass the render state to the driver
BOOL CanHandleRenderState(D3DRENDERSTATETYPE type)
{
if (type >= m_rsMax)
{
// not an error condition because we don't send front-end stuff to
// non-TL Hal devices, for example, but don't send to HAL anyway
return FALSE;
}
return TRUE;
};
void UpdateTextures();
void UpdatePalette(CBaseTexture *pTex, DWORD Palette, DWORD dwStage, BOOL bSavedWithinPrimitive);
HRESULT __declspec(nothrow) TexBlt(CBaseTexture *lpDst,
CBaseTexture* lpSrc,
POINT *pPoint,
RECTL *pRect);
HRESULT __declspec(nothrow) CubeTexBlt(CBaseTexture *lpDstParent,
CBaseTexture* lpSrcParent,
DWORD dwDestFaceHandle,
DWORD dwSrcFaceHandle,
POINT *pPoint,
RECTL *pRect);
HRESULT __declspec(nothrow) VolBlt(CBaseTexture *lpDst, CBaseTexture* lpSrc, DWORD dwDestX,
DWORD dwDestY, DWORD dwDestZ, D3DBOX *pBox);
HRESULT __declspec(nothrow) BufBlt(CBuffer *lpDst, CBuffer* lpSrc, DWORD dwOffset,
D3DRANGE* pRange);
HRESULT __declspec(nothrow) SetPriority(CResource *pRes, DWORD dwPriority);
HRESULT __declspec(nothrow) SetTexLOD(CBaseTexture *pTex, DWORD dwLOD);
HRESULT __declspec(nothrow) AddDirtyRect(CBaseTexture *pTex, CONST RECTL *pRect);
HRESULT __declspec(nothrow) AddCubeDirtyRect(CBaseTexture *pTex, DWORD dwFaceHandle, CONST RECTL *pRect);
HRESULT __declspec(nothrow) AddDirtyBox(CBaseTexture *pTex, CONST D3DBOX *pBox);
void __declspec(nothrow) CleanupTextures();
void __declspec(nothrow) OnTextureDestroy(CBaseTexture*);
ULONGLONG __declspec(nothrow) CurrentBatch()
{
DDASSERT(m_qwBatch > 0);
return m_qwBatch;
}
void IncrementBatchCount();
void __declspec(nothrow) Sync(ULONGLONG batch)
{
if (m_qwBatch <= batch)
{
FlushStatesNoThrow();
}
}
HRESULT __declspec(nothrow) ValidateFVF(DWORD dwFVF);
void __declspec(nothrow) FlushStatesNoThrow();
#if DBG
#define PROF_DRAWPRIMITIVEDEVICE2 0x0003
#define PROF_DRAWINDEXEDPRIMITIVEDEVICE2 0x0004
#define PROF_DRAWPRIMITIVESTRIDED 0x0005
#define PROF_DRAWINDEXEDPRIMITIVESTRIDED 0x0006
#define PROF_DRAWPRIMITIVEDEVICE3 0x0007
#define PROF_DRAWINDEXEDPRIMITIVEDEVICE3 0x0008
#define PROF_DRAWPRIMITIVEVB 0x0009
#define PROF_DRAWINDEXEDPRIMITIVEVB 0x000a
DWORD dwCaller;
DWORD dwPrimitiveType[PROF_DRAWINDEXEDPRIMITIVEVB+1];
DWORD dwVertexType1[PROF_DRAWINDEXEDPRIMITIVEVB+1];
DWORD dwVertexType2[PROF_DRAWINDEXEDPRIMITIVEVB+1];
void Profile(DWORD, D3DPRIMITIVETYPE, DWORD);
#else
#define Profile(a,b,c)
#endif
friend class CD3DDDIDX6;
};
typedef CD3DBase *LPD3DBASE;
/////////////////////////////////////////////////////////////////////////////
// //
// CD3DHal //
// //
/////////////////////////////////////////////////////////////////////////////
typedef void (CD3DHal::* PFN_PREPARETODRAW)(UINT StartVertex);
class CD3DHal : public CD3DBase
{
public: // Private Data
// buffer for H vertices
CAlignedBuffer32 HVbuf;
// Front end data
D3DFE_TRANSFORM transform; // Transformation state
D3DCLIPSTATUS8 m_ClipStatus;
// Pipeline state info
D3DFE_PROCESSVERTICES* m_pv; // common data for D3D and PSGP
DWORD dwFEFlags; // Front-end flags
//--------------- Lights start -----------------------
// List of currently enabled lights
LIST_ROOT(_dlights, DIRECT3DLIGHTI) m_ActiveLights;
LIST_ROOT(name10,_SpecularTable) specular_tables;
SpecularTable* specular_table;
LIGHT_VERTEX_FUNC_TABLE *lightVertexFuncTable;
// Light management support
CHandleArray* m_pLightArray;
//--------------- Lights end -----------------------
// Viewports
D3DVIEWPORT8 m_Viewport;
DWORD m_clrCount; // Number of rects allocated
LPD3DRECT m_clrRects; // Rects used for clearing
// Runtime copy of the renderstates
LPDWORD rstates;
// Runtime copy of texture stage states
DWORD tsstates[D3DHAL_TSS_MAXSTAGES][D3DHAL_TSS_STATESPERSTAGE];
// Bit set for a render state means that we have to update internal front-end state
// Otherwise we can go through a fast path
CPackedBitArray rsVec;
// Bit set for a render state means that the render state is retired
CPackedBitArray rsVecRetired;
// Bit set for a render state means that the render state is for vertex
// processing only
CPackedBitArray rsVertexProcessingOnly;
// For every transformation matrix there is a bit, which is set if we need
// to update driver state
CPackedBitArray* pMatrixDirtyForDDI;
// Pointer to a specific PrepareToDraw function
PFN_PREPARETODRAW m_pfnPrepareToDraw;
// Current vertex shader, corresponding to the dwCurrentShaderHandle
// NULL for the fixed-function pipeline
CVShader* m_pCurrentShader;
// The instance of the class providing a guaranteed implementation
D3DFE_PVFUNCSI* GeometryFuncsGuaranteed;
// Pixel Shader constant registers cached for Hal device
PVM_WORD m_PShaderConstReg[D3DPS_CONSTREG_MAX_DX8];
// Object, used to convert NPatches to TriPatches
CNPatch2TriPatch* m_pConvObj;
// Texture stages, which we need to remap, when number of output texture
// coordinates is greater than number of input texture coordinates
D3DFE_TEXTURESTAGE textureStageToRemap[D3DDP_MAXTEXCOORD];
// Number of texture stages to remap
DWORD dwNumTextureStagesToRemap;
virtual HRESULT D3DAPI SetRenderStateFast(D3DRENDERSTATETYPE dwState, DWORD value);
virtual HRESULT D3DAPI SetTextureStageStateFast(DWORD dwStage, D3DTEXTURESTAGESTATETYPE dwState, DWORD dwValue);
#ifdef FAST_PATH
virtual HRESULT D3DAPI SetVertexShaderFast(DWORD);
#endif // FAST_PATH
virtual HRESULT D3DAPI SetMaterialFast(CONST D3DMATERIAL8*);
virtual HRESULT D3DAPI SetPixelShaderFast(DWORD dwHandle);
virtual HRESULT D3DAPI SetPixelShaderConstantFast(DWORD dwRegisterAddress,
CONST VOID* lpvConstantData,
DWORD dwConstantCount);
public:
CD3DHal();
virtual ~CD3DHal();
virtual void Destroy();
//
// Pure Methods from CD3DBase implemented here
//
virtual HRESULT InitDevice();
virtual void StateInitialize(BOOL bZEnable);
virtual void SetTransformI(D3DTRANSFORMSTATETYPE, CONST D3DMATRIX*);
virtual void MultiplyTransformI(D3DTRANSFORMSTATETYPE, CONST D3DMATRIX*);
virtual void SetViewportI(CONST D3DVIEWPORT8*);
virtual void SetLightI(DWORD dwLightIndex, CONST D3DLIGHT8*);
virtual void LightEnableI(DWORD dwLightIndex, BOOL);
virtual void SetClipPlaneI(DWORD dwPlaneIndex,
CONST D3DVALUE* pPlaneEquation);
virtual void SetStreamSourceI(CVStream*);
virtual void SetIndicesI(CVIndexStream*);
virtual void CreateVertexShaderI(CONST DWORD* pdwDeclaration,
DWORD dwDeclSize,
CONST DWORD* pdwFunction,
DWORD dwCodeSize,
DWORD dwHandle);
virtual void SetVertexShaderI(DWORD dwHandle);
virtual void DeleteVertexShaderI(DWORD dwHandle);
virtual void SetVertexShaderConstantI(DWORD dwRegisterAddress,
CONST VOID* lpvConstantData,
DWORD dwConstantCount);
virtual void DrawPointsI(D3DPRIMITIVETYPE PrimitiveType,
UINT StartVertex,
UINT PrimitiveCount);
virtual void DrawPrimitiveUPI(D3DPRIMITIVETYPE PrimitiveType,
UINT PrimitiveCount);
virtual void DrawIndexedPrimitiveUPI(D3DPRIMITIVETYPE PrimitiveType,
UINT MinVertexIndex,
UINT NumVertexIndices,
UINT PrimitiveCount);
virtual void ClearI( DWORD dwCount, CONST D3DRECT* rects, DWORD dwFlags,
D3DCOLOR dwColor, D3DVALUE dvZ, DWORD dwStencil);
// This function is used when in SetRenderTarget the driver context is
// recreated
virtual void UpdateDriverStates(); // 10
virtual void UpdateRenderState(DWORD dwStateType, DWORD value)
{rstates[dwStateType] = value;}
virtual void __declspec(nothrow) PickDrawPrimFn();
public: // non virtual methods
// Called by drawing functions to prepare vertex stream pointers for
// legacy vertex shaders
void PrepareToDrawLegacy(UINT dwStartVertex);
// Called by drawing functions to prepare vertex stream pointers for
// programmable pipeline
void PrepareToDrawVVM(UINT dwStartVertex);
// Called by drawing functions to prepare vertex stream pointers for
// fixed-function pipeline with declarations
void PrepareToDraw(UINT dwStartVertex);
// dwValue could be changed by the function, when we need to filter
// PROJECTED bit.
BOOL UpdateInternalTextureStageState(DWORD dwStage,
D3DTEXTURESTAGESTATETYPE dwState,
DWORD* dwValue);
HRESULT checkDeviceSurface(LPDDRAWI_DDRAWSURFACE_LCL lpDDS, LPDDRAWI_DDRAWSURFACE_LCL lpZbuffer, LPGUID pGuid);
void SetupFVFDataCommon();
void SetupFVFData();
void SwitchVertexProcessingMode(DWORD SoftwareMode);
void DrawPoints(UINT StartVertex);
void GetPixelShaderConstantI(DWORD Register, DWORD count, LPVOID pData );
void PrepareNPatchConversion(UINT PrimitiveCount, UINT StartVertex);
BOOL NeedInternalTSSUpdate(DWORD dwState)
{
return dwState == D3DTSS_TEXCOORDINDEX || dwState >= D3DTSS_TEXTURETRANSFORMFLAGS ||
dwState == D3DTSS_COLOROP;
}
// Always use this function to update "rstates", because we have to
// set some internal flags when "rstats" is changed.
void UpdateInternalState(D3DRENDERSTATETYPE type, DWORD value);
// Checks for 'retired' render state - returns TRUE if not retired
BOOL CheckForRetiredRenderState(D3DRENDERSTATETYPE type)
{
if (!rsVecRetired.IsBitSet(type))
{
// not retired
return TRUE;
}
return FALSE;
}
// Update internal state
inline void SetFogFlags(void);
void ForceFVFRecompute(void)
{
dwFEFlags |= D3DFE_FVF_DIRTY | D3DFE_FRONTEND_DIRTY;
m_pv->dwDeviceFlags &= ~(D3DDEV_POSITIONINCAMERASPACE |
D3DDEV_NORMALINCAMERASPACE);
m_dwRuntimeFlags |= D3DRT_SHADERDIRTY;
};
void DisplayStats();
void SetRenderStateInternal(D3DRENDERSTATETYPE, DWORD);
HRESULT Initialize(IUnknown* pUnkOuter, LPDDRAWI_DIRECTDRAW_INT pDDrawInt);
HRESULT D3DFE_Create();
void D3DFE_Destroy();
void ValidateDraw2(D3DPRIMITIVETYPE primType, UINT StartVertex,
UINT PrimitiveCount, UINT NumVertices,
BOOL bIndexPrimitive, UINT StartIndex = 0);
#if DBG
void ValidateRTPatch();
#endif // DBG
#if DBG
#define PROF_DRAWPRIMITIVEDEVICE2 0x0003
#define PROF_DRAWINDEXEDPRIMITIVEDEVICE2 0x0004
#define PROF_DRAWPRIMITIVESTRIDED 0x0005
#define PROF_DRAWINDEXEDPRIMITIVESTRIDED 0x0006
#define PROF_DRAWPRIMITIVEDEVICE3 0x0007
#define PROF_DRAWINDEXEDPRIMITIVEDEVICE3 0x0008
#define PROF_DRAWPRIMITIVEVB 0x0009
#define PROF_DRAWINDEXEDPRIMITIVEVB 0x000a
DWORD dwCaller;
DWORD dwPrimitiveType[PROF_DRAWINDEXEDPRIMITIVEVB+1];
DWORD dwVertexType1[PROF_DRAWINDEXEDPRIMITIVEVB+1];
DWORD dwVertexType2[PROF_DRAWINDEXEDPRIMITIVEVB+1];
void Profile(DWORD, D3DPRIMITIVETYPE, DWORD);
#else
#define Profile(a,b,c)
#endif
public:
// IDirect3DDevice8 Methods
HRESULT D3DAPI GetViewport(D3DVIEWPORT8*);
HRESULT D3DAPI GetMaterial(D3DMATERIAL8*);
HRESULT D3DAPI GetTransform(D3DTRANSFORMSTATETYPE, LPD3DMATRIX);
HRESULT D3DAPI GetLight(DWORD, D3DLIGHT8*);
HRESULT D3DAPI GetLightEnable(DWORD dwLightIndex, BOOL*);
HRESULT D3DAPI GetClipPlane(DWORD dwPlaneIndex, D3DVALUE* pPlaneEquation);
HRESULT D3DAPI GetTextureStageState(DWORD, D3DTEXTURESTAGESTATETYPE,
LPDWORD);
HRESULT D3DAPI SetTextureStageState(DWORD dwStage,
D3DTEXTURESTAGESTATETYPE dwState,
DWORD dwValue);
HRESULT D3DAPI GetRenderState(D3DRENDERSTATETYPE, LPDWORD);
HRESULT D3DAPI SetRenderState(D3DRENDERSTATETYPE, DWORD);
HRESULT D3DAPI SetClipStatus(CONST D3DCLIPSTATUS8*);
HRESULT D3DAPI GetClipStatus(D3DCLIPSTATUS8*);
HRESULT D3DAPI ProcessVertices(UINT SrcStartIndex, UINT DestIndex,
UINT VertexCount,
IDirect3DVertexBuffer8 *DestBuffer,
DWORD Flags);
HRESULT D3DAPI GetVertexShaderConstant(DWORD dwRegisterAddress,
LPVOID lpvConstantData,
DWORD dwConstantCount);
HRESULT D3DAPI GetPixelShaderConstant(DWORD dwRegisterAddress,
LPVOID lpvConstantData,
DWORD dwConstantCount);
HRESULT D3DAPI GetVertexShader(LPDWORD pdwHandle);
HRESULT D3DAPI GetPixelShader(LPDWORD pdwHandle);
};
//---------------------------------------------------------------------
// macros to characterize device
//
#define IS_DX7HAL_DEVICE(lpDevI) ((lpDevI)->GetDDIType() >= D3DDDITYPE_DX7)
#define IS_DX8HAL_DEVICE(lpDevI) ((lpDevI)->GetDDIType() >= D3DDDITYPE_DX8)
#define IS_FPU_SETUP(lpDevI) ((lpDevI)->m_dwHintFlags & D3DDEVBOOL_HINTFLAGS_FPUSETUP )
#define IS_HAL_DEVICE(lpDevI) ((lpDevI)->GetDeviceType() == D3DDEVTYPE_HAL)
#define IS_HEL_DEVICE(lpDevI) ((lpDevI)->GetDeviceType() == D3DDEVTYPE_EMULATION)
#define IS_REF_DEVICE(lpDevI) ((lpDevI)->GetDeviceType() == D3DDEVTYPE_REF)
#endif
// @@END_MSINTERNAL
#endif /* _D3DI_H */