/////////////////////////////////////////////////////////////////////////////// // // ## ###### // ###### ### // ## ############### Shark 3D Engine (www.shark3d.com) // ########## # # # // ######## Copyright (c) 1996-2006 Spinor GmbH. // ######### # # # All rights reserved. // ## ########## // ## // /////////////////////////////////////////////////////////////////////////////// //@cpp #ifndef S3D_DRV_D3D9_BUF_H #define S3D_DRV_D3D9_BUF_H #include "drv_d3d9_types.h" #include "drv_d3d9_vertdecl.h" #include "drv_d3d9_param.h" #include "drv_d3d9_progmgr.h" #include "drv_d3d9_env.h" #include "util/cont/util_deque.h" /////////////////////////////////////////////////////////////////////////////// //@ struct s3d_CDrvD3d9VertBufDesc { s3d_CDrvGfxAttr *m_PointAttr; s3d_CDrvGfxAttr *m_ColorAlphaAttr; s3d_CDrvGfxAttr *m_NormalAttr; s3d_CDrvGfxAttr *m_BoneWghAttr; s3d_CDrvGfxAttr *m_BoneSubscrAttr; s3d_CDrvGfxAttr *m_TexAttrArray[S3D_DRV_D3D9_MAX_ATTR_CNT]; s3d_CSysIntps m_VertElemCnt; D3DVERTEXELEMENT9 m_VertElemArray[S3D_DRV_D3D9_MAX_VERTELEM_CNT]; s3d_CSysIntps m_VertSize; int m_VertBufFmtDecl; s3d_CDrvD3d9VertBufDesc(); void Reset(); //@ enum CDecl { //@ Decl_Generic = (1 << 0), //@ Decl_Point = (1 << 1), //@ Decl_ColorAlpha = (1 << 2), //@ Decl_Normal = (1 << 3), //@ Decl_BoneWgh = (1 << 4), //@ Decl_BoneSubscr = (1 << 5), //@ Decl_DummyBoneWgh = (1 << 6), //@ Decl_DummyBoneSubscr = (1 << 7), }; }; //@ typedef const s3d_CDrvD3d9VertBufDesc &s3d_CDrvD3d9VertBufDesc_cr; /////////////////////////////////////////////////////////////////////////////// class s3d_CDrvD3d9DummyWghBank : public s3d_CDrvBank { public: s3d_CDrvD3d9DummyWghBank(); void Fetch( s3d_CUtilMsgHandler *MsgHandler, const s3d_CSysChar *Info, s3d_CDrvBankContent &BankContent); s3d_CUtilPtrBase *GetOwner( s3d_CUtilMsgHandler *MsgHandler, const s3d_CSysChar *Info); private: float m_Data[4]; }; /////////////////////////////////////////////////////////////////////////////// struct s3d_CDrvD3d9DummyWghAttr : public s3d_CDrvGfxAttr { s3d_CDrvD3d9DummyWghAttr(); s3d_CDrvD3d9DummyWghBank m_DummyWghBank; }; /////////////////////////////////////////////////////////////////////////////// class s3d_CDrvD3d9DummySubscrBank : public s3d_CDrvBank { public: s3d_CDrvD3d9DummySubscrBank(); void Fetch( s3d_CUtilMsgHandler *MsgHandler, const s3d_CSysChar *Info, s3d_CDrvBankContent &BankContent); s3d_CUtilPtrBase *GetOwner( s3d_CUtilMsgHandler *MsgHandler, const s3d_CSysChar *Info); private: s3d_CSysInt32u m_Data[4]; }; /////////////////////////////////////////////////////////////////////////////// struct s3d_CDrvD3d9DummySubscrAttr : public s3d_CDrvGfxAttr { s3d_CDrvD3d9DummySubscrAttr(); s3d_CDrvD3d9DummySubscrBank m_DummySubscrBank; }; /////////////////////////////////////////////////////////////////////////////// //@ struct s3d_CDrvD3d9VertBufObj : public s3d_CUtilPtrBase { s3d_CUtilStr m_MainInfo; s3d_CDrvD3d9VertBuf m_VertBuf; s3d_CSysIntps m_BufSize; s3d_CSysIntps m_VertSize; s3d_CDrvD3d9VertDecl m_VertDecl; int m_VertBufFmtDecl; DWORD m_Usage; D3DPOOL m_Pool; s3d_CUtilMsgHandlerPtr m_ReportMsgHandler; ~s3d_CDrvD3d9VertBufObj(); void Reset(); }; //@ typedef s3d_CUtilPtr s3d_CDrvD3d9VertBufObjPtr; /////////////////////////////////////////////////////////////////////////////// //@ struct s3d_CDrvD3d9VertBufAttr { bool m_BankDyn; s3d_CDrvSigPtr m_BankSig; int m_Chan; int m_Slot; }; /////////////////////////////////////////////////////////////////////////////// //@ struct s3d_CDrvD3d9VertBufObjBatch : public s3d_CDrvD3d9VertBufObj { s3d_CDrvD3d9VertBufObjBatch(); ~s3d_CDrvD3d9VertBufObjBatch(); s3d_CUtilStr m_MainInfo; bool m_Complete; s3d_CDrvSigPtr m_TopolSig; s3d_CSysIntps m_AttrCnt; s3d_CUtilOwnArray m_AttrArray; s3d_CUtilTree::CNode m_Node; }; //@ typedef s3d_CUtilPtr s3d_CDrvD3d9VertBufObjBatchPtr; //@ typedef s3d_CUtilTree s3d_CDrvD3d9VertBufObjBatchTree; /////////////////////////////////////////////////////////////////////////////// //@ struct s3d_CDrvD3d9VertBufObjBatchRef { s3d_CDrvSig *m_TopolSig; s3d_CDrvGfxAttr *m_AttrArray; s3d_CSysIntps m_AttrCnt; static int Compare( const s3d_CDrvD3d9VertBufObjBatch *VertBufObj, const s3d_CDrvD3d9VertBufObjBatchRef &Ref); }; //@ bool operator==( const s3d_CDrvD3d9VertBufObjBatch *VertBufObj, const s3d_CDrvD3d9VertBufObjBatchRef &Ref); //@ bool operator<( const s3d_CDrvD3d9VertBufObjBatch *VertBufObj, const s3d_CDrvD3d9VertBufObjBatchRef &Ref); /////////////////////////////////////////////////////////////////////////////// //@ struct s3d_CDrvD3d9Packet { s3d_CSysInt32u m_VertCnt; s3d_CSysInt32u m_IdxCnt; s3d_CSysInt32u m_PrimCnt; s3d_CSysInt32u m_BoneIdxCnt; }; /////////////////////////////////////////////////////////////////////////////// //@ struct s3d_CDrvD3d9IdxBufObj : public s3d_CUtilPtrBase { s3d_CDrvD3d9IdxBuf m_IdxBuf; s3d_CSysIntps m_IdxCnt; s3d_CSysIntps m_BufSize; D3DFORMAT m_Fmt; D3DPRIMITIVETYPE m_D3dPrim; DWORD m_Usage; D3DPOOL m_Pool; s3d_CUtilMsgHandlerPtr m_ReportMsgHandler; ~s3d_CDrvD3d9IdxBufObj(); void Reset(); }; //@ typedef s3d_CUtilPtr s3d_CDrvD3d9IdxBufObjPtr; /////////////////////////////////////////////////////////////////////////////// //@ struct s3d_CDrvD3d9IdxBufObjBatch : public s3d_CDrvD3d9IdxBufObj { s3d_CDrvD3d9IdxBufObjBatch(); ~s3d_CDrvD3d9IdxBufObjBatch(); s3d_CSysIntps m_BoneIdxCnt; s3d_CUtilOwnArray m_BoneIdxArray; s3d_CSysIntps m_PacketCnt; s3d_CUtilOwnArray m_PacketArray; s3d_CDrvSigPtr m_TopolSig; s3d_CUtilTree::CNode m_Node; }; //@ typedef s3d_CUtilPtr s3d_CDrvD3d9IdxBufObjBatchPtr; //@ typedef s3d_CUtilTree s3d_CDrvD3d9IdxBufObjBatchTree; /////////////////////////////////////////////////////////////////////////////// //@ struct s3d_CDrvD3d9IdxBufObjBatchRef { s3d_CDrvSig *m_TopolSig; static int Compare( const s3d_CDrvD3d9IdxBufObjBatch *IdxBufObj, const s3d_CDrvD3d9IdxBufObjBatchRef &Ref); }; //@ bool operator==( const s3d_CDrvD3d9IdxBufObjBatch *IdxBufObj, const s3d_CDrvD3d9IdxBufObjBatchRef &Ref); //@ bool operator<( const s3d_CDrvD3d9IdxBufObjBatch *IdxBufObj, const s3d_CDrvD3d9IdxBufObjBatchRef &Ref); /////////////////////////////////////////////////////////////////////////////// //@ struct s3d_CDrvD3d9BufMgrVertBuf { s3d_CDrvD3d9VertBuf m_VertBuf; s3d_CSysIntps m_UsedSize; s3d_CDrvD3d9BufMgrVertBuf(); void Reset(); }; /////////////////////////////////////////////////////////////////////////////// //@ struct s3d_CDrvD3d9IdxBufMem { const s3d_CSysIntm *m_Data; D3DFORMAT m_Fmt; D3DPRIMITIVETYPE m_Prim; }; /////////////////////////////////////////////////////////////////////////////// //@ struct s3d_CDrvD3d9VertBufMem { const s3d_CSysIntm *m_Data; s3d_CDrvD3d9VertDecl m_VertDecl; s3d_CSysIntps m_VertSize; int m_VertBufFmtDecl; }; /////////////////////////////////////////////////////////////////////////////// //@ class s3d_CDrvD3d9BufMgr : public s3d_CUtilPtrBase { public: s3d_CDrvD3d9BufMgr( s3d_CUtilMsgHandler *MsgHandler, s3d_CDrvD3d9ProgMgr *ProgMgr, s3d_CDrvD3d9Env &Env, s3d_CDrvD3d9Param *D3dParam, s3d_CSysIntps VertIdxLimit, LPDIRECT3DDEVICE9 D3dDev); ~s3d_CDrvD3d9BufMgr(); // Vertex buffer s3d_CDrvD3d9VertBufObjBatchPtr CreateVertBufObjStatic( const s3d_CDrvGfxCharge *Charge, s3d_CDrvD3d9ProgMgr *ProgMgr, bool SWVertProc); s3d_CDrvD3d9VertBufObjPtr FetchVertBufObjDyn( s3d_CUtilMemPool *MemPool, const s3d_CDrvGfxCharge *Charge, s3d_CDrvD3d9ProgMgr *ProgMgr, bool SWVertProc); const s3d_CSysIntm *CheckVertBufDirectPointFloat3( const s3d_CDrvGfxCharge *Charge, s3d_CDrvD3d9VertBufDesc_cr VertBufDesc); void FetchVertBufMemDyn( s3d_CUtilMemPool *MemPool, const s3d_CDrvGfxCharge *Charge, s3d_CDrvD3d9ProgMgr *ProgMgr, s3d_CDrvD3d9VertBufMem &VertBuf); // Index buffer s3d_CDrvD3d9IdxBufObjBatchPtr CreateIdxBufObjStatic( const s3d_CDrvGfxCharge *Charge, DWORD Usage, D3DPOOL Pool); s3d_CDrvD3d9IdxBufObjPtr FetchIdxBufObjDyn( s3d_CUtilMemPool *MemPool, const s3d_CDrvGfxCharge *Charge, s3d_CUtilMemPoolArray &BoneIdxArray, DWORD Usage, D3DPOOL Pool); void FetchIdxBufMemDyn( s3d_CUtilMemPool *MemPool, const s3d_CDrvGfxCharge *Charge, s3d_CDrvD3d9IdxBufMem &IdxBuf, s3d_CUtilMemPoolArray &BoneIdxArray); // Packet data void LoadBatchPacketData( const s3d_CDrvGfxCharge *Charge, s3d_CSysIntps PacketCnt, s3d_CDrvD3d9Packet *PacketArray, s3d_CSysIntps PacketSubBase); void Park(); void Unpark(); const s3d_CDrvD3d9VertBuf &GetVertBufDummyBlendWghIdx() const; private: s3d_CUtilMsgHandlerPtr m_MsgHandler; s3d_CDrvD3d9VertBufObjPtr m_VertBufDyn; s3d_CDrvD3d9VertBufObjBatchTree m_VertBufTree; s3d_CDrvD3d9IdxBufObjPtr m_IdxBufDyn; s3d_CDrvD3d9IdxBufObjBatchTree m_IdxBufTree; s3d_CDrvD3d9BufMgrVertBuf m_VertBufDummyWghIdx; s3d_CUtilMap m_VertDeclMap; s3d_CDrvD3d9ProgMgrPtr m_ProgMgr; s3d_CDrvD3d9Device m_D3dDev; s3d_CDrvD3d9Env *m_Env; s3d_CDrvD3d9ParamPtr m_D3dParam; s3d_CSysIntps m_VertIdxLimit; bool m_PreferIdxBuf32; // Vertex declaration void FindVertDecl( s3d_CDrvD3d9VertBufDesc VertBufFmt, s3d_CDrvD3d9VertDecl &VertDecl); // Vertex buffer s3d_CDrvD3d9VertBufObjBatchPtr AllocVertBufObj( const s3d_CDrvGfxCharge *Charge, const s3d_CDrvD3d9VertBufDesc &VertBufFmt, LPDIRECT3DVERTEXDECLARATION9 VertDecl, bool SWVertProc); void LoadVertBuf( const s3d_CDrvGfxCharge *Charge, s3d_CDrvD3d9VertBufObj *VertBuf, const s3d_CDrvD3d9VertBufDesc &VertBufDesc, s3d_CSysIntps DestStartOffs, s3d_CSysIntps DestVertBase, s3d_CSysIntps VertBase, s3d_CSysIntps VertCnt, bool DynOnly, bool Discard); void LoadVertBufData( const s3d_CDrvGfxCharge *Charge, const s3d_CDrvD3d9VertBufDesc &VertBufDesc, s3d_CSysIntm *Dest, s3d_CSysIntps VertBase, s3d_CSysIntps VertCnt, bool DynOnly); void CalcVertBufDesc( const s3d_CDrvGfxCharge *Charge, s3d_CDrvD3d9VertBufDesc &VertBufDesc); // Index buffer s3d_CDrvD3d9IdxBufObjBatchPtr AllocIdxBufObj( const s3d_CDrvGfxCharge *Charge, D3DFORMAT Fmt, DWORD Usage, D3DPOOL Pool); void LoadIdxBuf( const s3d_CDrvGfxCharge *Charge, s3d_CDrvD3d9IdxBufObj *IdxBuf, s3d_CSysIntps DestIdxBase, s3d_CSysIntps VertOffset, s3d_CSysIntps IdxBase, bool Discard); void LoadIdxBufData( const s3d_CDrvGfxCharge *Charge, D3DFORMAT Fmt, s3d_CSysIntm *Dest, s3d_CSysIntps IdxCnt, s3d_CSysIntps DestIdxBase, s3d_CSysIntps VertOffset, s3d_CSysIntps IdxBase); D3DFORMAT CalcIdxBufFmtOfCnt( const s3d_CSysChar *Info, s3d_CSysIntps Cnt, bool Prefer32); s3d_CSysIntps CalcSizeOfFmtCnt( D3DFORMAT IndexBufFmt, s3d_CSysIntps Cnt); s3d_CSysIntps CalcCntOfFmtSize( D3DFORMAT IndexBufFmt, s3d_CSysIntps Size); void CheckAllocDummyBuffers( const s3d_CDrvGfxCharge* Charge, int VertBufFmtDecl, bool SWVertProc); void CreateDummyVertBuf( DWORD Usage, D3DPOOL Pool); void Reset(); void FreeDynBuffers(); }; //@ typedef s3d_CUtilPtr s3d_CDrvD3d9BufMgrPtr; /////////////////////////////////////////////////////////////////////////////// //@ struct s3d_CDrvD3d9BufInitUtil { //@ static void InitFloatX2ToFloat32X2( s3d_CSysIntm *pDest, s3d_CSysIntps VertexSize, const s3d_CSysIntm *pSrc, s3d_CSysIntps Cnt, s3d_CSysIntps Stride); //@ static void InitFloatX3ToFloat32X3( s3d_CSysIntm *pDest, s3d_CSysIntps VertexSize, const s3d_CSysIntm *pSrc, s3d_CSysIntps Cnt, s3d_CSysIntps Stride); //@ static void InitFloatX4ToFloat32X4( s3d_CSysIntm *pDest, s3d_CSysIntps VertexSize, const s3d_CSysIntm *pSrc, s3d_CSysIntps Cnt, s3d_CSysIntps Stride); //@ static void InitFloatX3ToColor( s3d_CSysIntm *pDest, s3d_CSysIntps VertexSize, const s3d_CSysIntm *pSrc, s3d_CSysIntps Cnt, s3d_CSysIntps Stride); //@ static void InitFloatX4ToColor( s3d_CSysIntm *pDest, s3d_CSysIntps VertexSize, const s3d_CSysIntm *pSrc, s3d_CSysIntps Cnt, s3d_CSysIntps Stride); //@ static void InitIntX4ToInt8uX4( s3d_CSysIntm *pDest, s3d_CSysIntps VertexSize, const s3d_CSysIntm *pSrc, s3d_CSysIntps Cnt, s3d_CSysIntps Stride); //@ // Compress float[-1..1] to int[0..255] // e.g. normals static void InitFloatX3ToInt8uX4( s3d_CSysIntm *pDest, s3d_CSysIntps VertexSize, const s3d_CSysIntm *pSrc, s3d_CSysIntps Cnt, s3d_CSysIntps Stride); //@ // Compress float[0..1] to int[0..255] // e.g. blendweights static void InitFloatX4ToInt8uX4( s3d_CSysIntm *pDest, s3d_CSysIntps VertexSize, const s3d_CSysIntm *pSrc, s3d_CSysIntps Cnt, s3d_CSysIntps Stride); //@ static void VertFormatError( s3d_CUtilMsgHandler *MsgHandler, const s3d_CDrvGfxCharge *Charge); }; /////////////////////////////////////////////////////////////////////////////// // Implementations: /////////////////////////////////////////////////////////////////////////////// S3D_SYS_INLINE s3d_CDrvD3d9DummyWghBank::s3d_CDrvD3d9DummyWghBank() { m_Data[0] = 1; m_Data[1] = 0; m_Data[2] = 0; m_Data[3] = 0; } S3D_SYS_INLINE void s3d_CDrvD3d9DummyWghBank::Fetch( s3d_CUtilMsgHandler *MsgHandler, const s3d_CSysChar *Info, s3d_CDrvBankContent &BankContent) { BankContent.m_Cnt = 1; BankContent.m_Data = reinterpret_cast(&m_Data); BankContent.m_Stride = 0; BankContent.m_TypeDesc = s3d_DrvDataGetTypeDesc(); } S3D_SYS_INLINE s3d_CUtilPtrBase *s3d_CDrvD3d9DummyWghBank::GetOwner( s3d_CUtilMsgHandler *MsgHandler, const s3d_CSysChar *Info) { return 0; } /////////////////////////////////////////////////////////////////////////////// S3D_SYS_INLINE s3d_CDrvD3d9DummyWghAttr::s3d_CDrvD3d9DummyWghAttr() { m_Bank = &m_DummyWghBank; m_BankDyn = false; m_BankSig = 0; m_Chan = s3d_CDrvGfxEng::AttrChan_BoneWgh; m_Slot = 0; } /////////////////////////////////////////////////////////////////////////////// S3D_SYS_INLINE s3d_CDrvD3d9DummySubscrBank::s3d_CDrvD3d9DummySubscrBank() { m_Data[0] = 0; m_Data[1] = 1; m_Data[2] = 2; m_Data[3] = 3; } S3D_SYS_INLINE void s3d_CDrvD3d9DummySubscrBank::Fetch( s3d_CUtilMsgHandler *MsgHandler, const s3d_CSysChar *Info, s3d_CDrvBankContent &BankContent) { BankContent.m_Cnt = 1; BankContent.m_Data = reinterpret_cast(&m_Data); BankContent.m_Stride = 0; BankContent.m_TypeDesc = s3d_DrvDataGetTypeDesc(); } S3D_SYS_INLINE s3d_CUtilPtrBase *s3d_CDrvD3d9DummySubscrBank::GetOwner( s3d_CUtilMsgHandler *MsgHandler, const s3d_CSysChar *Info) { return 0; } /////////////////////////////////////////////////////////////////////////////// S3D_SYS_INLINE s3d_CDrvD3d9DummySubscrAttr::s3d_CDrvD3d9DummySubscrAttr() { m_Bank = &m_DummySubscrBank; m_BankDyn = false; m_BankSig = 0; m_Chan = s3d_CDrvGfxEng::AttrChan_BoneSubscr; m_Slot = 0; } /////////////////////////////////////////////////////////////////////////////// S3D_SYS_INLINE s3d_CDrvD3d9VertBufDesc::s3d_CDrvD3d9VertBufDesc() { Reset(); } S3D_SYS_INLINE void s3d_CDrvD3d9VertBufDesc::Reset() { m_PointAttr = 0; m_ColorAlphaAttr = 0; m_NormalAttr = 0; m_BoneWghAttr = 0; m_BoneSubscrAttr = 0; int iTex = 0; for(iTex = 0; iTex < S3D_DRV_D3D9_MAX_ATTR_CNT; iTex++) m_TexAttrArray[iTex] = 0; m_VertElemCnt = 0; s3d_SysMemset(m_VertElemArray, 0, S3D_SYS_SIZEOFS(m_VertElemArray)); m_VertSize = 0; m_VertBufFmtDecl = 0; } /////////////////////////////////////////////////////////////////////////////// S3D_SYS_INLINE s3d_CDrvD3d9BufMgrVertBuf::s3d_CDrvD3d9BufMgrVertBuf() { Reset(); } S3D_SYS_INLINE void s3d_CDrvD3d9BufMgrVertBuf::Reset() { m_VertBuf = 0; m_UsedSize = 0; } /////////////////////////////////////////////////////////////////////////////// S3D_SYS_INLINE const s3d_CDrvD3d9VertBuf &s3d_CDrvD3d9BufMgr::GetVertBufDummyBlendWghIdx() const { return m_VertBufDummyWghIdx.m_VertBuf; } /////////////////////////////////////////////////////////////////////////////// #endif