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

837 lines
35 KiB
C++

/*==========================================================================;
*
* Copyright (C) 1995-2000 Microsoft Corporation. All Rights Reserved.
*
* File: ddi.h
* Content: Direct3D DDI encapsulation implementations
*
*
***************************************************************************/
#ifndef _DDI_H
#define _DDI_H
#include "ddibase.h"
class CVertexBuffer;
class CCommandBuffer;
class CTLStreamRO;
class CTLIndexStreamRO;
class CD3DDDIDX6;
// Number of point sprites in a point sprite batch
const UINT NUM_SPRITES_IN_BATCH = 500;
extern void CD3DDDIDX6_DrawPrimitive(CD3DBase* pDevice,
D3DPRIMITIVETYPE primType,
UINT StartVertex,
UINT PrimitiveCount);
extern void
CD3DDDIDX8_DrawPrimitive(CD3DBase* pDevice, D3DPRIMITIVETYPE PrimitiveType,
UINT StartVertex, UINT PrimitiveCount);
extern void
CD3DDDIDX8_DrawIndexedPrimitive(CD3DBase* pDevice,
D3DPRIMITIVETYPE PrimitiveType,
UINT BaseVertexIndex,
UINT MinIndex, UINT NumVertices,
UINT StartIndex, UINT PrimitiveCount);
extern void
CD3DDDITL_DrawIndexedPrimitive(CD3DBase* pDevice,
D3DPRIMITIVETYPE PrimitiveType,
UINT BaseVertexIndex,
UINT MinIndex,
UINT NumVertices, UINT StartIndex,
UINT PrimitiveCount);
extern void
CD3DDDIDX6_DrawIndexedPrimitive(CD3DBase* pDevice,
D3DPRIMITIVETYPE PrimitiveType,
UINT BaseVertexIndex,
UINT MinIndex,
UINT NumVertices, UINT StartIndex,
UINT PrimitiveCount);
typedef void (*PFN_DRAWPRIMFAST)(CD3DBase* pDevice, D3DPRIMITIVETYPE primType,
UINT StartVertex, UINT PrimitiveCount);
typedef void (*PFN_DRAWINDEXEDPRIMFAST)(CD3DBase* pDevice,
D3DPRIMITIVETYPE PrimitiveType,
UINT BaseVertexIndex,
UINT MinIndex, UINT NumVertices,
UINT StartIndex, UINT PrimitiveCount);
//-----------------------------------------------------------------------------
class CTLStream: public CVStream
{
public:
CTLStream(BOOL bWriteOnly);
CTLStream(BOOL bWriteOnly, UINT Usage);
UINT GetSize() {return m_dwSize - m_dwUsedSize;}
void Grow(UINT RequiredSize, CD3DDDIDX6* pDDI);
void Reset() {m_dwPrimitiveBase = 0; m_dwUsedSize = 0;}
DWORD GetVertexSize() {return m_dwStride;}
void SetVertexSize(DWORD dwVertexSize) {m_dwStride = dwVertexSize;}
DWORD GetPrimitiveBase() {return m_dwPrimitiveBase;}
virtual BYTE* Lock(UINT NeededSize, CD3DDDIDX6* pDDI);
virtual void Unlock();
virtual void AddVertices(UINT NumVertices)
{
m_dwUsedSize = m_dwPrimitiveBase + NumVertices * m_dwStride;
DXGASSERT(m_dwSize >= m_dwUsedSize);
}
virtual void SubVertices(UINT NumVertices)
{
DXGASSERT(m_dwUsedSize >= NumVertices * m_dwStride);
m_dwUsedSize -= NumVertices * m_dwStride;
DXGASSERT(m_dwSize >= m_dwUsedSize);
}
virtual void MovePrimitiveBase(int NumVertices)
{
m_dwPrimitiveBase += NumVertices * m_dwStride;
}
virtual void SkipVertices(DWORD NumVertices)
{
const UINT size = NumVertices * m_dwStride;
m_dwPrimitiveBase += size;
m_dwUsedSize = m_dwPrimitiveBase;
DXGASSERT(m_dwSize >= m_dwUsedSize);
}
BOOL CheckFreeSpace(UINT size) {return (m_dwSize - m_dwUsedSize) >= size;}
protected:
// Number of bytes used in the buffer
// It is not used by CTLStreamRO
DWORD m_dwUsedSize;
// Offset in bytes from where the current primitive starts
DWORD m_dwPrimitiveBase;
UINT m_Usage;
// TRUE, if buffer is used only for writing
BOOL m_bWriteOnly;
#if !DBG
DWORD m_dwSize;
#endif
};
//-----------------------------------------------------------------------------
class CTLIndexStream: public CVIndexStream
{
public:
CTLIndexStream();
UINT GetSize() {return m_dwSize - m_dwUsedSize;}
void Grow(UINT RequiredSize, CD3DDDIDX6* pDDI);
void Reset() {m_dwPrimitiveBase = 0; m_dwUsedSize = 0;}
DWORD GetVertexSize() {return m_dwStride;}
void SetVertexSize(DWORD dwVertexSize) {m_dwStride = dwVertexSize;}
DWORD GetPrimitiveBase() {return m_dwPrimitiveBase;}
virtual BYTE* Lock(UINT NeededSize, CD3DDDIDX6* pDDI);
BYTE* LockDiscard(UINT NeededSize, CD3DDDIDX6* pDDI);
virtual void Unlock();
virtual void AddVertices(UINT NumVertices)
{
m_dwUsedSize = m_dwPrimitiveBase + NumVertices * m_dwStride;
DXGASSERT(m_dwSize >= m_dwUsedSize);
}
virtual void SubVertices(UINT NumVertices)
{
DXGASSERT(m_dwUsedSize >= NumVertices * m_dwStride);
m_dwUsedSize -= NumVertices * m_dwStride;
DXGASSERT(m_dwSize >= m_dwUsedSize);
}
virtual void MovePrimitiveBase(int NumVertices)
{
m_dwPrimitiveBase += NumVertices * m_dwStride;
}
virtual void SkipVertices(DWORD NumVertices)
{
const UINT size = NumVertices * m_dwStride;
m_dwPrimitiveBase += size;
m_dwUsedSize = m_dwPrimitiveBase;
DXGASSERT(m_dwSize >= m_dwUsedSize);
}
protected:
// Number of bytes used in the buffer
// It is not used by CTLStreamRO
DWORD m_dwUsedSize;
// Index of a index, which is the start of the current primitive
DWORD m_dwPrimitiveBase;
#if !DBG
DWORD m_dwSize;
#endif
};
// This class is used to keep track of what set to a DDI stream
struct CDDIStream
{
CDDIStream()
{
m_pStream = NULL;
m_dwStride = 0;
m_pBuf = NULL;
}
// Pointer to a stream object
CVStreamBase* m_pStream;
// Stride of the currently set stream
DWORD m_dwStride;
// VB pointer of the currently set stream
CBuffer *m_pBuf;
};
/////////////////////////////////////////////////////////////////////////////
// //
// CD3DDDIDX6 //
// //
/////////////////////////////////////////////////////////////////////////////
//--------------------------------------------------------------------
// Flags for dwDP2Flags
//
// This flag is set if the current TLVbuf is write only
const DWORD D3DDDI_TLVBUFWRITEONLY = 1 << 0;
// This flag is set we pass user memory to the DDI
const DWORD D3DDDI_USERMEMVERTICES = 1 << 1;
// Set when DrawIndexPrim is called. It is used to check if vertices
// of an indexed primitive were used at all. They could not be used because
// of clipping.
const DWORD D3DDDI_INDEXEDPRIMDRAWN = 1 << 2;
typedef void (CD3DDDIDX6::* PFN_PROCESSPRIM)(D3DFE_PROCESSVERTICES*,
UINT StartVertex);
class CD3DDDIDX6 : public CD3DDDI
{
public:
CD3DDDIDX6();
~CD3DDDIDX6();
// Virtual functions -----------------------------------------------
virtual void Init(CD3DBase* pDevice );
virtual void SetRenderTarget(CBaseSurface*, CBaseSurface*);
virtual void FlushStates(BOOL bReturnDriverError=FALSE, BOOL bWithinPrimitive = FALSE);
virtual void ValidateDevice(LPDWORD lpdwNumPasses);
virtual void Clear(DWORD dwFlags, DWORD clrCount, LPD3DRECT clrRects,
D3DCOLOR dwColor, D3DVALUE dvZ, DWORD dwStencil);
virtual HRESULT __declspec(nothrow) LockVB(CDriverVertexBuffer*, DWORD dwFlags);
virtual HRESULT __declspec(nothrow) UnlockVB(CDriverVertexBuffer*);
virtual void ClearBatch( BOOL bWithinPrimitive );
virtual void SceneCapture(BOOL bState);
// This function is called whe software vertex processing is used
// Handle should be always legacy
virtual void SetVertexShader(DWORD dwHandle);
// This function is called whe hardware vertex processing is used
virtual void SetVertexShaderHW(DWORD dwHandle);
virtual void UpdatePalette(DWORD,DWORD,DWORD,PALETTEENTRY*);
virtual void SetPalette(DWORD,DWORD,CBaseTexture*);
// Used to pick a function to process (indexed) primitive
// The picking is based on
// D3DDEV_DONOTCLIP
// FVF_TRANSFORMED(m_pDevice->m_dwCurrentShaderHandle)
// D3DDEV_DOPOINTSPRITEEMULATION
virtual void PickProcessPrimitive();
virtual void SetTSS(DWORD, D3DTEXTURESTAGESTATETYPE, DWORD);
virtual void DrawPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType,
UINT PrimitiveCount);
virtual void DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType,
UINT MinVertexIndex,
UINT NumVertices,
UINT PrimitiveCount);
// Returns max number of renderstates, handled by the DDI
virtual D3DRENDERSTATETYPE GetMaxRenderState()
{return D3DRENDERSTATE_CLIPPING;}
// Returns max number of texture stage states, handled by the DDI
virtual D3DTEXTURESTAGESTATETYPE GetMaxTSS()
{return D3DTSS_TEXTURETRANSFORMFLAGS;}
// Returns TRUE if the device supports T&L
virtual BOOL CanDoTL() {return FALSE;}
// DDI can directly accept index buffer
virtual BOOL AcceptIndexBuffer() {return FALSE;}
virtual BOOL CanDoTLVertexClipping() {return FALSE;}
// Process primitive with untransformed vertices and with no clipping
virtual void ProcessPrimitive(D3DFE_PROCESSVERTICES* pv, UINT StartVertex);
virtual void ProcessIndexedPrimitive(D3DFE_PROCESSVERTICES* pv,
UINT StartVertex);
// Process primitive with untransformed vertices and with clipping
virtual void ProcessPrimitiveC(D3DFE_PROCESSVERTICES* pv,
UINT StartVertex);
virtual void ProcessIndexedPrimitiveC(D3DFE_PROCESSVERTICES* pv,
UINT StartVertex);
virtual void SetViewport(CONST D3DVIEWPORT8*);
virtual void StartPrimVB(D3DFE_PROCESSVERTICES * pv, CVStream* pStream,
DWORD dwStartVertex);
virtual LPVOID StartPrimTL(D3DFE_PROCESSVERTICES*, DWORD dwVertexPoolSize,
BOOL bWriteOnly);
virtual void StartPointSprites();
virtual void EndPointSprites();
// Virtual functions: Empty implementations ------------------------
virtual void SetTransform(D3DTRANSFORMSTATETYPE, CONST D3DMATRIX*){}
virtual void MultiplyTransform(D3DTRANSFORMSTATETYPE, CONST D3DMATRIX*){}
virtual void SetMaterial(CONST D3DMATERIAL8*){}
virtual void CreateLight(DWORD dwLightIndex) {}
virtual void SetLight(DWORD dwLightIndex, CONST D3DLIGHT8*){}
virtual void LightEnable(DWORD dwLightIndex, BOOL){}
virtual void SetClipPlane(DWORD dwPlaneIndex,
CONST D3DVALUE* pPlaneEquation){}
virtual void WriteStateSetToDevice(D3DSTATEBLOCKTYPE sbt) {}
// Used to notify DDI that a vertex buffer was released. If the DDI keeps a
// pointer to the VB it should be zeroed
virtual void VBReleased(CBuffer *pBuf) {}
// Used to notify DDI that amn index buffer was released. If the DDI keeps
// a pointer to the IB it should be zeroed
virtual void VBIReleased(CBuffer *pBuf) {}
virtual void ResetVertexShader() {}
virtual void SetVertexShaderConstant(DWORD dwRegisterAddress,
CONST VOID* lpvConstantData,
DWORD dwConstantCount){}
virtual void SetPixelShaderConstant(DWORD dwRegisterAddress,
CONST VOID* lpvConstantData,
DWORD dwConstantCount){}
// Virtual functions: Unsupported implementations ------------------
virtual void SetPriority(CResource*, DWORD dwPriority)
{ NotSupported("SetPriority");}
virtual void SetTexLOD(CBaseTexture*, DWORD dwLOD)
{ NotSupported("SetTexLOD");}
virtual void TexBlt(DWORD dwDst, DWORD dwSrc,
LPPOINT p, RECTL *r)
{ NotSupported("TexBlt");}
virtual void VolBlt(CBaseTexture *lpDst, CBaseTexture* lpSrc,
DWORD dwDestX, DWORD dwDestY, DWORD dwDestZ,
D3DBOX *pBox)
{ NotSupported("VolBlt");}
virtual void BufBlt(CBuffer *lpDst, CBuffer* lpSrc,
DWORD dwOffset, D3DRANGE* pRange)
{ NotSupported("BufBlt");}
virtual void AddDirtyRect(DWORD dwHandle,
CONST RECTL *pRect)
{ NotSupported("AddDirtyRect");}
virtual void AddDirtyBox(DWORD dwHandle,
CONST D3DBOX *pBox)
{ NotSupported("AddDirtyRect");}
virtual void InsertStateSetOp(DWORD dwOperation, DWORD dwParam,
D3DSTATEBLOCKTYPE sbt)
{ NotSupported("InsertStateSetOp");}
virtual void CreateVertexShader(CONST DWORD* pdwDeclaration,
DWORD dwDeclarationSize,
CONST DWORD* pdwFunction,
DWORD dwFunctionSize,
DWORD dwHandle,
BOOL bLegacyFVF)
{ NotSupported("CreateVertexShader");}
virtual void DeleteVertexShader(DWORD dwHandle)
{ NotSupported("DeleteVertexShader");}
virtual void CreatePixelShader(CONST DWORD* pdwFunction,
DWORD dwFunctionSize,
DWORD dwHandle)
{ NotSupported("CreatePixelShader");}
virtual void SetPixelShader(DWORD dwHandle) {}
virtual void DeletePixelShader(DWORD dwHandle)
{ NotSupported("DeletePixelShader");}
virtual void GetInfo(DWORD dwDevInfoID, LPVOID pDevInfoStruct,
DWORD dwSize)
{ NotSupported("GetInfo");}
virtual void DrawRectPatch(UINT Handle, CONST D3DRECTPATCH_INFO *pSurf,
CONST FLOAT *pNumSegs)
{ NotSupported("DrawRectPatch");}
virtual void DrawTriPatch(UINT Handle, CONST D3DTRIPATCH_INFO *pSurf,
CONST FLOAT *pNumSegs)
{ NotSupported("DrawTriPatch");}
// Non Virtual functions -------------------------------------------
void CreateContext();
void DestroyContext();
void SetRenderState(D3DRENDERSTATETYPE, DWORD);
void FlushStatesReq(DWORD dwReqSize);
void FlushStatesCmdBufReq(DWORD dwReqSize);
void SetStreamSource(UINT StreamIndex, CVStream*);
void SetIndices(CVIndexStream*);
// Update W range in device. Projection matrix is passed as parameter
void UpdateWInfo(CONST D3DMATRIX* lpMat);
// Process points with point sprite expansion
void ProcessPointSprites(D3DFE_PROCESSVERTICES* pv, UINT StartVertex);
// Process primitive with transformed vertices and with clipping
void ProcessPrimitiveTC(D3DFE_PROCESSVERTICES* pv, UINT StartVertex);
void ProcessIndexedPrimitiveTC(D3DFE_PROCESSVERTICES* pv,
UINT StartVertex);
void NotSupported(char* msg);
void BeginScene()
{
SceneCapture(TRUE);
}
void EndScene();
void EndPrim(UINT vertexSize);
void NextSprite(float x, float y, float z, float w, DWORD diffuse,
DWORD specular, float* pTexture, UINT TextureSize,
float PointSize);
void AddVertices(UINT NumVertices)
{
if (dwDP2VertexCountMask)
{
dwDP2VertexCount = max(dwVertexBase + NumVertices, dwDP2VertexCount);
}
}
void SubVertices(UINT NumVertices)
{
if (dwDP2VertexCountMask)
{
DXGASSERT(dwDP2VertexCount >= NumVertices);
dwDP2VertexCount -= NumVertices;
}
}
void MovePrimitiveBase(int NumVertices)
{
dwVertexBase += NumVertices;
}
void SkipVertices(DWORD NumVertices)
{
dwVertexBase += NumVertices;
if (dwDP2VertexCountMask)
dwDP2VertexCount = max(dwVertexBase, dwDP2VertexCount);
}
void SetWithinPrimitive( BOOL bWP ){ m_bWithinPrimitive = bWP; }
BOOL GetWithinPrimitive(){ return m_bWithinPrimitive; }
D3DDDITYPE GetDDIType() {return m_ddiType;}
CD3DBase* GetDevice() {return m_pDevice;}
ULONG_PTR GetDeviceContext() {return m_dwhContext;}
virtual PFN_DRAWPRIMFAST __declspec(nothrow) GetDrawPrimFunction()
{
return CD3DDDIDX6_DrawPrimitive;
}
virtual PFN_DRAWINDEXEDPRIMFAST __declspec(nothrow) GetDrawIndexedPrimFunction()
{
return CD3DDDIDX6_DrawIndexedPrimitive;
}
// Implementation of base functions ---------------------------------
// Draw non-indexed primitive
void DrawPrim(D3DFE_PROCESSVERTICES* pv);
// Draw point sprites with emulation
void DrawPrimPS(D3DFE_PROCESSVERTICES* pv);
// Draw primitive, generated by the clipper
void DrawClippedPrim(D3DFE_PROCESSVERTICES* pv);
// Draw indexed primitive
void DrawIndexPrim(D3DFE_PROCESSVERTICES* pv);
protected:
// DDI Type
D3DDDITYPE m_ddiType;
CD3DBase* m_pDevice;
DWORD m_dwInterfaceNumber;
// Driver context
ULONG_PTR m_dwhContext;
// Is it within primitive
BOOL m_bWithinPrimitive;
PFN_PROCESSPRIM m_pfnProcessPrimitive;
PFN_PROCESSPRIM m_pfnProcessIndexedPrimitive;
// Reserve space in the command buffer. Flush and grow if needed.
// Returns pointer to where new commands could be inserted
LPVOID ReserveSpaceInCommandBuffer(UINT ByteCount);
// Reserve space for a new command in the command buffer. Flush if needed
// New command is initialized.
// Returns pointer to where the command data could be inserted
LPVOID GetHalBufferPointer(D3DHAL_DP2OPERATION op, DWORD dwDataSize);
DWORD GetTLVbufSize() { return TLVbuf_size - TLVbuf_base; }
DWORD& TLVbuf_Base() { return TLVbuf_base; }
LPVOID TLVbuf_GetAddress() {return (LPBYTE)alignedBuf + TLVbuf_base;}
void GrowCommandBuffer(DWORD dwSize);
void GrowTLVbuf(DWORD growSize, BOOL bWriteOnly);
void PrepareForClipping(D3DFE_PROCESSVERTICES* pv, UINT StartVertex);
void StartPrimUserMem(D3DFE_PROCESSVERTICES*, UINT VertexPoolSize);
inline CVertexBuffer* TLVbuf_GetVBI() { return allocatedBuf; }
#if DBG
void ValidateVertex(LPDWORD lpdwVertex);
virtual void ValidateCommand(LPD3DHAL_DP2COMMAND lpCmd);
#endif
static const DWORD dwD3DDefaultCommandBatchSize;
// Index (relative to the TLVbuf start) of the first vertex of
// the current primitive
DWORD dwVertexBase;
// Number of vertices in the DP2 vertex buffer
DWORD dwDP2VertexCount;
// Mask used to prevent modification of dwDP2VertexCount. This is needed
// when user calls SetStreamSource with TL vertices and uses multiple
// DrawPrimitive calls with different StartVertex. dwDP2VertexCount should
// be always set to the number of vertices in the user vertex buffer.
DWORD dwDP2VertexCountMask;
// This is the VB interface corresponding to the dp2data.lpDDVertex
// This is kept so that the VB can be released when done
// which cannot be done from just the LCL pointer which is lpDDVertex
CVertexBuffer* lpDP2CurrBatchVBI;
DWORD TLVbuf_size;
DWORD TLVbuf_base;
#ifdef VTABLE_HACK
// Cached dwFlags for fast path
DWORD dwLastFlags;
// Last VB used in a call that involved D3D's FE.
CVertexBuffer* lpDP2LastVBI;
#endif
DWORD dwDP2CommandBufSize;
DWORD dwDP2CommandLength;
// Cache line should start here
// Pointer to the actual data in CB1
LPVOID lpvDP2Commands;
//Pointer to the current position the CB1 buffer
LPD3DHAL_DP2COMMAND lpDP2CurrCommand;
// Perf issue: replace the below 3 fields by a 32 bit D3DHAL_DP2COMMAND struct
WORD wDP2CurrCmdCnt; // Mirror of Count field if the current command
BYTE bDP2CurrCmdOP; // Mirror of Opcode of the current command
BYTE bDummy; // Force DWORD alignment of next member
D3D8_DRAWPRIMITIVES2DATA dp2data;
// The buffer we currently batch into
CCommandBuffer *lpDDSCB1;
CVertexBuffer *allocatedBuf;
LPVOID alignedBuf;
CVertexBuffer *m_pNullVB;
// Count read/write <-> write-only transistions
DWORD dwTLVbufChanges;
// Flags specific to DP2 device
DWORD dwDP2Flags;
// This stuff is allocated by the NT Kernel. Need to keep
// it around to pass it to all the DP2 calls. Kernel validates
// this pointer.
WORD *lpwDPBuffer;
// Used to offset indices in DrawIndexPrim
DWORD m_dwIndexOffset;
// Data to draw point sprites
// Pointer where to insert the next point sprite vertex
BYTE* m_pCurSpriteVertex;
// Pointer where to insert the next point sprite index
WORD* m_pCurPointSpriteIndex;
// Number of sprites in the current point sprite batch
UINT m_CurNumberOfSprites;
// When we need to expand points to quads, we use this stream to process
// vertices into
CTLStream* m_pPointStream;
// These is used to keep the original dwVertexBase and dwDP2VertexCount,
// when processing point sprites
DWORD m_dwVertexBasePS;
DWORD m_dwVertexCountPS;
// Output vertex FVF for point sprite emulation
DWORD m_dwVIDOutPS;
// Output vertex size for point sprites emulation
DWORD m_dwOutputSizePS;
DWORD dwDPBufferSize;
// Vertex shader handle currently set to the device driver
DWORD m_CurrentVertexShader;
// Currently used stream 0
CVStream* m_pStream0;
// Currently used index stream
CVIndexStream* m_pIStream;
#if DBG
// Vertex size, computed from the vertex shader
DWORD m_VertexSizeFromShader;
// Switches on/off command and vertices validation
BOOL m_bValidateCommands;
#endif
friend class CD3DHal;
friend void CD3DDDIDX6_DrawPrimitive(CD3DBase* pDevice,
D3DPRIMITIVETYPE primType,
UINT StartVertex,
UINT PrimitiveCount);
friend void CD3DDDIDX6_DrawPrimitiveFast(CD3DBase* pDevice,
D3DPRIMITIVETYPE primType,
UINT StartVertex,
UINT PrimitiveCount);
friend void CD3DDDIDX6_DrawIndexedPrimitive(CD3DBase* pDevice,
D3DPRIMITIVETYPE PrimitiveType,
UINT BaseVertexIndex,
UINT MinIndex, UINT NumVertices,
UINT StartIndex, UINT PrimitiveCount);
friend void CD3DDDIDX6_DrawIndexedPrimitiveFast(CD3DBase* pDevice,
D3DPRIMITIVETYPE primType,
UINT BaseVertexIndex,
UINT MinIndex, UINT NumVertices,
UINT StartIndex, UINT PrimitiveCount);
friend void CD3DHal_DrawPrimitive(CD3DBase* pBaseDevice,
D3DPRIMITIVETYPE PrimitiveType,
UINT StartVertex, UINT PrimitiveCount);
friend void CD3DHal_DrawIndexedPrimitive(CD3DBase* pBaseDevice,
D3DPRIMITIVETYPE PrimitiveType,
UINT BaseIndex,
UINT MinIndex, UINT NumVertices,
UINT StartIndex,
UINT PrimitiveCount);
};
typedef CD3DDDIDX6 *LPD3DDDIDX6;
/////////////////////////////////////////////////////////////////////////////
// //
// CD3DDDIDX7 //
// //
/////////////////////////////////////////////////////////////////////////////
class CD3DDDIDX7 : public CD3DDDIDX6
{
public:
CD3DDDIDX7();
~CD3DDDIDX7();
void SetRenderTarget(CBaseSurface*, CBaseSurface*);
void InsertStateSetOp(DWORD dwOperation, DWORD dwParam,
D3DSTATEBLOCKTYPE sbt);
void Clear(DWORD dwFlags, DWORD clrCount, LPD3DRECT clrRects,
D3DCOLOR dwColor, D3DVALUE dvZ, DWORD dwStencil);
void TexBlt(DWORD dwDst, DWORD dwSrc, LPPOINT p, RECTL *r);
void SetPriority(CResource*, DWORD dwPriority);
void SetTexLOD(CBaseTexture*, DWORD dwLOD);
void AddDirtyRect(DWORD dwHandle, CONST RECTL *pRect);
void AddDirtyBox(DWORD dwHandle, CONST D3DBOX *pBox);
void UpdatePalette(DWORD,DWORD,DWORD,PALETTEENTRY*);
void SetPalette(DWORD,DWORD,CBaseTexture*);
void WriteStateSetToDevice(D3DSTATEBLOCKTYPE sbt);
virtual void SceneCapture(BOOL bState);
virtual D3DTEXTURESTAGESTATETYPE GetMaxTSS()
{return (D3DTEXTURESTAGESTATETYPE)(D3DTSS_TEXTURETRANSFORMFLAGS+1);}
};
typedef CD3DDDIDX7 *LPD3DDDIDX7;
/////////////////////////////////////////////////////////////////////////////
// //
// CD3DDDITL //
// //
/////////////////////////////////////////////////////////////////////////////
class CD3DDDITL : public CD3DDDIDX7
{
public:
CD3DDDITL();
~CD3DDDITL();
void SetTransform(D3DTRANSFORMSTATETYPE, CONST D3DMATRIX*);
void SetVertexShader(DWORD dwHandle);
void SetVertexShaderHW(DWORD dwHandle);
void SetViewport(CONST D3DVIEWPORT8*);
void SetMaterial(CONST D3DMATERIAL8*);
void SetLight(DWORD dwLightIndex, CONST D3DLIGHT8*);
void LightEnable(DWORD dwLightIndex, BOOL);
void CreateLight(DWORD dwLightIndex);
void SetClipPlane(DWORD dwPlaneIndex, CONST D3DVALUE* pPlaneEquation);
D3DRENDERSTATETYPE GetMaxRenderState()
{return (D3DRENDERSTATETYPE)(D3DRENDERSTATE_CLIPPLANEENABLE + 1);}
BOOL CanDoTL() {return TRUE;}
BOOL CanDoTLVertexClipping() {return TRUE;}
void CreateVertexShader(CONST DWORD* pdwDeclaration,
DWORD dwDeclarationSize,
CONST DWORD* pdwFunction,
DWORD dwFunctionSize,
DWORD dwHandle,
BOOL bLegacyFVF);
};
typedef CD3DDDITL *LPD3DDDITL;
/////////////////////////////////////////////////////////////////////////////
// //
// CD3DDDIDX8 //
// //
/////////////////////////////////////////////////////////////////////////////
class CD3DDDIDX8 : public CD3DDDIDX7
{
public:
CD3DDDIDX8();
~CD3DDDIDX8();
void Init(CD3DBase* pDevice );
void SetDummyData();
void FlushStates(BOOL bReturnDriverError=FALSE, BOOL bWithinPrimitive = FALSE);
void ClearBatch( BOOL bWithinPrimitive );
HRESULT __declspec(nothrow) LockVB(CDriverVertexBuffer*, DWORD dwFlags);
HRESULT __declspec(nothrow) UnlockVB(CDriverVertexBuffer*);
D3DRENDERSTATETYPE GetMaxRenderState();
D3DTEXTURESTAGESTATETYPE GetMaxTSS()
{return (D3DTEXTURESTAGESTATETYPE)(D3DTSS_RESULTARG+1);}
void SetTSS(DWORD, D3DTEXTURESTAGESTATETYPE, DWORD);
void SetVertexShader(DWORD dwHandle);
void SetVertexShaderHW(DWORD dwHandle);
void ValidateDevice(LPDWORD lpdwNumPasses);
void VolBlt(CBaseTexture *lpDst, CBaseTexture* lpSrc, DWORD dwDestX,
DWORD dwDestY, DWORD dwDestZ, D3DBOX *pBox);
void BufBlt(CBuffer *lpDst, CBuffer* lpSrc, DWORD dwOffset,
D3DRANGE* pRange);
void CreatePixelShader(CONST DWORD* pdwFunction,
DWORD dwFunctionSize,
DWORD dwHandle);
void SetPixelShader(DWORD dwHandle);
void DeletePixelShader(DWORD dwHandle);
void SetPixelShaderConstant(DWORD dwRegisterAddress,
CONST VOID* lpvConstantData,
DWORD dwConstantCount);
void DrawPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount);
void DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType,
UINT MinVertexIndex,
UINT NumVertices,
UINT PrimitiveCount);
BOOL AcceptIndexBuffer() {return TRUE;}
BOOL CanDoTLVertexClipping() {return TRUE;}
void DrawRectPatch(UINT Handle, CONST D3DRECTPATCH_INFO *pSurf,
CONST FLOAT *pNumSegs);
void DrawTriPatch(UINT Handle, CONST D3DTRIPATCH_INFO *pSurf,
CONST FLOAT *pNumSegs);
void PickProcessPrimitive();
// Process primitive with untransformed vertices and with no clipping
void ProcessPrimitive(D3DFE_PROCESSVERTICES* pv, UINT StartVertex);
void ProcessIndexedPrimitive(D3DFE_PROCESSVERTICES* pv, UINT StartVertex);
// Process primitive with untransformed vertices and with clipping
void ProcessPrimitiveC(D3DFE_PROCESSVERTICES* pv, UINT StartVertex);
void ProcessIndexedPrimitiveC(D3DFE_PROCESSVERTICES* pv, UINT StartVertex);
// Process primitive with transformed vertices
void ProcessPrimitiveT(D3DFE_PROCESSVERTICES* pv, UINT StartVertex);
void ProcessIndexedPrimitiveT(D3DFE_PROCESSVERTICES* pv, UINT StartVertex);
void StartPrimVB(D3DFE_PROCESSVERTICES * pv, CVStream* pStream,
DWORD dwStartVertex);
LPVOID StartPrimTL(D3DFE_PROCESSVERTICES*, DWORD dwVertexPoolSize,
BOOL bWriteOnly);
void DrawPrim(D3DFE_PROCESSVERTICES* pv);
void DrawIndexPrim(D3DFE_PROCESSVERTICES* pv);
void DrawClippedPrim(D3DFE_PROCESSVERTICES* pv);
void VBReleased(CBuffer *pBuf)
{
if (m_pDDIStream[0].m_pBuf == pBuf)
m_pDDIStream[0].m_pBuf = NULL;
}
void VBIReleased(CBuffer *pBuf)
{
if (m_pDDIStream[__NUMSTREAMS].m_pBuf == pBuf)
m_pDDIStream[__NUMSTREAMS].m_pBuf = NULL;
}
void AddVertices(UINT NumVertices)
{
m_pCurrentTLStream->AddVertices(NumVertices);
}
void MovePrimitiveBase(int NumVertices)
{
m_pCurrentTLStream->MovePrimitiveBase(NumVertices);
}
void SkipVertices(DWORD NumVertices)
{
m_pCurrentTLStream->SkipVertices(NumVertices);
}
// Returns offset in bytes of the start vertex of the current primitive in
// the current TL stream
DWORD GetCurrentPrimBase()
{
return m_pCurrentTLStream->GetPrimitiveBase();
}
void ResetVertexShader()
{
m_CurrentVertexShader = 0;
#if DBG
m_VertexSizeFromShader = 0;
#endif
}
PFN_DRAWPRIMFAST __declspec(nothrow) GetDrawPrimFunction() {return CD3DDDIDX8_DrawPrimitive;}
PFN_DRAWINDEXEDPRIMFAST __declspec(nothrow) GetDrawIndexedPrimFunction()
{
return CD3DDDIDX8_DrawIndexedPrimitive;
}
protected:
void StartPointSprites();
void EndPointSprites();
void StartIndexPrimVB(CVIndexStream* pStream, UINT StartIndex, UINT IndexSize);
void UpdateDirtyStreams();
void InsertStreamSource(CVStream*);
void InsertStreamSourceUP(DWORD);
void InsertIndices(CVIndexStream*);
#if DBG
void ValidateCommand(LPD3DHAL_DP2COMMAND lpCmd);
#endif
// This array is used to keep track of what stream is set to a DDI stream.
// __NUMSTREAMS element is used for the indexed DDI stream
CDDIStream m_pDDIStream[__NUMSTREAMS+1];
// Stream for TL vertices, which are the result of the front-end pipeline
CTLStream* m_pTLStream;
// Stream for TL vertices, which are the result of the front-end pipeline
// This is write-only stream
CTLStream* m_pTLStreamW;
// Stream for TL vertices, generated by the clipper. Write-only stream
CTLStream* m_pTLStreamClip;
// Read-only stream. Used with user provided VBs
CTLStreamRO* m_pTLStreamRO;
// Points to the current TL stream. This could be NULL.
CTLStream* m_pCurrentTLStream;
// Points to the current index stream. This could be NULL.
CTLIndexStream* m_pCurrentIndexStream;
// Internal index stream. Used to store indices during clipping
CTLIndexStream* m_pIndexStream;
// Read-only index stream. Used with user provided VBs
CTLIndexStreamRO* m_pTLIndexStreamRO;
// This is a dummy buffer allocated for DP2 call to pass through
// the kernel.
VOID* m_pvDummyArray;
static const DWORD m_dwDummyVertexLength;
static const DWORD m_dwDummyVertexSize;
friend void CD3DDDIDX8_DrawPrimitive(CD3DBase* pDevice,
D3DPRIMITIVETYPE PrimitiveType,
UINT StartVertex, UINT PrimitiveCount);
friend void CD3DDDIDX8_DrawIndexedPrimitive(CD3DBase* pDevice,
D3DPRIMITIVETYPE PrimitiveType,
UINT BaseVertexIndex,
UINT MinIndex, UINT NumVertices,
UINT StartIndex, UINT PrimitiveCount);
};
typedef CD3DDDIDX8 *LPD3DDDIDX8;
/////////////////////////////////////////////////////////////////////////////
// //
// CD3DDDIDX8TL //
// //
/////////////////////////////////////////////////////////////////////////////
class CD3DDDIDX8TL : public CD3DDDIDX8
{
public:
CD3DDDIDX8TL();
~CD3DDDIDX8TL();
void SetTransform(D3DTRANSFORMSTATETYPE, CONST D3DMATRIX*);
void MultiplyTransform(D3DTRANSFORMSTATETYPE, CONST D3DMATRIX*);
void SetViewport(CONST D3DVIEWPORT8*);
void SetMaterial(CONST D3DMATERIAL8*);
void SetLight(DWORD dwLightIndex, CONST D3DLIGHT8*);
void LightEnable(DWORD dwLightIndex, BOOL);
void CreateLight(DWORD dwLightIndex);
void SetClipPlane(DWORD dwPlaneIndex, CONST D3DVALUE* pPlaneEquation);
void CreateVertexShader(CONST DWORD* pdwDeclaration,
DWORD dwDeclarationSize,
CONST DWORD* pdwFunction,
DWORD dwFunctionSize,
DWORD dwHandle,
BOOL bLegacyFVF);
void DeleteVertexShader(DWORD dwHandle);
void SetVertexShaderConstant(DWORD dwRegisterAddress,
CONST VOID* lpvConstantData,
DWORD dwConstantCount);
BOOL CanDoTL() {return TRUE;}
BOOL AcceptIndexBuffer() {return TRUE;}
};
typedef CD3DDDIDX8TL *LPD3DDDIDX8TL;
#endif /* _D3DI_H */