source: GTP/trunk/App/Demos/Geom/Shark3D/src/drv_d3d9_buf.cpp @ 2236

Revision 2236, 61.5 KB checked in by gumbau, 17 years ago (diff)
Line 
1///////////////////////////////////////////////////////////////////////////////
2//
3//      ##  ######
4//       ######  ###
5//  ## ###############        Shark 3D Engine (www.shark3d.com)
6//   ########## # # #
7//    ########                Copyright (c) 1996-2006 Spinor GmbH.
8//   ######### # # #          All rights reserved.
9//  ##   ##########
10//      ##
11//
12///////////////////////////////////////////////////////////////////////////////
13
14#include "drv_d3d9_buf.h"
15#include "drv_d3d9_mmx.h"
16#include "drv_d3d9_util.h"
17#include "drv/interf/drv_gfx.h"
18#include "drv/util/drv_util_gfxutil.h"
19#include "sys/core/sys_util.h"
20#include "sys/core/sys_cmem.h"
21#include <malloc.h>
22
23///////////////////////////////////////////////////////////////////////////////
24
25#define S3D_DRV_D3D9_CACHEALIGN(A)\
26        (((A) & ~(S3D_DRV_D3D9_CACHELINE - 1)) + S3D_DRV_D3D9_CACHELINE)
27
28///////////////////////////////////////////////////////////////////////////////
29
30static const D3DPRIMITIVETYPE drv_d3d9_PrimTable[6] =
31{
32    D3DPT_POINTLIST, D3DPT_LINELIST, D3DPT_LINESTRIP,
33    D3DPT_TRIANGLELIST, D3DPT_TRIANGLESTRIP, D3DPT_TRIANGLEFAN,
34};
35
36///////////////////////////////////////////////////////////////////////////////
37
38s3d_CDrvD3d9VertBufObj::~s3d_CDrvD3d9VertBufObj()
39{
40    if(m_ReportMsgHandler)
41    {
42        s3d_CUtilMsg m;
43        m.m_Code = "drv/imp/directx/d3d9/drv_d3d9_buf.report_vertbuf_destroy";
44        m.m_StdTempl = "D3D: "
45            "Destroying vertex buffer object addr=0x[1].";
46        m.AddInfo("");
47        m.AddInfo(s3d_CUtilStrUtil::StrOfPtr(this));
48        s3d_UtilMsgReportNote(m_ReportMsgHandler, m);
49    }
50}
51
52void s3d_CDrvD3d9VertBufObj::Reset()
53{
54    m_VertBuf.Reset();
55    m_BufSize = 0;
56    m_VertSize = 0;
57    m_VertDecl.Reset();
58    m_VertBufFmtDecl = 0;
59
60    m_Usage = 0;
61    m_Pool = D3DPOOL_FORCE_DWORD;
62}
63
64///////////////////////////////////////////////////////////////////////////////
65
66s3d_CDrvD3d9IdxBufObj::~s3d_CDrvD3d9IdxBufObj()
67{
68    if(m_ReportMsgHandler)
69    {
70        s3d_CUtilMsg m;
71        m.m_Code = "drv/imp/directx/d3d9/drv_d3d9_buf.report_idxbuf_destroy";
72        m.m_StdTempl = "D3D: "
73            "Destroying index buffer object addr=0x[1].";
74        m.AddInfo("");
75        m.AddInfo(s3d_CUtilStrUtil::StrOfPtr(this));
76        s3d_UtilMsgReportNote(m_ReportMsgHandler, m);
77    }
78}
79
80void s3d_CDrvD3d9IdxBufObj::Reset()
81{
82    m_IdxBuf.Reset();
83    m_IdxCnt = 0;
84    m_BufSize = 0;
85
86    D3DFORMAT m_Fmt = D3DFMT_UNKNOWN;
87    m_D3dPrim = D3DPT_FORCE_DWORD;
88    m_Usage = 0;
89    m_Pool = D3DPOOL_FORCE_DWORD;
90}
91
92///////////////////////////////////////////////////////////////////////////////
93
94s3d_CDrvD3d9VertBufObjBatch::s3d_CDrvD3d9VertBufObjBatch()
95{
96    Reset();
97
98    m_Complete = true;
99
100    m_AttrCnt = 0;
101    m_TopolSig = 0;
102    m_Node.m_Data = this;
103}
104
105s3d_CDrvD3d9VertBufObjBatch::~s3d_CDrvD3d9VertBufObjBatch()
106{
107}
108
109///////////////////////////////////////////////////////////////////////////////
110
111int s3d_CDrvD3d9VertBufObjBatchRef::Compare(
112        const s3d_CDrvD3d9VertBufObjBatch *VertBufObj,
113        const s3d_CDrvD3d9VertBufObjBatchRef &Ref)
114{
115    if(VertBufObj->m_TopolSig < Ref.m_TopolSig)
116        return -1;
117    if(VertBufObj->m_TopolSig > Ref.m_TopolSig)
118        return 1;
119
120    if(VertBufObj->m_AttrCnt < Ref.m_AttrCnt)
121        return -1;
122    if(VertBufObj->m_AttrCnt > Ref.m_AttrCnt)
123        return 1;
124
125    S3D_SYS_ASSERT(VertBufObj->m_AttrCnt == Ref.m_AttrCnt);
126
127    const s3d_CDrvD3d9VertBufAttr *Attr = VertBufObj->m_AttrArray;
128    const s3d_CDrvGfxAttr *RefAttr = Ref.m_AttrArray;
129    int iAttr;
130    for(iAttr = 0; iAttr < Ref.m_AttrCnt; iAttr++)
131    {
132        if(Attr->m_BankDyn < RefAttr->m_BankDyn)
133            return -1;
134        if(Attr->m_BankDyn > RefAttr->m_BankDyn)
135            return 1;
136
137        if(Attr->m_BankSig < RefAttr->m_BankSig)
138            return -1;
139        if(Attr->m_BankSig > RefAttr->m_BankSig)
140            return 1;
141
142        if(Attr->m_Chan < RefAttr->m_Chan)
143            return -1;
144        if(Attr->m_Chan > RefAttr->m_Chan)
145            return 1;
146
147        if(Attr->m_Slot < RefAttr->m_Slot)
148            return -1;
149        if(Attr->m_Slot > RefAttr->m_Slot)
150            return 1;
151
152        Attr++;
153        RefAttr++;
154    }
155    return 0;
156}
157
158///////////////////////////////////////////////////////////////////////////////
159
160bool operator==(
161        const s3d_CDrvD3d9VertBufObjBatch *VertBufObj,
162        const s3d_CDrvD3d9VertBufObjBatchRef &Ref)
163{
164    return s3d_CDrvD3d9VertBufObjBatchRef::Compare(VertBufObj, Ref) == 0;
165}
166
167bool operator<(
168        const s3d_CDrvD3d9VertBufObjBatch *VertBufObj,
169        const s3d_CDrvD3d9VertBufObjBatchRef &Ref)
170{
171    return s3d_CDrvD3d9VertBufObjBatchRef::Compare(VertBufObj, Ref) < 0;
172}
173
174///////////////////////////////////////////////////////////////////////////////
175
176s3d_CDrvD3d9IdxBufObjBatch::s3d_CDrvD3d9IdxBufObjBatch()
177{
178    Reset();
179
180    m_Node.m_Data = this;
181}
182
183s3d_CDrvD3d9IdxBufObjBatch::~s3d_CDrvD3d9IdxBufObjBatch()
184{
185}
186
187///////////////////////////////////////////////////////////////////////////////
188
189int s3d_CDrvD3d9IdxBufObjBatchRef::Compare(
190        const s3d_CDrvD3d9IdxBufObjBatch *IdxBufObj,
191        const s3d_CDrvD3d9IdxBufObjBatchRef &Ref)
192{
193    if(IdxBufObj->m_TopolSig < Ref.m_TopolSig)
194        return -1;
195    if(IdxBufObj->m_TopolSig > Ref.m_TopolSig)
196        return 1;
197    return 0;
198}
199
200///////////////////////////////////////////////////////////////////////////////
201
202bool operator==(
203        const s3d_CDrvD3d9IdxBufObjBatch *IdxBufObj,
204        const s3d_CDrvD3d9IdxBufObjBatchRef &Ref)
205{
206    return s3d_CDrvD3d9IdxBufObjBatchRef::Compare(IdxBufObj, Ref) == 0;
207}
208
209bool operator<(
210        const s3d_CDrvD3d9IdxBufObjBatch *IdxBufObj,
211        const s3d_CDrvD3d9IdxBufObjBatchRef &Ref)
212{
213    return s3d_CDrvD3d9IdxBufObjBatchRef::Compare(IdxBufObj, Ref) < 0;
214}
215
216///////////////////////////////////////////////////////////////////////////////
217
218s3d_CDrvD3d9BufMgr::s3d_CDrvD3d9BufMgr(
219        s3d_CUtilMsgHandler *MsgHandler, s3d_CDrvD3d9ProgMgr *ProgMgr,
220        s3d_CDrvD3d9Env &Env, s3d_CDrvD3d9Param *D3dParam, s3d_CSysIntps
221                VertIdxLimit,
222        LPDIRECT3DDEVICE9 D3dDev)
223{
224    m_MsgHandler = MsgHandler;
225    m_ProgMgr = ProgMgr;
226    m_D3dDev = D3dDev;
227    m_Env = &Env;
228    m_D3dParam = D3dParam;
229    m_VertIdxLimit = VertIdxLimit;
230    m_PreferIdxBuf32 = D3dParam->m_PreferIndexBuf32;
231}
232
233s3d_CDrvD3d9BufMgr::~s3d_CDrvD3d9BufMgr()
234{
235}
236
237void s3d_CDrvD3d9BufMgr::Park()
238{
239    FreeDynBuffers();
240}
241
242void s3d_CDrvD3d9BufMgr::Unpark()
243{
244}
245
246///////////////////////////////////////////////////////////////////////////////
247
248s3d_CDrvD3d9VertBufObjBatchPtr s3d_CDrvD3d9BufMgr::CreateVertBufObjStatic(
249        const s3d_CDrvGfxCharge *Charge, s3d_CDrvD3d9ProgMgr *ProgMgr,
250        bool SWVertProc)
251{
252    if(!Charge)
253        return 0;
254
255    // Search for exisiting vertexbuffer:
256    s3d_CDrvD3d9VertBufObjBatchRef Ref;
257    Ref.m_TopolSig = Charge->m_Topol.m_TopolSig;
258    Ref.m_AttrCnt = Charge->m_AttrCnt;
259    Ref.m_AttrArray = Charge->m_AttrArray;
260
261    s3d_CDrvD3d9VertBufObjBatchPtr VertBufObj;
262    s3d_CDrvD3d9VertBufObjBatchTree::CNode *Pos;
263    Pos = s3d_UtilTreeSortedGetStart(m_VertBufTree, Ref);
264    if(s3d_UtilTreeIsEqualAt(Pos, Ref))
265        VertBufObj = Pos->m_Data;
266
267    s3d_CDrvD3d9VertBufDesc VertBufDesc;
268    const s3d_CDrvD3d9Prog *ProgImpl = 0;
269    if(Charge->m_Prog)
270        ProgImpl = s3d_UtilRecogCastSilent<s3d_CDrvD3d9Prog>(
271                Charge->m_Prog);
272
273    if(ProgImpl)
274        ProgImpl->CalcVertBufDesc(Charge, VertBufDesc);
275    else
276        CalcVertBufDesc(Charge, VertBufDesc);
277   
278    s3d_CDrvD3d9VertDecl VertDecl;
279    FindVertDecl(VertBufDesc, VertDecl);
280    if(!VertDecl)
281        return 0;
282
283    if(VertBufObj)
284    {
285        if(VertBufObj->m_VertBufFmtDecl != VertBufDesc.m_VertBufFmtDecl)
286        {
287            s3d_CUtilStr ExistingVertBufDeclStr
288                    = s3d_CDrvD3d9Util::StrOfVertDecl(
289                        m_Env, VertBufObj->m_VertDecl);
290            s3d_CUtilStr VertBufDeclStr
291                    = s3d_CDrvD3d9Util::StrOfVertDecl(m_Env, VertDecl);
292
293            s3d_CDrvD3d9Error e;
294            e.m_Code = "drv/imp/directx/d3d9/drv_d3d9_buf"
295                    ".vertdecl_mismatch";
296            e.m_StdTempl =
297                    "The vertex program of this shader "
298                    "requires the vertex buffer format '[2]', "
299                    "whereas the vertex program of shader '[1]' "
300                    "requires the vertex buffer of format '[3]'. "
301                    "They must not use different vertex data for skinning. ";
302            e.AddInfo(Charge->m_MainInfo);
303            e.AddInfo(VertBufObj->m_MainInfo);
304            e.AddInfo(VertBufDeclStr);
305            e.AddInfo(ExistingVertBufDeclStr);
306            s3d_UtilMsgReportError(m_MsgHandler, e);
307
308            e.Reset();
309            e.m_Code = "drv/imp/directx/d3d9/drv_d3d9_buf"
310                    ".sic_vertdecl_mismatch";
311            e.m_StdTempl = "Sic: "
312                    "The vertex program of this shader "
313                    "requires the vertex buffer format '[3]', "
314                    "whereas the vertex program of shader '[1]' "
315                    "requires the vertex buffer format '[2]'. "
316                    "They must not use different vertex data for skinning. ";
317            e.AddInfo(VertBufObj->m_MainInfo);
318            e.AddInfo(Charge->m_MainInfo);
319            e.AddInfo(VertBufDeclStr);
320            e.AddInfo(ExistingVertBufDeclStr);
321            s3d_UtilMsgReportError(m_MsgHandler, e);
322        }
323        return VertBufObj;
324    }
325
326    if(Charge->m_Prog && ProgMgr)
327    {
328        ProgMgr->CheckVertBufIsCompatible(
329                Charge->m_Prog,
330                Charge->m_ObjInfo, Charge->m_ObjDesc, VertDecl);
331    }
332
333    VertBufObj = AllocVertBufObj(Charge, VertBufDesc, VertDecl, SWVertProc);
334    if(VertBufObj)
335    {
336        if(Ref.m_TopolSig)
337            m_VertBufTree.InsertBefore(Pos, &VertBufObj->m_Node);
338
339        VertBufObj->m_TopolSig = Charge->m_Topol.m_TopolSig;
340        VertBufObj->m_AttrCnt = Charge->m_AttrCnt;
341       
342        VertBufObj->m_AttrArray.Alloc(Charge->m_AttrCnt);
343        s3d_CDrvD3d9VertBufAttr *AttrArray = VertBufObj->m_AttrArray;
344        s3d_CSysIntps nAttrCnt = Charge->m_AttrCnt;
345        int iAttr;
346        for(iAttr = 0; iAttr < nAttrCnt; iAttr++)
347        {
348            s3d_CDrvGfxAttr *Attr = &Charge->m_AttrArray[iAttr];
349            AttrArray[iAttr].m_BankDyn = Attr->m_BankDyn;
350            AttrArray[iAttr].m_BankSig = Attr->m_BankSig;
351            AttrArray[iAttr].m_Chan = Attr->m_Chan;
352            AttrArray[iAttr].m_Slot = Attr->m_Slot;
353        }
354    }
355    return VertBufObj;
356}
357
358s3d_CDrvD3d9VertBufObjPtr s3d_CDrvD3d9BufMgr::FetchVertBufObjDyn(
359        s3d_CUtilMemPool *MemPool, const s3d_CDrvGfxCharge *Charge,
360        s3d_CDrvD3d9ProgMgr *ProgMgr, bool SWVertProc)
361{
362    if(!Charge)
363        return 0;
364
365    s3d_CDrvD3d9VertBufDesc VertBufDesc;
366    const s3d_CDrvD3d9Prog *ProgImpl = 0;
367    if(Charge->m_Prog)
368        ProgImpl = s3d_UtilRecogCastSilent<s3d_CDrvD3d9Prog>(Charge->m_Prog);
369
370    if(ProgImpl)
371        ProgImpl->CalcVertBufDesc(Charge, VertBufDesc);
372    else
373        CalcVertBufDesc(Charge, VertBufDesc);
374
375    s3d_CDrvD3d9VertDecl VertDecl;
376    FindVertDecl(VertBufDesc, VertDecl);
377    if(!VertDecl)
378        return 0;
379
380    if(Charge->m_Prog && ProgMgr)
381    {
382        ProgMgr->CheckVertBufIsCompatible(
383            Charge->m_Prog,
384            Charge->m_ObjInfo, Charge->m_ObjDesc, VertDecl);
385    }
386
387    s3d_CSysIntps VertCnt = Charge->m_VertSubCnt;
388    s3d_CSysIntps VertBufSize = VertBufDesc.m_VertSize * VertCnt;
389   
390    DWORD Usage = D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC;
391    if(SWVertProc)
392        Usage |= D3DUSAGE_SOFTWAREPROCESSING;
393
394    bool AllocNew = false;
395    if(!m_VertBufDyn)
396        AllocNew = true;
397    else if(m_VertBufDyn->m_BufSize < VertBufSize)
398        AllocNew = true;
399    else if(m_VertBufDyn->m_Usage != Usage)
400        AllocNew = true;
401
402    if(AllocNew)
403    {
404        D3DPOOL Pool = D3DPOOL_SYSTEMMEM;
405        DWORD FVF = 0;
406        s3d_CDrvD3d9VertBuf VertBuf;
407        S3D_DRV_D3D9_CHECK(
408                m_Env, m_D3dDev->CreateVertexBuffer(
409                    UINT(VertBufSize), Usage, FVF, Pool,
410                    &VertBuf.EmptyRef(), 0));
411        if(!VertBuf)
412            return 0;
413 
414        if(!m_VertBufDyn)
415            m_VertBufDyn = S3D_SYS_NEW s3d_CDrvD3d9VertBufObj;
416        m_VertBufDyn->m_VertBuf = VertBuf;
417        m_VertBufDyn->m_Usage = Usage;
418        m_VertBufDyn->m_Pool = Pool;
419        m_VertBufDyn->m_BufSize = VertBufSize;
420
421        if(m_D3dParam->m_ReportBuf)
422        {
423            m_VertBufDyn->m_ReportMsgHandler = m_MsgHandler;
424
425            s3d_CUtilMsg m;
426            m.m_Code =
427                    "drv/imp/directx/d3d9/drv_d3d9_buf."
428                    "report_vertbufdyn_create";
429            m.m_StdTempl = "D3D: "
430                    "Creating new dynamic vertex buffer object "
431                    "addr=0x[1] size=[2]: '[3]'";
432            m.AddInfo("");
433            m.AddInfo(s3d_CUtilStrUtil::StrOfPtr(m_VertBufDyn));
434            m.AddInfo(s3d_CUtilStrUtil::StrOfIntps(VertBufSize));
435            m.AddInfo(Charge->m_MainInfo);
436            s3d_UtilMsgReportNote(m_MsgHandler, m);
437        }
438    }
439
440    m_VertBufDyn->m_VertSize = VertBufDesc.m_VertSize;
441    m_VertBufDyn->m_VertDecl = VertDecl;
442    m_VertBufDyn->m_VertBufFmtDecl = VertBufDesc.m_VertBufFmtDecl;
443
444    s3d_CSysIntps DestVertBase = 0;
445    s3d_CSysIntps VertBase = Charge->m_VertSubBase;
446    bool DynOnly = false;
447    bool Discard = true;
448    LoadVertBuf(
449            Charge, m_VertBufDyn, VertBufDesc, 0, DestVertBase,
450            VertBase, VertCnt, DynOnly, Discard);
451
452    if(!m_D3dParam->m_NoDummyBoneVertexBuf)
453    {
454        int VertBufFmtDecl = VertBufDesc.m_VertBufFmtDecl;
455        CheckAllocDummyBuffers(Charge, VertBufFmtDecl, SWVertProc);
456    }
457
458    return m_VertBufDyn;
459}
460
461const s3d_CSysIntm *s3d_CDrvD3d9BufMgr::CheckVertBufDirectPointFloat3(
462        const s3d_CDrvGfxCharge *Charge,
463        s3d_CDrvD3d9VertBufDesc_cr VertBufDesc)
464{
465    if(VertBufDesc.m_VertElemCnt != 2)
466        return 0;
467    const D3DVERTEXELEMENT9 *VertElem = &VertBufDesc.m_VertElemArray[0];
468    if(VertElem->Usage != D3DDECLUSAGE_POSITION)
469        return 0;
470
471    if(Charge->m_AttrCnt != 1)
472        return 0;
473    s3d_CDrvGfxAttr *Attr = &Charge->m_AttrArray[0];
474    if(Attr->m_Chan != s3d_CDrvGfxEng::AttrChan_Point)
475        return 0;
476
477    s3d_CDrvBankContent BankContent;
478    s3d_DrvBankFetchExisting(
479        m_MsgHandler, Charge->m_ObjInfo,
480        "point", Attr->m_Bank, BankContent);
481    if(BankContent.m_TypeDesc != s3d_DrvDataGetTypeDesc<s3d_CDrvFloat32X3>())
482        return 0;
483    if(BankContent.m_Stride != 3 * sizeof(float))
484        return 0;
485
486    return BankContent.m_Data;
487}
488
489void s3d_CDrvD3d9BufMgr::FetchVertBufMemDyn(
490        s3d_CUtilMemPool *MemPool, const s3d_CDrvGfxCharge *Charge,
491        s3d_CDrvD3d9ProgMgr *ProgMgr, s3d_CDrvD3d9VertBufMem &VertBuf)
492{
493    VertBuf.m_Data = 0;
494    VertBuf.m_VertSize = 0;
495    VertBuf.m_VertBufFmtDecl = 0;
496
497    if(!Charge)
498        return;
499
500    s3d_CDrvD3d9VertBufDesc VertBufDesc;
501    const s3d_CDrvD3d9Prog *ProgImpl = 0;
502    if(Charge->m_Prog)
503        ProgImpl = s3d_UtilRecogCastSilent<s3d_CDrvD3d9Prog>(Charge->m_Prog);
504
505    if(ProgImpl)
506        ProgImpl->CalcVertBufDesc(Charge, VertBufDesc);
507    else
508        CalcVertBufDesc(Charge, VertBufDesc);
509
510    FindVertDecl(VertBufDesc, VertBuf.m_VertDecl);
511    if(!VertBuf.m_VertDecl)
512        return;
513
514    if(Charge->m_Prog && ProgMgr)
515    {
516        ProgMgr->CheckVertBufIsCompatible(
517            Charge->m_Prog,
518            Charge->m_ObjInfo, Charge->m_ObjDesc, VertBuf.m_VertDecl);
519    }
520
521    VertBuf.m_VertSize = VertBufDesc.m_VertSize;
522    VertBuf.m_VertBufFmtDecl = VertBufDesc.m_VertBufFmtDecl;
523    const s3d_CSysIntm *DirectData = CheckVertBufDirectPointFloat3(
524            Charge, VertBufDesc);
525    if(DirectData)
526    {
527        VertBuf.m_Data = DirectData;
528        return;
529    }
530
531    s3d_CSysIntps VertBufSize = Charge->m_VertSubCnt * VertBufDesc.m_VertSize;
532    s3d_CSysIntm *VertBufData = new(MemPool) s3d_CSysIntm[VertBufSize];
533
534    s3d_CSysIntps DestVertBase = 0;
535    s3d_CSysIntps VertCnt = Charge->m_VertSubCnt;
536    s3d_CSysIntps VertBase = Charge->m_VertSubBase;
537    bool DynOnly = false;
538    LoadVertBufData(
539            Charge, VertBufDesc, VertBufData, VertBase, VertCnt, DynOnly);
540
541    VertBuf.m_Data = VertBufData;
542}
543
544s3d_CDrvD3d9IdxBufObjBatchPtr s3d_CDrvD3d9BufMgr::CreateIdxBufObjStatic(
545        const s3d_CDrvGfxCharge *Charge, DWORD Usage, D3DPOOL Pool)
546{
547    if(!Charge)
548        return 0;
549
550    // Search for  indexbuf w/ same batch->topol->atom
551    s3d_CDrvD3d9IdxBufObjBatchRef Ref;
552    Ref.m_TopolSig = Charge->m_Topol.m_TopolSig;
553
554    s3d_CDrvD3d9IdxBufObjBatchPtr IdxBufObj;
555    s3d_CDrvD3d9IdxBufObjBatchTree::CNode *Pos
556            = s3d_UtilTreeSortedGetStart(m_IdxBufTree, Ref);
557    if(s3d_UtilTreeIsEqualAt(Pos, Ref))
558        IdxBufObj = Pos->m_Data;
559
560    if(IdxBufObj)
561        return IdxBufObj;
562
563    s3d_CSysIntps MaxIdx
564            = Charge->m_VertSubBase + Charge->m_Topol.m_VertCnt;
565    D3DFORMAT IdxBufFmt = CalcIdxBufFmtOfCnt(
566            Charge->m_MainInfo, MaxIdx, m_PreferIdxBuf32);
567
568    const s3d_CDrvInt32u *BoneIdxData
569        = s3d_DrvBankFetchArray<s3d_CDrvInt32u>(
570            m_MsgHandler, Charge->m_MainInfo,
571            "bone_idx", Charge->m_Topol.m_BoneIdxBank,
572            Charge->m_Topol.m_BoneIdxCnt);
573   
574    s3d_CSysIntps BoneIdxCnt = 0;
575    s3d_CUtilOwnArray<s3d_CSysInt32u> BoneIdxArray;
576    if(BoneIdxData)
577    {
578        BoneIdxCnt = Charge->m_Topol.m_BoneIdxCnt;
579        BoneIdxArray.Alloc(BoneIdxCnt);
580        s3d_CSysIntps iBoneIdx;
581        for(iBoneIdx = 0; iBoneIdx < BoneIdxCnt; iBoneIdx++)
582        {
583            s3d_CSysInt32u BoneIdx = *BoneIdxData++;
584            BoneIdxArray[iBoneIdx] = BoneIdx;
585        }
586    }
587
588    s3d_CSysIntps PacketCnt = Charge->m_Topol.m_PacketCnt;
589    s3d_CUtilOwnArray<s3d_CDrvD3d9Packet> PacketArray;
590    PacketArray.Alloc(PacketCnt);
591
592    s3d_CSysIntps PacketSubBase = 0;
593    LoadBatchPacketData(Charge, PacketCnt, PacketArray, PacketSubBase);
594
595    IdxBufObj = AllocIdxBufObj(Charge, IdxBufFmt, Usage, Pool);
596   
597    if(IdxBufObj)
598    {
599        IdxBufObj->m_BoneIdxCnt = BoneIdxCnt;
600        IdxBufObj->m_BoneIdxArray.Assign(BoneIdxArray);
601
602        IdxBufObj->m_PacketCnt = PacketCnt;
603        IdxBufObj->m_PacketArray.Assign(PacketArray);
604
605        if(Ref.m_TopolSig)
606            m_IdxBufTree.InsertBefore(Pos, &IdxBufObj->m_Node);
607    }
608    return IdxBufObj;
609}
610
611s3d_CDrvD3d9IdxBufObjPtr s3d_CDrvD3d9BufMgr::FetchIdxBufObjDyn(
612        s3d_CUtilMemPool *MemPool, const s3d_CDrvGfxCharge *Charge,
613        s3d_CUtilMemPoolArray<s3d_CSysInt32u> &BoneIdxArray,
614        DWORD Usage, D3DPOOL Pool)
615{
616    if(!Charge)
617        return 0;
618
619    s3d_CSysIntps MaxIdx = Charge->m_VertSubBase + Charge->m_VertSubCnt;
620    D3DFORMAT IdxBufFmt = CalcIdxBufFmtOfCnt(
621            Charge->m_MainInfo, MaxIdx, m_PreferIdxBuf32);
622
623    s3d_CSysIntps IdxCnt = Charge->m_IdxSubCnt;
624    s3d_CSysIntps IdxBufSize = CalcSizeOfFmtCnt(IdxBufFmt, IdxCnt);
625
626    const s3d_CDrvInt32u *BoneIdxData
627        = s3d_DrvBankFetchArray<s3d_CDrvInt32u>(
628            m_MsgHandler, Charge->m_MainInfo,
629            "bone_idx", Charge->m_Topol.m_BoneIdxBank,
630            Charge->m_Topol.m_BoneIdxCnt);
631    if(BoneIdxData)
632    {
633        BoneIdxData += Charge->m_BoneIdxSubBase;
634        s3d_CSysIntps BoneIdxCnt = Charge->m_BoneIdxSubCnt;
635        BoneIdxArray.SetCnt(MemPool, BoneIdxCnt);
636        s3d_CSysIntps iBoneIdx;
637        for(iBoneIdx = 0; iBoneIdx < BoneIdxCnt; iBoneIdx++)
638        {
639            s3d_CSysInt32u BoneIdx = *BoneIdxData++;
640            BoneIdxArray.SetAtRaw(iBoneIdx, BoneIdx);
641        }
642    }
643
644    bool AllocNew = false;
645    if(!m_IdxBufDyn)
646        AllocNew = true;
647    else if(m_IdxBufDyn->m_BufSize < IdxBufSize)
648        AllocNew = true;
649    else if(m_IdxBufDyn->m_Fmt < IdxBufFmt)
650        AllocNew = true;
651    else if(m_IdxBufDyn->m_Usage != Usage)
652        AllocNew = true;
653
654    if(AllocNew)
655    {
656        s3d_CDrvD3d9IdxBuf IdxBuf;
657        S3D_DRV_D3D9_CHECK(
658                m_Env, m_D3dDev->CreateIndexBuffer(
659                    UINT(IdxBufSize), Usage, IdxBufFmt,
660                    Pool, &IdxBuf.EmptyRef(), 0));
661        if(!IdxBuf)
662            return 0;
663
664        if(!m_IdxBufDyn)
665            m_IdxBufDyn = S3D_SYS_NEW s3d_CDrvD3d9IdxBufObj;
666
667        m_IdxBufDyn->m_IdxBuf = IdxBuf;
668        m_IdxBufDyn->m_BufSize = IdxBufSize;
669        m_IdxBufDyn->m_Pool = Pool;
670        m_IdxBufDyn->m_Usage = Usage;
671        m_IdxBufDyn->m_Fmt = IdxBufFmt;
672
673        if(m_D3dParam->m_ReportBuf)
674        {
675            m_IdxBufDyn->m_ReportMsgHandler = m_MsgHandler;
676
677            s3d_CUtilMsg m;
678            m.m_Code =
679                    "drv/imp/directx/d3d9/drv_d3d9_buf."
680                    "report_idxbufdyn_create";
681            m.m_StdTempl = "D3D: "
682                    "Creating new dynamic index buffer object "
683                    "addr=0x[1] size=[2]: '[3]'";
684            m.AddInfo("");
685            m.AddInfo(s3d_CUtilStrUtil::StrOfPtr(m_IdxBufDyn));
686            m.AddInfo(s3d_CUtilStrUtil::StrOfIntps(IdxBufSize));
687            m.AddInfo(Charge->m_MainInfo);
688            s3d_UtilMsgReportNote(m_MsgHandler, m);
689        }
690    }
691
692    int Prim = Charge->m_Topol.m_Prim;
693    D3DPRIMITIVETYPE D3dPrim = D3DPT_POINTLIST;
694    if(s3d_SysIsValidArrayIdx(Prim, S3D_SYS_ARRAYCNTS(drv_d3d9_PrimTable)))
695        D3dPrim = drv_d3d9_PrimTable[Prim];
696   
697    m_IdxBufDyn->m_D3dPrim = D3dPrim;
698    m_IdxBufDyn->m_IdxCnt = IdxCnt;
699   
700    s3d_CSysIntps DestIdxBase = 0;
701    s3d_CSysIntps VertOffset = Charge->m_VertSubBase;
702    s3d_CSysIntps SrcIdxBase = Charge->m_IdxSubBase;
703    bool Discard = true;
704    LoadIdxBuf(
705            Charge, m_IdxBufDyn, DestIdxBase, VertOffset, SrcIdxBase, Discard);
706
707    return m_IdxBufDyn;
708}
709
710void s3d_CDrvD3d9BufMgr::FetchIdxBufMemDyn(
711        s3d_CUtilMemPool *MemPool, const s3d_CDrvGfxCharge *Charge,
712        s3d_CDrvD3d9IdxBufMem &IdxBuf,
713        s3d_CUtilMemPoolArray<s3d_CSysInt32u> &BoneIdxArray)
714{
715    IdxBuf.m_Data = 0;
716    IdxBuf.m_Fmt = D3DFMT_UNKNOWN;
717    IdxBuf.m_Prim = D3DPT_POINTLIST;
718
719    if(!Charge)
720        return;
721
722    const s3d_CDrvInt32u *BoneIdxData
723        = s3d_DrvBankFetchArray<s3d_CDrvInt32u>(
724            m_MsgHandler, Charge->m_MainInfo,
725            "bone_idx", Charge->m_Topol.m_BoneIdxBank,
726            Charge->m_Topol.m_BoneIdxCnt);
727
728    if(BoneIdxData)
729    {
730        BoneIdxData += Charge->m_BoneIdxSubBase;
731        s3d_CSysIntps BoneIdxCnt = Charge->m_BoneIdxSubCnt;
732        BoneIdxArray.SetCnt(MemPool, BoneIdxCnt);
733        s3d_CSysIntps iBoneIdx;
734        for(iBoneIdx = 0; iBoneIdx < BoneIdxCnt; iBoneIdx++)
735        {
736            s3d_CSysInt32u BoneIdx = *BoneIdxData++;
737            BoneIdxArray.SetAtRaw(iBoneIdx, BoneIdx);
738        }
739    }
740
741    // prefer 32 bit indices for use w/ DIPUP coz engine delivers data
742    // in int32u. so we dont need to convert 32 -> 16 bit indices
743    bool PreferIdxBuf32 = true;
744    s3d_CSysIntps MaxIdx = Charge->m_VertSubBase + Charge->m_VertSubCnt;
745    IdxBuf.m_Fmt = s3d_CDrvD3d9BufMgr::CalcIdxBufFmtOfCnt(
746                Charge->m_MainInfo, MaxIdx, PreferIdxBuf32);
747
748    int Prim = Charge->m_Topol.m_Prim;
749    if(s3d_SysIsValidArrayIdx(Prim, S3D_SYS_ARRAYCNTS(drv_d3d9_PrimTable)))
750        IdxBuf.m_Prim = drv_d3d9_PrimTable[Prim];
751
752    s3d_CSysIntps IdxSubBase = Charge->m_IdxSubBase;
753    if(IdxSubBase == 0)
754    {
755        s3d_CDrvBankContent BankContent;
756        s3d_DrvBankFetchExisting(
757            m_MsgHandler, Charge->m_MainInfo,
758            "idx", Charge->m_Topol.m_IdxBank, BankContent);
759        if(BankContent.m_TypeDesc == s3d_DrvDataGetTypeDesc<s3d_CDrvInt32u>()
760                && BankContent.m_Stride == sizeof(s3d_CSysInt32u)
761                && IdxBuf.m_Fmt == D3DFMT_INDEX32)
762        {
763            IdxBuf.m_Data = BankContent.m_Data;
764            return;
765        }
766    }
767
768    s3d_CSysIntps IdxCnt = Charge->m_IdxSubCnt;
769    s3d_CSysIntps IdxBufSize = CalcSizeOfFmtCnt(IdxBuf.m_Fmt, IdxCnt);
770    s3d_CSysIntm *IdxBufData = new(MemPool) s3d_CSysIntm[IdxBufSize];
771
772    s3d_CSysIntps DestIdxBase = 0;
773    s3d_CSysIntps VertOffset = Charge->m_VertSubBase;
774    s3d_CSysIntps IdxBase = Charge->m_IdxSubBase;
775    LoadIdxBufData(
776            Charge, IdxBuf.m_Fmt, IdxBufData, IdxCnt,
777            DestIdxBase, VertOffset, IdxBase);
778    IdxBuf.m_Data = IdxBufData;
779}
780
781
782void s3d_CDrvD3d9BufMgr::LoadBatchPacketData(
783        const s3d_CDrvGfxCharge *Charge,
784        s3d_CSysIntps PacketCnt, s3d_CDrvD3d9Packet *PacketArray,
785        s3d_CSysIntps PacketSubBase)
786{
787    if(!Charge)
788        return;
789
790    const s3d_CDrvMeshPacket *ChargePacketArray
791            = s3d_DrvBankFetchExistingArray<s3d_CDrvMeshPacket>(
792                    m_MsgHandler, Charge->m_ObjInfo, "packet",
793                    Charge->m_Topol.m_PacketBank,
794                    Charge->m_Topol.m_PacketCnt);
795
796    const s3d_CDrvMeshPacket *CurChargePacket
797            = ChargePacketArray + PacketSubBase;
798
799    s3d_CDrvD3d9Packet *CurPacket = PacketArray;
800
801    s3d_CSysIntps iPacket;
802    for(iPacket = 0; iPacket < PacketCnt; iPacket++)
803    {
804        CurPacket->m_VertCnt = CurChargePacket->m_VertCnt;
805        CurPacket->m_IdxCnt = CurChargePacket->m_IdxCnt;
806        CurPacket->m_PrimCnt = s3d_CDrvUtilGfxUtil::PrimCntOfIdxCnt(
807                    Charge->m_Topol.m_Prim, CurChargePacket->m_IdxCnt);
808        CurPacket->m_BoneIdxCnt = CurChargePacket->m_BoneIdxCnt;
809
810        CurChargePacket++;
811        CurPacket++;
812    }
813}
814
815///////////////////////////////////////////////////////////////////////////////
816
817void s3d_CDrvD3d9BufMgr::FindVertDecl(
818        s3d_CDrvD3d9VertBufDesc VertBufDesc, s3d_CDrvD3d9VertDecl &VertDecl)
819{
820    D3DVERTEXELEMENT9 *VertElemArray = VertBufDesc.m_VertElemArray;
821    s3d_CSysIntps VertElemCnt = VertBufDesc.m_VertElemCnt;
822
823    // Search if we have already a VertDecl matching the VertBufDesc,
824    // if not create a new VertDecl and store it in VertDeclMap.
825    s3d_CDrvD3d9VertElemObjRef ElemObjRef;
826    ElemObjRef.m_VertElemCnt = VertElemCnt;
827    ElemObjRef.m_VertElemArray = VertElemArray;
828
829    if(!s3d_UtilMapGetAtInto(m_VertDeclMap, ElemObjRef, VertDecl))
830    {
831        DWORD Stream = 0;
832        UINT VertSize;
833        S3D_DRV_D3D9_HRESCALL(
834                m_Env, VertSize, D3DXGetDeclVertexSize(VertElemArray, Stream));
835        if(VertSize != VertBufDesc.m_VertSize)
836        {
837            s3d_CUtilMsg e;
838            e.m_Code =
839                    "drv/imp/directx/d3d9/drv_d3d9_buf."
840                    "vertdecl_size_missmatch";
841            e.m_StdTempl = "Vertex declaration [1] size mismatch. "
842                            "D3D size is [2]. Calculated size is [3]. ";
843            e.AddInfo("");
844            e.AddInfo(s3d_CDrvD3d9Util::StrOfVertElemArray(
845                    VertElemCnt, VertElemArray));
846            e.AddInfo(s3d_CUtilStrUtil::StrOfInt64s(VertSize));
847            e.AddInfo(s3d_CUtilStrUtil::StrOfInt64s(VertBufDesc.m_VertSize));
848            s3d_UtilMsgReportError(m_MsgHandler, e);
849            S3D_SYS_ASSERT(0);
850            return;
851        }
852
853        S3D_DRV_D3D9_CHECK(
854                m_Env, m_D3dDev->CreateVertexDeclaration(
855                    VertElemArray, &VertDecl.EmptyRef()));
856        if(!VertDecl)
857            return;
858
859        s3d_CDrvD3d9VertElemObjPtr VertElemObj
860                = S3D_SYS_NEW s3d_CDrvD3d9VertElemObj;
861        VertElemObj->m_VertElemCnt = VertElemCnt;
862        VertElemObj->m_VertElemArray.Alloc(VertElemCnt);
863        s3d_SysMemcpy(
864                VertElemObj->m_VertElemArray, VertElemArray,
865                VertElemCnt * S3D_SYS_SIZEOFS(D3DVERTEXELEMENT9));
866
867        s3d_CDrvD3d9VertElemObjKey VertElemObjKey;
868        VertElemObjKey.m_VertElemObj = VertElemObj;
869        m_VertDeclMap.SetAt(VertElemObjKey, VertDecl);
870    }
871}
872
873
874s3d_CDrvD3d9VertBufObjBatchPtr s3d_CDrvD3d9BufMgr::AllocVertBufObj(
875        const s3d_CDrvGfxCharge *Charge,
876        const s3d_CDrvD3d9VertBufDesc &VertBufDesc,
877        LPDIRECT3DVERTEXDECLARATION9 VertDecl,
878        bool SWVertProc)
879{
880    s3d_CSysIntps VertCnt = Charge->m_Topol.m_VertCnt;
881    s3d_CSysIntps VertBufSize = VertBufDesc.m_VertSize * VertCnt;
882
883    s3d_CSysIntps Offs = 0;
884    s3d_CDrvD3d9VertBuf VertBuf;
885    DWORD Usage = D3DUSAGE_WRITEONLY;
886    if(SWVertProc)
887        Usage |= D3DUSAGE_SOFTWAREPROCESSING;
888    D3DPOOL Pool = D3DPOOL_MANAGED;
889    DWORD FVF = 0;
890    S3D_DRV_D3D9_CHECK(
891            m_Env, m_D3dDev->CreateVertexBuffer(
892                UINT(VertBufSize), Usage, FVF, Pool, &VertBuf.EmptyRef(), 0));
893    if(!VertBuf)
894        return 0;
895
896    D3DVERTEXBUFFER_DESC D3dVertBufDesc;
897    S3D_DRV_D3D9_CHECK(m_Env, VertBuf->GetDesc(&D3dVertBufDesc));
898   
899    s3d_CDrvD3d9VertBufObjBatchPtr VertBufObj
900            = S3D_SYS_NEW s3d_CDrvD3d9VertBufObjBatch;
901    VertBufObj->m_MainInfo = Charge->m_MainInfo;
902    VertBufObj->m_VertBuf = VertBuf;
903    VertBufObj->m_BufSize = VertBufSize;
904    VertBufObj->m_VertSize = VertBufDesc.m_VertSize;
905    VertBufObj->m_VertDecl = VertDecl;
906    VertBufObj->m_VertBufFmtDecl = VertBufDesc.m_VertBufFmtDecl;
907    VertBufObj->m_Pool = D3dVertBufDesc.Pool;
908    VertBufObj->m_Usage = D3dVertBufDesc.Usage;
909    if(m_D3dParam->m_ReportBuf)
910    {
911        VertBufObj->m_ReportMsgHandler = m_MsgHandler;
912
913        s3d_CUtilMsg m;
914        m.m_Code = "drv/imp/directx/d3d9/drv_d3d9_buf.report_vertbuf_create";
915        m.m_StdTempl = "D3D: "
916            "Creating new vertex buffer object addr=0x[1] size=[2]: "
917            "'[3]'";
918        m.AddInfo("");
919        m.AddInfo(s3d_CUtilStrUtil::StrOfPtr(VertBufObj));
920        m.AddInfo(s3d_CUtilStrUtil::StrOfIntps(VertBufSize));
921        m.AddInfo(Charge->m_MainInfo);
922        s3d_UtilMsgReportNote(m_MsgHandler, m);
923    }
924
925    s3d_CSysIntps DestVertBase = 0;
926    s3d_CSysIntps VertBase = 0;
927    bool DynOnly = false;
928    bool Discard = false;
929    LoadVertBuf(
930            Charge, VertBufObj, VertBufDesc, Offs, DestVertBase,
931            VertBase, VertCnt, DynOnly, Discard);
932
933#ifndef S3D_DRV_D3D9_NO_DUMMY_STREAMS
934    if(!m_D3dParam->m_NoDummyBoneVertexBuf)
935    {
936        int VertBufFmtDecl = VertBufDesc.m_VertBufFmtDecl;
937        CheckAllocDummyBuffers(Charge, VertBufFmtDecl, SWVertProc);
938    }
939#endif
940
941    return VertBufObj;
942}
943
944void s3d_CDrvD3d9BufMgr::LoadVertBuf(
945        const s3d_CDrvGfxCharge *Charge, s3d_CDrvD3d9VertBufObj *VertBuf,
946        const s3d_CDrvD3d9VertBufDesc &VertBufDesc,
947        s3d_CSysIntps DestStartOffs,
948        s3d_CSysIntps DestVertBase, s3d_CSysIntps VertBase,
949        s3d_CSysIntps VertCnt, bool DynOnly, bool Discard)
950{
951    if(!Charge)
952        return;
953    if(!VertBuf)
954        return;
955
956    LPDIRECT3DVERTEXBUFFER9 D3dVertBuf = VertBuf->m_VertBuf;
957    if(!D3dVertBuf)
958        return;
959
960    s3d_CSysIntps VertSize = VertBuf->m_VertSize;
961    UINT LockSize = UINT(VertCnt * VertSize);
962    UINT LockOffset = UINT(DestVertBase * VertSize) + DestStartOffs;
963    DWORD Flags = 0;
964    if(Discard)
965        Flags = D3DLOCK_DISCARD;
966
967    void *LockTarget;
968    S3D_DRV_D3D9_CHECK(
969            m_Env, D3dVertBuf->Lock(
970                LockOffset, LockSize, &LockTarget, Flags));
971    if(!LockTarget)
972        return;
973
974    s3d_CSysIntm *Data = reinterpret_cast<s3d_CSysIntm *>(LockTarget);
975    LoadVertBufData(Charge, VertBufDesc, Data, VertBase, VertCnt, DynOnly);
976
977    S3D_DRV_D3D9_CHECK(
978            m_Env, D3dVertBuf->Unlock());
979
980    if(m_D3dParam->m_PreloadResources && VertBuf->m_Pool == D3DPOOL_MANAGED)
981    {
982        S3D_DRV_D3D9_CALL(m_Env, D3dVertBuf->PreLoad());
983    }
984}
985
986void s3d_CDrvD3d9BufMgr::LoadVertBufData(
987        const s3d_CDrvGfxCharge *Charge,
988        const s3d_CDrvD3d9VertBufDesc &VertBufDesc, s3d_CSysIntm *Dest,
989        s3d_CSysIntps VertBase, s3d_CSysIntps VertCnt, bool DynOnly)
990{
991    const s3d_CDrvD3d9DummyWghAttr DummyWghAttr;
992    const s3d_CDrvD3d9DummySubscrAttr DummySubscrAttr;
993
994    s3d_CSysIntps VertexSize = VertBufDesc.m_VertSize;
995    s3d_CSysIntps AttrCnt = VertBufDesc.m_VertElemCnt - 1; // DECL_END()
996    int VertBufFmtDecl = VertBufDesc.m_VertBufFmtDecl;
997
998    const s3d_CDrvGfxAttr *Attr = 0;
999    s3d_CSysIntps iAttr;
1000    for(iAttr = 0; iAttr < AttrCnt; iAttr++)
1001    {
1002        const D3DVERTEXELEMENT9 *VertElemArray
1003                = &VertBufDesc.m_VertElemArray[iAttr];
1004        switch(VertElemArray->Usage)
1005        {
1006            case D3DDECLUSAGE_POSITION:
1007            {
1008                Attr = VertBufDesc.m_PointAttr;
1009                break;
1010            }
1011            case D3DDECLUSAGE_BLENDWEIGHT:
1012            {
1013                Attr = VertBufDesc.m_BoneWghAttr;
1014                if((VertBufFmtDecl
1015                        & s3d_CDrvD3d9VertBufDesc::Decl_DummyBoneWgh)
1016                    && VertElemArray->Stream == 0)
1017                {
1018                    Attr = &DummyWghAttr;
1019                }
1020                break;
1021            }
1022            case D3DDECLUSAGE_BLENDINDICES:
1023            {
1024                Attr = VertBufDesc.m_BoneSubscrAttr;
1025                if((VertBufFmtDecl &
1026                        s3d_CDrvD3d9VertBufDesc::Decl_DummyBoneSubscr)
1027                    && VertElemArray->Stream == 0)
1028                {
1029                    Attr = &DummySubscrAttr;
1030                }
1031                break;
1032            }
1033            case D3DDECLUSAGE_NORMAL:
1034            {
1035                Attr = VertBufDesc.m_NormalAttr;
1036                break;
1037            }
1038            case D3DDECLUSAGE_COLOR:
1039            {
1040                Attr = VertBufDesc.m_ColorAlphaAttr;
1041                break;
1042            }
1043            case D3DDECLUSAGE_TEXCOORD:
1044            {
1045                int Idx = VertElemArray->UsageIndex;
1046                Attr = VertBufDesc.m_TexAttrArray[Idx];
1047                break;
1048            }
1049            default:
1050            {
1051                S3D_SYS_ASSERT(0);
1052                continue;
1053            }
1054        }
1055        if(!Attr)
1056            continue;
1057
1058        if(DynOnly && !Attr->m_BankDyn)
1059            continue;
1060       
1061        s3d_CDrvBankContent BankContent;
1062        s3d_DrvBankFetch(
1063                m_MsgHandler, Charge->m_MainInfo,
1064                "d3d_load_vertex_buf_data", Attr->m_Bank,
1065                BankContent);
1066        if(!BankContent.m_Data)
1067            continue;
1068        const s3d_CSysIntm *EffData
1069                = BankContent.m_Data + VertBase * BankContent.m_Stride;
1070        s3d_CSysIntm *Target = Dest + VertElemArray->Offset;
1071
1072        DWORD DestType = VertElemArray->Type;
1073        switch(DestType)
1074        {
1075        case D3DDECLTYPE_FLOAT2:
1076            {
1077                if(BankContent.m_TypeDesc
1078                        == s3d_DrvDataGetTypeDesc<s3d_CDrvFloat32X2>())
1079                {
1080                    s3d_CDrvD3d9BufInitUtil::InitFloatX2ToFloat32X2(
1081                            Target, VertexSize, EffData, VertCnt,
1082                                    BankContent.m_Stride);
1083                }
1084                else
1085                    s3d_CDrvD3d9BufInitUtil::VertFormatError(
1086                            m_MsgHandler, Charge);
1087                break;
1088            }
1089        case D3DDECLTYPE_FLOAT3:
1090            {
1091                if(BankContent.m_TypeDesc
1092                        == s3d_DrvDataGetTypeDesc<s3d_CDrvFloat32X3>())
1093                {
1094                    s3d_CDrvD3d9BufInitUtil::InitFloatX3ToFloat32X3(
1095                            Target, VertexSize, EffData, VertCnt,
1096                                    BankContent.m_Stride);
1097                }
1098                else if(BankContent.m_TypeDesc
1099                        == s3d_DrvDataGetTypeDesc<s3d_CDrvFloat32X4>())
1100                {
1101                    S3D_SYS_ASSERT(
1102                            VertElemArray->Usage == D3DDECLUSAGE_BLENDWEIGHT);
1103                    s3d_CDrvD3d9BufInitUtil::InitFloatX3ToFloat32X3(
1104                            Target, VertexSize, EffData, VertCnt,
1105                                    BankContent.m_Stride);
1106                }
1107                else
1108                    s3d_CDrvD3d9BufInitUtil::VertFormatError(
1109                            m_MsgHandler, Charge);
1110                break;
1111            }
1112        case D3DDECLTYPE_FLOAT4:
1113            {
1114                if(BankContent.m_TypeDesc
1115                        == s3d_DrvDataGetTypeDesc<s3d_CDrvFloat32X4>())
1116                {
1117                    s3d_CDrvD3d9BufInitUtil::InitFloatX4ToFloat32X4(
1118                            Target, VertexSize, EffData, VertCnt,
1119                                    BankContent.m_Stride);
1120                }
1121                else
1122                    s3d_CDrvD3d9BufInitUtil::VertFormatError(
1123                            m_MsgHandler, Charge);
1124                break;
1125            }
1126        case D3DDECLTYPE_D3DCOLOR:
1127            {
1128                if(BankContent.m_TypeDesc
1129                        == s3d_DrvDataGetTypeDesc<s3d_CDrvFloat32X3>())
1130                {
1131                    s3d_CDrvD3d9BufInitUtil::InitFloatX3ToColor(
1132                            Target, VertexSize, EffData, VertCnt,
1133                                    BankContent.m_Stride);
1134                }
1135                else if(BankContent.m_TypeDesc
1136                        == s3d_DrvDataGetTypeDesc<s3d_CDrvFloat32X4>())
1137                {
1138                    s3d_CDrvD3d9BufInitUtil::InitFloatX4ToColor(
1139                            Target, VertexSize, EffData, VertCnt,
1140                                    BankContent.m_Stride);
1141                }
1142                else
1143                    s3d_CDrvD3d9BufInitUtil::VertFormatError(
1144                            m_MsgHandler, Charge);
1145                break;
1146            }
1147        case D3DDECLTYPE_UBYTE4:
1148            {
1149                if(BankContent.m_TypeDesc
1150                        == s3d_DrvDataGetTypeDesc<s3d_CDrvInt32uX4>())
1151                {
1152                    s3d_CDrvD3d9BufInitUtil::InitIntX4ToInt8uX4(
1153                            Target, VertexSize, EffData, VertCnt,
1154                                    BankContent.m_Stride);
1155                }
1156                else if(BankContent.m_TypeDesc
1157                        == s3d_DrvDataGetTypeDesc<s3d_CDrvFloat32X3>())
1158                {
1159                    // Compress float[-1..1] to int[0..255]
1160                    s3d_CDrvD3d9BufInitUtil::InitFloatX3ToInt8uX4(
1161                            Target, VertexSize, EffData, VertCnt,
1162                                    BankContent.m_Stride);
1163                }
1164                else if(BankContent.m_TypeDesc
1165                        == s3d_DrvDataGetTypeDesc<s3d_CDrvFloat32X4>())
1166                {
1167                    // Compress float[0..1] to int[0..255]
1168                    s3d_CDrvD3d9BufInitUtil::InitFloatX4ToInt8uX4(
1169                            Target, VertexSize, EffData, VertCnt,
1170                                    BankContent.m_Stride);
1171                }
1172                else
1173                    s3d_CDrvD3d9BufInitUtil::VertFormatError(
1174                            m_MsgHandler, Charge);
1175                break;
1176            }
1177/*
1178        case D3DDECLTYPE_FLOAT1:
1179        case D3DDECLTYPE_SHORT2:
1180        case D3DDECLTYPE_SHORT4:
1181        case D3DDECLTYPE_UBYTE4N:
1182        case D3DDECLTYPE_SHORT2N:
1183        case D3DDECLTYPE_SHORT4N:
1184        case D3DDECLTYPE_USHORT2N:
1185        case D3DDECLTYPE_USHORT4N:
1186        case D3DDECLTYPE_UDEC3:
1187        case D3DDECLTYPE_DEC3N:
1188        case D3DDECLTYPE_FLOAT16_2:
1189        case D3DDECLTYPE_FLOAT16_4:
1190*/
1191        default:
1192            s3d_CDrvD3d9BufInitUtil::VertFormatError(m_MsgHandler, Charge);
1193            break;
1194        }
1195    }
1196}
1197
1198void s3d_CDrvD3d9BufMgr::CalcVertBufDesc(
1199        const s3d_CDrvGfxCharge *Charge, s3d_CDrvD3d9VertBufDesc &VertBufDesc)
1200{
1201    VertBufDesc.Reset();
1202
1203    if(!Charge)
1204        return;
1205
1206    bool Complete = true;
1207    int VertBufFmtDecl = 0;
1208
1209    s3d_CDrvGfxAttr *PointAttr = 0;
1210    s3d_CDrvGfxAttr *ColorAlphaAttr = 0;
1211    s3d_CDrvGfxAttr *NormalAttr = 0;
1212    s3d_CDrvGfxAttr *BoneWghAttr = 0;
1213    s3d_CDrvGfxAttr *BoneSubscrAttr = 0;
1214    s3d_CDrvGfxAttr *TexAttrArray[S3D_DRV_D3D9_MAX_ATTR_CNT];
1215
1216    int TexSlotCnt = 0;
1217    const s3d_CDrvDataTypeDesc *TexTypeDescArray[S3D_DRV_D3D9_MAX_ATTR_CNT];
1218    int iTex;
1219    for(iTex = 0; iTex < S3D_DRV_D3D9_MAX_ATTR_CNT; iTex++)
1220    {
1221        TexTypeDescArray[iTex] = 0;
1222        TexAttrArray[iTex] = 0;
1223    }
1224
1225    int iAttr;
1226    for(iAttr = 0; iAttr < Charge->m_AttrCnt; iAttr++)
1227    {
1228        s3d_CDrvGfxAttr *Attr = &Charge->m_AttrArray[iAttr];
1229
1230        if(Attr->m_BankDyn)
1231            Complete = false;
1232
1233        s3d_CDrvBankContent BankContent;
1234        s3d_DrvBankFetch(
1235                m_MsgHandler, Charge->m_MainInfo,
1236                "attr", Attr->m_Bank, BankContent);
1237
1238        int Slot = Attr->m_Slot;
1239        int Chan = Attr->m_Chan;
1240        switch(Chan)
1241        {
1242            case s3d_CDrvGfxEng::AttrChan_Generic:
1243            {
1244                if(s3d_SysIsValidArrayIdx(Slot, S3D_DRV_D3D9_MAX_ATTR_CNT))
1245                {
1246                    while(TexSlotCnt <= Slot)
1247                        TexTypeDescArray[TexSlotCnt++] = 0;
1248                    TexTypeDescArray[Slot] = BankContent.m_TypeDesc;
1249                    TexAttrArray[Slot] = Attr;
1250                    VertBufFmtDecl |= s3d_CDrvD3d9VertBufDesc::Decl_Generic;
1251                }
1252                break;
1253            }
1254            case s3d_CDrvGfxEng::AttrChan_Point:
1255            {
1256                if(Slot == 0)
1257                {
1258                    VertBufFmtDecl |= s3d_CDrvD3d9VertBufDesc::Decl_Point;
1259                    PointAttr = Attr;
1260                }
1261                break;
1262            }
1263            case s3d_CDrvGfxEng::AttrChan_ColorAlpha:
1264            {
1265                if(Slot == 0)
1266                {
1267                    VertBufFmtDecl |= s3d_CDrvD3d9VertBufDesc::Decl_ColorAlpha;
1268                    ColorAlphaAttr = Attr;
1269                }
1270                break;
1271            }
1272            case s3d_CDrvGfxEng::AttrChan_Normal:
1273            {
1274                if(Slot == 0)
1275                {
1276                    VertBufFmtDecl |= s3d_CDrvD3d9VertBufDesc::Decl_Normal;
1277                    NormalAttr = Attr;
1278                }
1279                break;
1280            }
1281            case s3d_CDrvGfxEng::AttrChan_BoneWgh:
1282            {
1283                if(Slot == 0)
1284                {
1285                    VertBufFmtDecl |= s3d_CDrvD3d9VertBufDesc::Decl_BoneWgh;
1286                    BoneWghAttr = Attr;
1287                }
1288                break;
1289            }
1290            case s3d_CDrvGfxEng::AttrChan_BoneSubscr:
1291            {
1292                if(Slot == 0)
1293                {
1294                    VertBufFmtDecl |= s3d_CDrvD3d9VertBufDesc::Decl_BoneSubscr;
1295                    BoneSubscrAttr = Attr;
1296                }
1297                break;
1298            }
1299        }
1300    }
1301
1302    D3DVERTEXELEMENT9 *VertElemArray = VertBufDesc.m_VertElemArray;
1303    WORD DeclOffs = 0;
1304    WORD VertElemStream = 0;
1305    if(VertBufFmtDecl & s3d_CDrvD3d9VertBufDesc::Decl_Point)
1306    {
1307        const D3DVERTEXELEMENT9 DeclPoint =
1308        {
1309            VertElemStream, DeclOffs, D3DDECLTYPE_FLOAT3,
1310            D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0
1311        };
1312        DeclOffs = DeclOffs + S3D_SYS_SIZEOFS(float) * 3;
1313        VertBufDesc.m_PointAttr = PointAttr;
1314        *VertElemArray++ = DeclPoint;
1315    }
1316    if(VertBufFmtDecl & s3d_CDrvD3d9VertBufDesc::Decl_BoneWgh)
1317    {
1318        const D3DVERTEXELEMENT9 DeclBlendWgh =
1319        {
1320            VertElemStream, DeclOffs, D3DDECLTYPE_FLOAT3,
1321            D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0
1322        };
1323        DeclOffs = DeclOffs + S3D_SYS_SIZEOFS(float) * 3;
1324        VertBufDesc.m_BoneWghAttr = BoneWghAttr;
1325        *VertElemArray++ = DeclBlendWgh;
1326    }
1327    if(VertBufFmtDecl & s3d_CDrvD3d9VertBufDesc::Decl_BoneSubscr)
1328    {
1329        const D3DVERTEXELEMENT9 DeclBlendIdx =
1330        {
1331            VertElemStream, DeclOffs, D3DDECLTYPE_UBYTE4,
1332            D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0
1333        };
1334        DeclOffs = DeclOffs + S3D_SYS_SIZEOFS(DWORD);
1335        VertBufDesc.m_BoneSubscrAttr = BoneSubscrAttr;
1336        *VertElemArray++ = DeclBlendIdx;
1337    }
1338    if(VertBufFmtDecl & s3d_CDrvD3d9VertBufDesc::Decl_ColorAlpha)
1339    {
1340        const D3DVERTEXELEMENT9 DeclColorAlpha =
1341        {
1342            VertElemStream, DeclOffs, D3DDECLTYPE_D3DCOLOR,
1343            D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0
1344        };
1345        DeclOffs = DeclOffs + S3D_SYS_SIZEOFS(DWORD);
1346        VertBufDesc.m_ColorAlphaAttr = ColorAlphaAttr;
1347        *VertElemArray++ = DeclColorAlpha;
1348    }
1349    if(VertBufFmtDecl & s3d_CDrvD3d9VertBufDesc::Decl_Normal)
1350    {
1351        const D3DVERTEXELEMENT9 DeclNormal =
1352        {
1353            VertElemStream, DeclOffs, D3DDECLTYPE_FLOAT3,
1354            D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0
1355        };
1356        DeclOffs = DeclOffs + S3D_SYS_SIZEOFS(float) * 3;
1357        VertBufDesc.m_NormalAttr = NormalAttr;
1358        *VertElemArray++ = DeclNormal;
1359    }
1360
1361    for(iTex = 0; iTex < TexSlotCnt; iTex++)
1362    {
1363        WORD TexOffs = S3D_SYS_SIZEOFS(float) * 2;
1364        D3DDECLTYPE TexType = D3DDECLTYPE_FLOAT2;
1365        D3DVERTEXELEMENT9 DeclTex;
1366        const s3d_CDrvDataTypeDesc *TexTypeDesc = TexTypeDescArray[iTex];
1367        if(TexTypeDesc == s3d_DrvDataGetTypeDesc<s3d_CDrvFloat32X2>())
1368        {
1369            TexOffs = S3D_SYS_SIZEOFS(float) * 2;
1370            TexType = D3DDECLTYPE_FLOAT2;
1371        }
1372        else if(TexTypeDesc == s3d_DrvDataGetTypeDesc<s3d_CDrvFloat32>())
1373        {
1374            TexOffs = S3D_SYS_SIZEOFS(float);
1375            TexType = D3DDECLTYPE_FLOAT1;
1376        }
1377        else if(TexTypeDesc == s3d_DrvDataGetTypeDesc<s3d_CDrvFloat32X3>())
1378        {
1379            TexOffs = S3D_SYS_SIZEOFS(float) * 3;
1380            TexType = D3DDECLTYPE_FLOAT3;
1381        }
1382        else if(TexTypeDesc == s3d_DrvDataGetTypeDesc<s3d_CDrvFloat32X4>())
1383        {
1384            TexOffs = S3D_SYS_SIZEOFS(float) * 4;
1385            TexType = D3DDECLTYPE_FLOAT4;
1386        }
1387        else
1388        {
1389            S3D_SYS_ASSERT(0);
1390        }
1391
1392        DeclTex.Stream = VertElemStream;
1393        DeclTex.Offset = DeclOffs;
1394        DeclTex.Type = TexType;
1395        DeclTex.Method = D3DDECLMETHOD_DEFAULT;
1396        DeclTex.Usage = D3DDECLUSAGE_TEXCOORD;
1397        DeclTex.UsageIndex = BYTE(iTex);
1398
1399        DeclOffs += TexOffs;
1400        VertBufDesc.m_TexAttrArray[iTex] = TexAttrArray[iTex];
1401        *VertElemArray++ = DeclTex;
1402    }
1403
1404    const D3DVERTEXELEMENT9 DeclEnd = D3DDECL_END();
1405    *VertElemArray = DeclEnd;
1406    VertBufDesc.m_VertElemCnt = Charge->m_AttrCnt + 1; //D3DDECL_END()
1407    VertBufDesc.m_VertSize = DeclOffs;
1408    VertBufDesc.m_VertBufFmtDecl = VertBufFmtDecl;
1409}
1410
1411///////////////////////////////////////////////////////////////////////////////
1412
1413s3d_CDrvD3d9IdxBufObjBatchPtr s3d_CDrvD3d9BufMgr::AllocIdxBufObj(
1414        const s3d_CDrvGfxCharge *Charge,
1415        D3DFORMAT Fmt, DWORD Usage, D3DPOOL Pool)
1416{
1417    s3d_CSysIntps IdxCnt = Charge->m_Topol.m_IdxCnt;
1418    s3d_CSysIntps IdxBufSize = CalcSizeOfFmtCnt(Fmt, IdxCnt);
1419
1420    s3d_CDrvD3d9IdxBuf IdxBuf;
1421    S3D_DRV_D3D9_CHECK(
1422            m_Env, m_D3dDev->CreateIndexBuffer(
1423                UINT(IdxBufSize), Usage, Fmt, Pool, &IdxBuf.EmptyRef(), 0));
1424    if(!IdxBuf)
1425        return 0;
1426
1427    D3DINDEXBUFFER_DESC IdxBufDesc;
1428    S3D_DRV_D3D9_CHECK(m_Env, IdxBuf->GetDesc(&IdxBufDesc));
1429   
1430    s3d_CDrvD3d9IdxBufObjBatchPtr IdxBufObj
1431            = S3D_SYS_NEW s3d_CDrvD3d9IdxBufObjBatch;
1432    IdxBufObj->m_IdxBuf = IdxBuf;
1433    IdxBufObj->m_BufSize = IdxBufDesc.Size;
1434    IdxBufObj->m_Pool = IdxBufDesc.Pool;
1435    IdxBufObj->m_Usage = IdxBufDesc.Usage;
1436    IdxBufObj->m_Fmt = IdxBufDesc.Format;
1437    IdxBufObj->m_TopolSig = Charge->m_Topol.m_TopolSig;
1438    if(m_D3dParam->m_ReportBuf)
1439    {
1440        IdxBufObj->m_ReportMsgHandler = m_MsgHandler;
1441
1442        s3d_CUtilMsg m;
1443        m.m_Code = "drv/imp/directx/d3d9/drv_d3d9_buf.report_idxbuf_create";
1444        m.m_StdTempl = "D3D: "
1445            "Creating new index buffer object addr=0x[1] size=[2]: "
1446            "'[3]'";
1447        m.AddInfo("");
1448        m.AddInfo(s3d_CUtilStrUtil::StrOfPtr(IdxBufObj));
1449        m.AddInfo(s3d_CUtilStrUtil::StrOfIntps(IdxBufSize));
1450        m.AddInfo(Charge->m_MainInfo);
1451        s3d_UtilMsgReportNote(m_MsgHandler, m);
1452    }
1453
1454    int Prim = Charge->m_Topol.m_Prim;
1455    D3DPRIMITIVETYPE D3dPrim = D3DPT_POINTLIST;
1456    if(s3d_SysIsValidArrayIdx(Prim, S3D_SYS_ARRAYCNTS(drv_d3d9_PrimTable)))
1457        D3dPrim = drv_d3d9_PrimTable[Prim];
1458
1459    IdxBufObj->m_D3dPrim = D3dPrim;
1460    IdxBufObj->m_IdxCnt = IdxCnt;
1461
1462    LoadIdxBuf(Charge, IdxBufObj, 0, 0, 0, false);
1463
1464    return IdxBufObj;
1465}
1466
1467void s3d_CDrvD3d9BufMgr::LoadIdxBuf(
1468        const s3d_CDrvGfxCharge *Charge, s3d_CDrvD3d9IdxBufObj *IdxBuf,
1469        s3d_CSysIntps DestIdxBase, s3d_CSysIntps VertOffset,
1470        s3d_CSysIntps IdxBase, bool Discard)
1471{
1472    if(!Charge)
1473        return;
1474    if(!IdxBuf)
1475        return;
1476
1477    LPDIRECT3DINDEXBUFFER9 D3dIdxBuf = IdxBuf->m_IdxBuf;
1478    if(!D3dIdxBuf)
1479        return;
1480
1481    D3DFORMAT Fmt = IdxBuf->m_Fmt;
1482    s3d_CSysIntps IdxCnt = IdxBuf->m_IdxCnt;
1483
1484    UINT LockSize = UINT(CalcSizeOfFmtCnt(Fmt, IdxCnt));
1485    UINT LockOffs = UINT(CalcSizeOfFmtCnt(Fmt, DestIdxBase));
1486    DWORD Flags = 0;
1487    if(Discard)
1488        Flags = D3DLOCK_DISCARD;
1489
1490    void *LockTarget = 0;
1491    S3D_DRV_D3D9_CHECK(
1492            m_Env, D3dIdxBuf->Lock(LockOffs, LockSize, &LockTarget, Flags));
1493    if(!LockTarget)
1494        return;
1495
1496    s3d_CSysIntm *Target = reinterpret_cast<s3d_CSysIntm*>(LockTarget);
1497    LoadIdxBufData(
1498            Charge, Fmt, Target, IdxCnt, DestIdxBase, VertOffset, IdxBase);
1499
1500    S3D_DRV_D3D9_CHECK(
1501            m_Env, D3dIdxBuf->Unlock());
1502
1503    if(m_D3dParam->m_PreloadResources && IdxBuf->m_Pool == D3DPOOL_MANAGED)
1504    {
1505        S3D_DRV_D3D9_CALL(m_Env, D3dIdxBuf->PreLoad());
1506    }
1507}
1508
1509void s3d_CDrvD3d9BufMgr::LoadIdxBufData(
1510        const s3d_CDrvGfxCharge *Charge, D3DFORMAT Fmt, s3d_CSysIntm *Dest,
1511        s3d_CSysIntps IdxCnt, s3d_CSysIntps DestIdxBase,
1512        s3d_CSysIntps VertOffset, s3d_CSysIntps IdxBase)
1513{
1514    const s3d_CSysInt32u *Data = s3d_DrvBankFetchArray<s3d_CSysInt32u>(
1515        m_MsgHandler, Charge->m_MainInfo, "idx", Charge->m_Topol.m_IdxBank,
1516        Charge->m_Topol.m_IdxCnt);
1517    if(!Data)
1518        return;
1519    const s3d_CSysInt32u *EffData = Data + IdxBase;
1520
1521    if(Fmt == D3DFMT_INDEX16)
1522    {
1523        s3d_CSysInt16u *Target = reinterpret_cast<s3d_CSysInt16u*>(Dest);
1524
1525        if(VertOffset == 0)
1526        {
1527            s3d_CSysIntps iIdx;
1528            for(iIdx = 0; iIdx < IdxCnt; iIdx++)
1529                Target[iIdx] = EffData[iIdx];
1530        }
1531        else
1532        {
1533            s3d_CSysIntps iIdx;
1534            for(iIdx = 0; iIdx < IdxCnt; iIdx++)
1535                Target[iIdx] = EffData[iIdx] - VertOffset;
1536        }
1537    }
1538    else if(Fmt == D3DFMT_INDEX32)
1539    {
1540        if(VertOffset == 0)
1541            s3d_SysMemcpy(Dest, EffData, IdxCnt << 2);
1542        else
1543        {
1544            s3d_CSysInt32u *Target = reinterpret_cast<s3d_CSysInt32u*>(Dest);
1545            s3d_CSysIntps iIdx;
1546            for(iIdx = 0; iIdx < IdxCnt; iIdx++)
1547                Target[iIdx] = EffData[iIdx] - VertOffset;
1548        }
1549    }
1550    else
1551    {
1552        s3d_CDrvDxError e;
1553        e.m_Code = "drv/imp/directx/d3d9/drv_d3d9_buf.unknown_index_format";
1554        e.m_StdTempl = "D3D: "
1555                        "Unknown index buffer or index data format.";
1556        e.AddInfo(Charge->m_MainInfo);
1557        s3d_UtilMsgReportFatal(m_MsgHandler, e);
1558    }
1559}
1560
1561D3DFORMAT s3d_CDrvD3d9BufMgr::CalcIdxBufFmtOfCnt(
1562        const s3d_CSysChar *Info, s3d_CSysIntps Cnt, bool Prefer32)
1563{
1564    D3DFORMAT IdxBufFmt = D3DFMT_INDEX16;
1565    if(Cnt > m_VertIdxLimit)
1566    {
1567        s3d_CDrvD3d9Error e;
1568        e.m_Code = "drv/imp/directx/d3d9/drv_d3d9_buf.max_index_cnt";
1569        e.m_StdTempl = "D3D error: "
1570                        "Vertex count [1] exceeds maximum [2].";
1571        e.AddInfo(Info);
1572        e.AddInfo(s3d_CUtilStrUtil::StrOfIntps(Cnt));
1573        e.AddInfo(s3d_CUtilStrUtil::StrOfIntps(m_VertIdxLimit));
1574        s3d_UtilMsgReportError(m_MsgHandler, e);
1575
1576        Cnt = m_VertIdxLimit;
1577    }
1578
1579    if(Cnt >= 0x10000)
1580        IdxBufFmt = D3DFMT_INDEX32;
1581    else if(Prefer32 && m_VertIdxLimit > 0x10000)
1582        IdxBufFmt = D3DFMT_INDEX32;
1583
1584    return IdxBufFmt;
1585}
1586
1587s3d_CSysIntps s3d_CDrvD3d9BufMgr::CalcSizeOfFmtCnt(
1588        D3DFORMAT IndexBufFmt, s3d_CSysIntps Cnt)
1589{
1590    s3d_CSysIntps BufSize = 0;
1591   
1592    if(IndexBufFmt == D3DFMT_INDEX16)
1593        BufSize = Cnt << 1;
1594    else if(IndexBufFmt == D3DFMT_INDEX32)
1595        BufSize = Cnt << 2;
1596   
1597    return BufSize;
1598}
1599
1600s3d_CSysIntps s3d_CDrvD3d9BufMgr::CalcCntOfFmtSize(
1601        D3DFORMAT IndexBufFmt, s3d_CSysIntps Size)
1602{
1603    s3d_CSysIntps Cnt = 0;
1604   
1605    if(IndexBufFmt == D3DFMT_INDEX16)
1606        Cnt =  Size >> 1;
1607    else if(IndexBufFmt == D3DFMT_INDEX32)
1608        Cnt =  Size >> 2;
1609   
1610    return Cnt;
1611}
1612
1613void s3d_CDrvD3d9BufMgr::CheckAllocDummyBuffers(
1614        const s3d_CDrvGfxCharge* Charge, int VertBufFmtDecl, bool SWVertProc)
1615{
1616    DWORD Usage = D3DUSAGE_WRITEONLY;
1617    if(SWVertProc)
1618        Usage |= D3DUSAGE_SOFTWAREPROCESSING;
1619    D3DPOOL Pool = D3DPOOL_MANAGED;
1620
1621    if((VertBufFmtDecl & s3d_CDrvD3d9VertBufDesc::Decl_DummyBoneWgh)
1622        || (VertBufFmtDecl & s3d_CDrvD3d9VertBufDesc::Decl_DummyBoneSubscr))
1623    {
1624        if(!m_VertBufDummyWghIdx.m_VertBuf)
1625        {
1626            CreateDummyVertBuf(Usage, Pool);
1627
1628            if(m_D3dParam->m_ReportBuf)
1629            {
1630                s3d_CUtilMsg m;
1631                m.m_Code =
1632                        "drv/imp/directx/d3d9/drv_d3d9_buf."
1633                        "report_vertbuf_dummyblendwghidx";
1634                m.m_StdTempl = "D3D: "
1635                    "Allocating dummy blend weight/ idx vertex buffer object "
1636                    "size=[2]: '[3]'";
1637                m.AddInfo("");
1638                m.AddInfo(s3d_CUtilStrUtil::StrOfIntps(
1639                        m_VertBufDummyWghIdx.m_UsedSize));
1640                m.AddInfo(Charge->m_MainInfo);
1641                s3d_UtilMsgReportNote(m_MsgHandler, m);
1642            }
1643        }
1644    }
1645}
1646
1647void s3d_CDrvD3d9BufMgr::CreateDummyVertBuf(
1648        DWORD Usage, D3DPOOL Pool)
1649{
1650    UINT AllocSize = S3D_SYS_SIZEOFU(DWORD) * 4; // wgh+idx
1651    s3d_CDrvD3d9VertBuf VertBuf;
1652    S3D_DRV_D3D9_CHECK(
1653            m_Env, m_D3dDev->CreateVertexBuffer(
1654                AllocSize, Usage, 0, Pool, &VertBuf.EmptyRef(), 0));
1655    LPVOID RawDest = 0;
1656    if(VertBuf)
1657    {
1658        S3D_DRV_D3D9_CHECK(
1659                m_Env, VertBuf->Lock(
1660                    0, AllocSize, &RawDest, 0));
1661    }
1662
1663    if(RawDest)
1664    {
1665        s3d_CDrvInt32uX4 *Dest
1666                = reinterpret_cast<s3d_CDrvInt32uX4 *>(RawDest);
1667        Dest->m_x = 0;
1668        Dest->m_y = 0;
1669        Dest->m_z = 0;
1670        Dest->m_w = 0x03020100;
1671
1672        S3D_DRV_D3D9_CHECK(
1673                m_Env, VertBuf->Unlock());
1674
1675        m_VertBufDummyWghIdx.m_VertBuf = VertBuf;
1676        m_VertBufDummyWghIdx.m_UsedSize = AllocSize;
1677
1678        if(m_D3dParam->m_PreloadResources && Pool == D3DPOOL_MANAGED)
1679        {
1680            S3D_DRV_D3D9_CALL(m_Env, VertBuf->PreLoad());
1681        }
1682    }
1683}
1684
1685void s3d_CDrvD3d9BufMgr::Reset()
1686{
1687    m_VertBufTree.ExtractAll();
1688    m_VertDeclMap.Reset();
1689    m_IdxBufTree.ExtractAll();
1690    m_VertBufDummyWghIdx.Reset();
1691    FreeDynBuffers();
1692}
1693
1694void s3d_CDrvD3d9BufMgr::FreeDynBuffers()
1695{
1696    if(m_VertBufDyn)
1697        m_VertBufDyn->Reset();
1698    if(m_IdxBufDyn)
1699        m_IdxBufDyn->Reset();
1700    m_VertBufDyn = 0;
1701    m_IdxBufDyn = 0;
1702}
1703
1704///////////////////////////////////////////////////////////////////////////////
1705
1706void s3d_CDrvD3d9BufInitUtil::InitFloatX2ToFloat32X2(
1707        s3d_CSysIntm *pDest, s3d_CSysIntps VertexSize,
1708        const s3d_CSysIntm *pSrc, s3d_CSysIntps Cnt, s3d_CSysIntps Stride)
1709{
1710    s3d_CSysIntps Rest;
1711    for(Rest = Cnt; Rest > 0; Rest--)
1712    {
1713        const float *pDataSrc
1714            = reinterpret_cast<const float*>(pSrc);
1715        s3d_CSysFloat32 *pDataDest
1716            = reinterpret_cast<s3d_CSysFloat32*>(pDest);
1717
1718        pDataDest[0] = pDataSrc[0];
1719        pDataDest[1] = pDataSrc[1];
1720
1721        pSrc  += Stride;
1722        pDest += VertexSize;
1723    }
1724}
1725
1726void s3d_CDrvD3d9BufInitUtil::InitFloatX3ToFloat32X3(
1727        s3d_CSysIntm *pDest, s3d_CSysIntps VertexSize,
1728        const s3d_CSysIntm *pSrc, s3d_CSysIntps Cnt, s3d_CSysIntps Stride)
1729{
1730    s3d_CSysIntps Rest;
1731    for(Rest = Cnt; Rest > 0; Rest--)
1732    {
1733        const float *pDataSrc
1734            = reinterpret_cast<const float*>(pSrc);
1735        s3d_CSysFloat32 *pDataDest
1736            = reinterpret_cast<s3d_CSysFloat32*>(pDest);
1737
1738        pDataDest[0] = pDataSrc[0];
1739        pDataDest[1] = pDataSrc[1];
1740        pDataDest[2] = pDataSrc[2];
1741
1742        pSrc  += Stride;
1743        pDest += VertexSize;
1744    }
1745}
1746
1747void s3d_CDrvD3d9BufInitUtil::InitFloatX4ToFloat32X4(
1748        s3d_CSysIntm *pDest, s3d_CSysIntps VertexSize,
1749        const s3d_CSysIntm *pSrc, s3d_CSysIntps Cnt, s3d_CSysIntps Stride)
1750{
1751    s3d_CSysIntps Rest;
1752    for(Rest = Cnt; Rest > 0; Rest--)
1753    {
1754        const float *pDataSrc
1755            = reinterpret_cast<const float*>(pSrc);
1756        s3d_CSysFloat32 *pDataDest
1757            = reinterpret_cast<s3d_CSysFloat32*>(pDest);
1758
1759        pDataDest[0] = pDataSrc[0];
1760        pDataDest[1] = pDataSrc[1];
1761        pDataDest[2] = pDataSrc[2];
1762        pDataDest[3] = pDataSrc[3];
1763
1764        pSrc  += Stride;
1765        pDest += VertexSize;
1766    }
1767}
1768
1769void s3d_CDrvD3d9BufInitUtil::InitFloatX3ToColor(
1770        s3d_CSysIntm *pDest, s3d_CSysIntps VertexSize,
1771        const s3d_CSysIntm *pSrc, s3d_CSysIntps Cnt, s3d_CSysIntps Stride)
1772{
1773    s3d_CSysIntps Rest;
1774    for(Rest = Cnt; Rest > 0; Rest--)
1775    {
1776        const float *pDataSrc
1777            = reinterpret_cast<const float*>(pSrc);
1778        LPDWORD pDataDest
1779            = reinterpret_cast<LPDWORD>(pDest);
1780
1781        float ColR = pDataSrc[0];
1782        float ColG = pDataSrc[1];
1783        float ColB = pDataSrc[2];
1784        float Alpha = 1;
1785        *pDataDest = S3D_DRV_D3D9_UTIL_COLORVALUE(ColR, ColG, ColB, Alpha);
1786
1787        pSrc   += Stride;
1788        pDest  += VertexSize;
1789    }
1790}
1791
1792void s3d_CDrvD3d9BufInitUtil::InitFloatX4ToColor(
1793        s3d_CSysIntm *pDest, s3d_CSysIntps VertexSize,
1794        const s3d_CSysIntm *pSrc, s3d_CSysIntps Cnt, s3d_CSysIntps Stride)
1795{
1796    s3d_CSysIntps Rest;
1797    for(Rest = Cnt; Rest > 0; Rest--)
1798    {
1799        const float *pDataSrc
1800            = reinterpret_cast<const float*>(pSrc);
1801        LPDWORD pDataDest
1802            = reinterpret_cast<LPDWORD>(pDest);
1803
1804        float ColR = pDataSrc[0];
1805        float ColG = pDataSrc[1];
1806        float ColB = pDataSrc[2];
1807        float Alpha = pDataSrc[3];
1808        *pDataDest = S3D_DRV_D3D9_UTIL_COLORVALUE(ColR, ColG, ColB, Alpha);
1809
1810        pSrc   += Stride;
1811        pDest  += VertexSize;
1812    }
1813}
1814
1815void s3d_CDrvD3d9BufInitUtil::InitIntX4ToInt8uX4(
1816        s3d_CSysIntm *pDest, s3d_CSysIntps VertexSize,
1817        const s3d_CSysIntm *pSrc, s3d_CSysIntps Cnt, s3d_CSysIntps Stride)
1818{
1819    s3d_CSysIntps Rest;
1820    for(Rest = Cnt; Rest > 0; Rest--)
1821    {
1822        const int *pDataSrc = reinterpret_cast<const int*>(pSrc);
1823        s3d_CSysInt8u *pDataDest = reinterpret_cast<s3d_CSysInt8u*>(pDest);
1824
1825        pDataDest[0] = (pDataSrc[0] & 0xFF);
1826        pDataDest[1] = (pDataSrc[1] & 0xFF);
1827        pDataDest[2] = (pDataSrc[2] & 0xFF);
1828        pDataDest[3] = (pDataSrc[3] & 0xFF);
1829
1830        pSrc  += Stride;
1831        pDest += VertexSize;
1832    }
1833}
1834
1835void s3d_CDrvD3d9BufInitUtil::InitFloatX3ToInt8uX4(
1836        s3d_CSysIntm *pDest, s3d_CSysIntps VertexSize,
1837        const s3d_CSysIntm *pSrc, s3d_CSysIntps Cnt, s3d_CSysIntps Stride)
1838{
1839    s3d_CSysIntps Rest;
1840    for(Rest = Cnt; Rest > 0; Rest--)
1841    {
1842        const float *pDataSrc = reinterpret_cast<const float*>(pSrc);
1843        s3d_CSysInt8u *pDataDest = reinterpret_cast<s3d_CSysInt8u*>(pDest);
1844        pDataDest[0] = s3d_SysIntOfFloatCoarse(pDataSrc[0] * 127.5f + 127.5f);
1845        pDataDest[1] = s3d_SysIntOfFloatCoarse(pDataSrc[1] * 127.5f + 127.5f);
1846        pDataDest[2] = s3d_SysIntOfFloatCoarse(pDataSrc[2] * 127.5f + 127.5f);
1847        pDataDest[3] = 0;
1848
1849        pSrc  += Stride;
1850        pDest += VertexSize;
1851    }
1852}
1853
1854void s3d_CDrvD3d9BufInitUtil::InitFloatX4ToInt8uX4(
1855        s3d_CSysIntm *pDest, s3d_CSysIntps VertexSize,
1856        const s3d_CSysIntm *pSrc, s3d_CSysIntps Cnt, s3d_CSysIntps Stride)
1857{
1858    s3d_CSysIntps Rest;
1859    for(Rest = Cnt; Rest > 0; Rest--)
1860    {
1861        const float *pDataSrc = reinterpret_cast<const float*>(pSrc);
1862        s3d_CSysInt8u *pDataDest = reinterpret_cast<s3d_CSysInt8u*>(pDest);
1863
1864        pDataDest[0] = s3d_SysIntOfFloatCoarse(pDataSrc[0] * 255.0f);
1865        pDataDest[1] = s3d_SysIntOfFloatCoarse(pDataSrc[1] * 255.0f);
1866        pDataDest[2] = s3d_SysIntOfFloatCoarse(pDataSrc[2] * 255.0f);
1867        pDataDest[3] = s3d_SysIntOfFloatCoarse(pDataSrc[3] * 255.0f);
1868
1869        pSrc  += Stride;
1870        pDest += VertexSize;
1871    }
1872}
1873
1874void s3d_CDrvD3d9BufInitUtil::VertFormatError(
1875        s3d_CUtilMsgHandler *MsgHandler, const s3d_CDrvGfxCharge *Charge)
1876{
1877    s3d_CDrvDxError e;
1878    e.m_Code = "drv/imp/directx/d3d9/drv_d3d9_buf.illegal_vertex_format";
1879    e.m_StdTempl = "D3D driver: Illegal vertex format.";
1880    e.AddInfo(s3d_CDrvGfxCharge::GetMainInfoOf(Charge));
1881    s3d_UtilMsgReportFatal(MsgHandler, e);
1882}
1883
1884
1885///////////////////////////////////////////////////////////////////////////////
Note: See TracBrowser for help on using the repository browser.