837 lines
35 KiB
C++
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 */
|