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

Revision 2236, 70.9 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//@cpp
15
16#include "drv_d3d9_proghlsl.h"
17#include "drv_d3d9_progutil.h"
18#include "drv_d3d9_progincmgr.h"
19#include "drv_d3d9_progreport.h"
20#include "drv_d3d9_util.h"
21#include "drv/interf/drv_vartypes.h"
22#include "drv/util/drv_util_varutil.h"
23#include "drv/util/drv_util_varfetch.h"
24#include "drv/util/drv_util_gfxprog.h"
25#include "util/os/util_filesystem.h"
26#include "util/snk/util_snk_extractutil.h"
27#include "util/notif/util_multinotif.h"
28#include "util/cont/util_arrayalgo.h"
29
30///////////////////////////////////////////////////////////////////////////////
31/*@{
32
33@declare{shaderprog.param}{<d3d9_hlsl_shader>}{$ [chunk]}
34
35Parameters for d3d HLSL @ident{shaderprog}{d3d9.hlsl_vertshader}
36and @ident{shaderprog}{d3d9.hlsl_pixshader}.
37This is a pseudo chunk name.
38
39@}*/
40///////////////////////////////////////////////////////////////////////////////
41
42#define S3D_DRV_D3D9_RESOLVEVAR(Var, VarInfo, VarName)\
43    s3d_CDrvD3d9ProgHLSLUtil::ResolveVar(\
44    ProgCtx, VarInfo, CodeName, ConstTab, Var, VarName, VarSet);
45
46///////////////////////////////////////////////////////////////////////////////
47
48s3d_CDrvD3d9ProgHLSL::s3d_CDrvD3d9ProgHLSL(
49        s3d_CUtilNotifGather *NotifGather, s3d_CUtilStr_cr Info,
50        s3d_CDrvD3d9ProgCtx *ProgCtx,
51        s3d_CUtilSnkChunk *ParamVert, s3d_CUtilSnkChunk *ParamPix)
52{
53    m_ProgCtx = ProgCtx;
54    m_Info = Info;
55    s3d_CUtilMemPoolFrm MemPoolFrm(ProgCtx->m_MemPool);
56
57    const s3d_CDrvD3d9Param *D3dParam = ProgCtx->m_D3dParam;
58    if(D3dParam->m_ReportProg)
59        m_ReportMsgHandler = ProgCtx->m_MsgHandler;
60
61    if(ParamVert)
62    {
63        s3d_CDrvD3d9ProgHLSLUtil::CreateShader(
64                NotifGather, ParamVert, ProgCtx,
65                true, this, m_VertTrackBlk);
66    }
67
68    if(ParamPix)
69    {
70        s3d_CDrvD3d9ProgHLSLUtil::CreateShader(
71                NotifGather, ParamPix, ProgCtx, false, this, m_PixTrackBlk);
72    }
73}
74
75void s3d_CDrvD3d9ProgHLSL::TrackParams(
76        s3d_CDrvGfxParam_cr GfxParam,
77        const s3d_CDrvD3d9ParamBlk &ParamBlk,
78        const s3d_CDrvD3d9ParamBlkState &ParamBlkState)
79{
80    TrackParams(GfxParam, ParamBlk, ParamBlkState, m_VertTrackBlk);
81    TrackParams(GfxParam, ParamBlk, ParamBlkState, m_PixTrackBlk);
82}
83
84void s3d_CDrvD3d9ProgHLSL::TrackTransfBone(
85        s3d_CSysIntps BoneIdxCnt, const s3d_CSysInt32u *BoneIdxData,
86        s3d_CSysIntps MatBoneCnt, const D3DXMATRIXA16 *MatBoneArray)
87{
88    TrackTransfBone(
89            BoneIdxCnt, BoneIdxData, MatBoneCnt, MatBoneArray,
90            m_VertTrackBlk);
91    TrackTransfBone(
92            BoneIdxCnt, BoneIdxData, MatBoneCnt, MatBoneArray,
93            m_PixTrackBlk);
94}
95
96void s3d_CDrvD3d9ProgHLSL::CalcVertBufDesc(
97        const s3d_CDrvGfxCharge *Charge,
98        s3d_CDrvD3d9VertBufDesc &VertBufDesc) const
99{
100    s3d_CDrvD3d9ProgUtil::CalcVertBufDesc(
101            m_ProgCtx, Charge, m_VertProgDecl.m_ProgUsage,
102            m_VertComprFmt, VertBufDesc);
103}
104
105bool s3d_CDrvD3d9ProgHLSL::IsValid()
106{
107    if(!m_VertTrackBlk.m_CodeName.IsEmpty() && !m_VertShader)
108        return false;
109    if(!m_PixTrackBlk.m_CodeName.IsEmpty() && !m_PixShader)
110        return false;
111    return true;
112}
113
114void s3d_CDrvD3d9ProgHLSL::GetVertProgCodeInfoName(
115        s3d_CUtilStr &CodeInfo, s3d_CUtilStr &CodeName) const
116{
117    CodeInfo = m_VertTrackBlk.m_CodeInfo;
118    CodeName = m_VertTrackBlk.m_CodeName;
119}
120
121void s3d_CDrvD3d9ProgHLSL::GetPixProgCodeInfoName(
122        s3d_CUtilStr &CodeInfo, s3d_CUtilStr &CodeName) const
123{
124    CodeInfo = m_PixTrackBlk.m_CodeInfo;
125    CodeName = m_PixTrackBlk.m_CodeName;
126}
127
128///////////////////////////////////////////////////////////////////////////////
129
130void s3d_CDrvD3d9ProgHLSL::TrackMatTrans(
131        const D3DXHANDLE &Var, int Trans,
132        const D3DXMATRIXA16 *Mat, s3d_CSysIntps Cnt,
133        const LPD3DXCONSTANTTABLE ConstTab, LPDIRECT3DDEVICE9 D3dDev)
134{
135    switch(Trans)
136    {
137        case s3d_CDrvUtilGfxProg::TrackTrans_Identity:
138        {
139            S3D_DRV_D3D9_CHECK(
140                    m_ProgCtx->m_Env, ConstTab->SetMatrixTransposeArray(
141                        D3dDev, Var, Mat, UINT(Cnt)));
142            break;
143        }
144        case s3d_CDrvUtilGfxProg::TrackTrans_Inv:
145        {
146            if(Cnt > 1)
147            {
148                D3DXMATRIXA16 *InvMat
149                        = reinterpret_cast<D3DXMATRIXA16 *>
150                            (alloca(Cnt * S3D_SYS_SIZEOFS(D3DXMATRIXA16)));
151                s3d_CSysIntps i;
152                for(i = 0; i < Cnt; i++)
153                    D3DXMatrixInverse(&InvMat[i], 0, Mat);
154                S3D_DRV_D3D9_CHECK(
155                        m_ProgCtx->m_Env, ConstTab->SetMatrixTransposeArray(
156                            D3dDev, Var, InvMat, UINT(Cnt)));
157            }
158            else
159            {
160                D3DXMATRIXA16 InvMat;
161                D3DXMatrixInverse(&InvMat, 0, Mat);
162                S3D_DRV_D3D9_CHECK(
163                    m_ProgCtx->m_Env,
164                        ConstTab->SetMatrixTranspose(D3dDev, Var, &InvMat));
165            }
166            break;
167        }
168        case s3d_CDrvUtilGfxProg::TrackTrans_Transp:
169        {
170            S3D_DRV_D3D9_CHECK(
171                    m_ProgCtx->m_Env, ConstTab->SetMatrixArray(
172                        D3dDev, Var, Mat, UINT(Cnt)));
173            break;
174        }
175        case s3d_CDrvUtilGfxProg::TrackTrans_InvTransp:
176        {
177            if(Cnt > 1)
178            {
179                D3DXMATRIXA16 *InvMat
180                        = reinterpret_cast<D3DXMATRIXA16 *>
181                            (alloca(Cnt * S3D_SYS_SIZEOFS(D3DXMATRIXA16)));
182                s3d_CSysIntps i;
183                for(i = 0; i < Cnt; i++)
184                    D3DXMatrixInverse(&InvMat[i], 0, Mat);
185                S3D_DRV_D3D9_CHECK(
186                        m_ProgCtx->m_Env, ConstTab->SetMatrixArray(
187                            D3dDev, Var, InvMat, UINT(Cnt)));
188            }
189            else
190            {
191                D3DXMATRIXA16 InvMat;
192                D3DXMatrixInverse(&InvMat, 0, Mat);
193                S3D_DRV_D3D9_CHECK(
194                        m_ProgCtx->m_Env, ConstTab->SetMatrix(
195                            D3dDev, Var, &InvMat));
196            }
197            break;
198        }
199        default:
200            S3D_SYS_ASSERT(0);
201            break;
202    }
203}
204
205void s3d_CDrvD3d9ProgHLSL::TrackParams(
206        s3d_CDrvGfxParam_cr GfxParam,
207        const s3d_CDrvD3d9ParamBlk &ParamBlk,
208        const s3d_CDrvD3d9ParamBlkState &ParamBlkState,
209        s3d_CDrvD3d9ProgHLSLTrackBlk &TrackBlk)
210{
211    LPDIRECT3DDEVICE9 D3dDev = m_ProgCtx->m_D3dDev;
212    if(!D3dDev)
213        return;
214    LPD3DXCONSTANTTABLE ConstTab = TrackBlk.m_ConstTab;
215    if(!ConstTab)
216        return;
217
218    S3D_DRV_D3D9_CHECK(
219            m_ProgCtx->m_Env, ConstTab->SetDefaults(D3dDev));
220
221    const s3d_CSysChar *Info = TrackBlk.m_CodeInfo.GetChars();
222
223    const s3d_CDrvD3d9ProgHLSLTrackMatArray *TrackMatArray
224            = &TrackBlk.m_MatTrackArray;
225    s3d_CSysIntps nTrackMat = TrackMatArray->GetCnt();
226    s3d_CSysIntps iTrackMat;
227    for(iTrackMat = 0; iTrackMat < nTrackMat; iTrackMat++)
228    {
229        const s3d_CDrvD3d9ProgHLSLTrackMat *TrackMat
230                = &TrackMatArray->RefAtRaw(iTrackMat);
231        D3DXHANDLE Var = TrackMat->m_Var;
232        if(!Var)
233            continue;
234
235        int Trans = TrackMat->m_Trans;
236        switch(TrackMat->m_Chan)
237        {
238            case s3d_CDrvUtilGfxProg::TrackChan_View:
239            {
240                if(ParamBlkState.m_DirtyMask
241                    & s3d_CDrvD3d9ParamBlkState::Dirty_MatView)
242                {
243                    TrackMatTrans(
244                            Var, Trans, &ParamBlk.m_MatView,
245                            1, ConstTab, D3dDev);
246                }
247                break;
248            }
249            case s3d_CDrvUtilGfxProg::TrackChan_Proj:
250            {
251                if(ParamBlkState.m_DirtyMask
252                    & s3d_CDrvD3d9ParamBlkState::Dirty_MatProj)
253                {
254                    TrackMatTrans(
255                            Var, Trans, &ParamBlk.m_MatProj, 1,
256                            ConstTab, D3dDev);
257                }
258                break;
259            }
260            case s3d_CDrvUtilGfxProg::TrackChan_ProjView:
261            {
262                if((ParamBlkState.m_DirtyMask
263                        & s3d_CDrvD3d9ParamBlkState::Dirty_MatView)
264                    || (ParamBlkState.m_DirtyMask
265                        & s3d_CDrvD3d9ParamBlkState::Dirty_MatProj))
266                {
267                    D3DXMATRIXA16 ProjView;
268                    D3DXMatrixMultiply(
269                            &ProjView, &ParamBlk.m_MatProj,
270                            &ParamBlk.m_MatView);
271                    TrackMatTrans(
272                            Var, Trans, &ProjView, 1, ConstTab, D3dDev);
273                }
274                break;
275            }
276            case s3d_CDrvUtilGfxProg::TrackChan_Attr:
277            {
278                if(ParamBlkState.m_DirtyMask
279                    & s3d_CDrvD3d9ParamBlkState::Dirty_MatGen)
280                {
281                    int Slot = TrackMat->m_Slot;
282                    const D3DXMATRIXA16 *Mat
283                            = &ParamBlk.m_MatGenArray[Slot];
284                    TrackMatTrans(
285                            Var, Trans, Mat, 1, ConstTab, D3dDev);
286                }
287                break;
288            }
289            default:
290                break;
291        }
292    }
293
294    if(ParamBlk.m_UseConstColorAlpha)
295        TrackNoLighting(ParamBlk, ParamBlkState, TrackBlk);
296    else
297        TrackLighting(ParamBlk, ParamBlkState, TrackBlk);
298
299    D3DXHANDLE Var = TrackBlk.m_FogVar;
300    if(Var && (ParamBlkState.m_DirtyMask
301        & s3d_CDrvD3d9ParamBlkState::Dirty_Fog))
302    {
303        S3D_DRV_D3D9_CHECK(
304                m_ProgCtx->m_Env, ConstTab->SetVector(
305                    D3dDev, Var, &ParamBlk.m_FogColDensity));
306    }
307
308    const s3d_CDrvD3d9TexObjBasePtr *SampTexArray = ParamBlk.m_SampTexArray;
309    const s3d_CDrvD3d9ProgHLSLVarArray *TexSizeArray
310            = &TrackBlk.m_TexSizeArray;
311    s3d_CSysIntps nTex = TexSizeArray->GetCnt();
312    s3d_CSysIntps iTex;
313    for(iTex = 0; iTex < nTex; iTex++)
314    {
315        D3DXHANDLE Var = TexSizeArray->GetAtRaw(iTex);
316        if(Var)
317        {
318            D3DXVECTOR4 Val(0, 0, 0, 0);
319            s3d_CDrvD3d9TexObjBase *Tex = 0;
320            if(iTex < m_ProgCtx->m_MaxSampCnt)
321                Tex = SampTexArray[iTex];
322            if(Tex)
323            {
324                Val.x = s3d_SysFloatOfInt<float>(Tex->m_Width);
325                Val.y = s3d_SysFloatOfInt<float>(Tex->m_Height);
326                Val.z = s3d_SysFloatOfInt<float>(Tex->m_Depth);
327                Val.w = 0;
328            }
329            S3D_DRV_D3D9_CHECK(
330                    m_ProgCtx->m_Env, ConstTab->SetVector(D3dDev, Var, &Val));
331        }
332    }
333
334    const s3d_CDrvD3d9ProgHLSLVarArray *TexRcpSizeArray
335            = &TrackBlk.m_TexRcpSizeArray;
336    nTex = TexRcpSizeArray->GetCnt();
337    for(iTex = 0; iTex < nTex; iTex++)
338    {
339        D3DXHANDLE Var = TexRcpSizeArray->GetAtRaw(iTex);
340        if(Var)
341        {
342            D3DXVECTOR4 Val(0, 0, 0, 0);
343            s3d_CDrvD3d9TexObjBase *Tex = 0;
344            if(iTex < m_ProgCtx->m_MaxSampCnt)
345                Tex = SampTexArray[iTex];
346            if(Tex)
347            {
348                Val.x = 1 / s3d_SysFloatOfInt<float>(Tex->m_Width);
349                Val.y = 1 / s3d_SysFloatOfInt<float>(Tex->m_Height);
350                Val.z = 1 / s3d_SysFloatOfInt<float>(Tex->m_Depth);
351                Val.w = 0;
352            }
353            S3D_DRV_D3D9_CHECK(
354                    m_ProgCtx->m_Env, ConstTab->SetVector(D3dDev, Var, &Val));
355        }
356    }
357
358    s3d_CDrvUtilVarFetch VarFetch(
359            m_ProgCtx->m_MsgHandler, GfxParam.m_Blk);
360
361    s3d_CDrvD3d9ProgHLSLParamEntry *ParamArray
362            = TrackBlk.m_ParamArray.GetPtrRaw();
363    s3d_CSysIntps nParam = TrackBlk.m_ParamArray.GetCnt();
364    s3d_CSysIntps iParam;
365    for(iParam = 0; iParam < nParam; iParam++)
366    {
367        s3d_CDrvD3d9ProgHLSLParamEntry *Param = &ParamArray[iParam];
368        s3d_CDrvVarSlot *VarSlot
369                = VarFetch.FetchNextSlot(
370                        Param->m_Val.m_Info.GetChars(), Param->m_Key,
371                        Param->m_Val.m_HadError,
372                        Param->m_Val.m_HadError);
373        s3d_CUtilRecogBase *VarRecog
374                = s3d_DrvVarFetchWary(m_ProgCtx->m_MsgHandler, Info,
375                    GfxParam.m_Blk, *VarSlot);
376       
377        if(!VarRecog)
378            continue;
379
380        const s3d_CDrvD3d9ProgHLSLParam *ParamEntry = &Param->m_Val;
381        D3DXHANDLE ParamVar = ParamEntry->m_Var;
382        if(!ParamVar)
383            continue;
384        const s3d_CSysChar *ParamInfo = ParamEntry->m_Info.GetChars();
385        switch(ParamEntry->m_Type)
386        {
387            case s3d_CDrvUtilGfxProg::ParamType_Float4:
388            {
389                const s3d_CDrvVarVec4f *DrvVar
390                        = s3d_DrvVarCast<s3d_CDrvVarVec4f>(
391                            m_ProgCtx->m_MsgHandler,
392                            ParamInfo, GfxParam.m_Blk,
393                            *VarSlot, VarRecog);
394                if(DrvVar)
395                {
396                    const float *fD3dVal
397                            = reinterpret_cast<const float*>(&DrvVar->m_Val);
398                    S3D_DRV_D3D9_CHECK(
399                            m_ProgCtx->m_Env, ConstTab->SetFloatArray(
400                                D3dDev, ParamVar, fD3dVal, 4));
401                }
402                break;
403            }
404
405            case s3d_CDrvUtilGfxProg::ParamType_Float4x4:
406            case s3d_CDrvUtilGfxProg::ParamType_Float4x4_Transp:
407            case s3d_CDrvUtilGfxProg::ParamType_Float4x4_Inv:
408            case s3d_CDrvUtilGfxProg::ParamType_Float4x4_InvTransp:
409            {
410                const s3d_CDrvVarMat4x4f *DrvVar;
411                DrvVar = s3d_DrvVarCast<s3d_CDrvVarMat4x4f>(
412                        m_ProgCtx->m_MsgHandler, ParamInfo, GfxParam.m_Blk,
413                        *VarSlot, VarRecog);
414                if(DrvVar)
415                {
416                    D3DXMATRIXA16 Mat;
417                    const s3d_CUtilMat4x4f *EngMat = &DrvVar->m_Val;
418                    Mat._11 = EngMat->m_xx;
419                    Mat._21 = EngMat->m_yx;
420                    Mat._31 = EngMat->m_zx;
421                    Mat._41 = EngMat->m_wx;
422                    Mat._12 = EngMat->m_xy;
423                    Mat._22 = EngMat->m_yy;
424                    Mat._32 = EngMat->m_zy;
425                    Mat._42 = EngMat->m_wy;
426                    Mat._13 = EngMat->m_xz;
427                    Mat._23 = EngMat->m_yz;
428                    Mat._33 = EngMat->m_zz;
429                    Mat._43 = EngMat->m_wz;
430                    Mat._14 = EngMat->m_xw;
431                    Mat._24 = EngMat->m_yw;
432                    Mat._34 = EngMat->m_zw;
433                    Mat._44 = EngMat->m_ww;
434                    int Trans = ParamEntry->m_Type; /*s3d_CDrvUtilGfxProg::TransOfParamType(
435                            ParamEntry->m_Type);*/
436                    TrackMatTrans(
437                            ParamVar, Trans, &Mat, 1, ConstTab, D3dDev);
438               }
439                break;
440            }
441            default:
442                S3D_SYS_ASSERT(0);
443                break;
444        }
445    }
446}
447
448void s3d_CDrvD3d9ProgHLSL::TrackNoLighting(
449        const s3d_CDrvD3d9ParamBlk &ParamBlk,
450        const s3d_CDrvD3d9ParamBlkState &ParamBlkState,
451        s3d_CDrvD3d9ProgHLSLTrackBlk &TrackBlk)
452{
453    LPDIRECT3DDEVICE9 D3dDev = m_ProgCtx->m_D3dDev;
454    LPD3DXCONSTANTTABLE ConstTab = TrackBlk.m_ConstTab;
455   
456    D3DXHANDLE Var = TrackBlk.m_Mtl.m_EmissiveVar;
457    if(Var)
458    {
459        const D3DXVECTOR4 *Vec4 = reinterpret_cast<const D3DXVECTOR4*>(
460                &ParamBlk.m_ColorAlphaVal);
461        S3D_DRV_D3D9_CHECK(
462                m_ProgCtx->m_Env, ConstTab->SetVector(D3dDev, Var, Vec4));
463    }
464   
465    Var = TrackBlk.m_ActiveLightCntVar;
466    if(Var)
467    {
468        S3D_DRV_D3D9_CHECK(
469                m_ProgCtx->m_Env, ConstTab->SetInt(
470                    D3dDev, Var, 0));
471    }
472
473    s3d_CSysIntps FromLight = 0;
474    TrackLightingBlack(ParamBlk, ParamBlkState, TrackBlk, FromLight);
475}
476
477void s3d_CDrvD3d9ProgHLSL::TrackLighting(
478        const s3d_CDrvD3d9ParamBlk &ParamBlk,
479        const s3d_CDrvD3d9ParamBlkState &ParamBlkState,
480        s3d_CDrvD3d9ProgHLSLTrackBlk &TrackBlk)
481{
482    LPDIRECT3DDEVICE9 D3dDev = m_ProgCtx->m_D3dDev;
483    LPD3DXCONSTANTTABLE ConstTab = TrackBlk.m_ConstTab;
484   
485    if(ParamBlkState.m_DirtyMask
486        & s3d_CDrvD3d9ParamBlkState::Dirty_Mtl)
487    {
488        D3DXHANDLE Var = TrackBlk.m_Mtl.m_EmissiveVar;
489        if(Var)
490        {
491            const D3DXVECTOR4 *Vec4 = reinterpret_cast<const D3DXVECTOR4*>(
492                    &ParamBlk.m_Mtl.Emissive);
493            S3D_DRV_D3D9_CHECK(
494                    m_ProgCtx->m_Env, ConstTab->SetVector(D3dDev, Var, Vec4));
495        }
496        Var = TrackBlk.m_Mtl.m_PowerVar;
497        if(Var)
498        {
499            D3DXVECTOR4 Vec4;
500            Vec4.x = ParamBlk.m_Mtl.Power;
501            Vec4.y = ParamBlk.m_Mtl.Power;
502            Vec4.z = ParamBlk.m_Mtl.Power;
503            Vec4.w = ParamBlk.m_Mtl.Power;
504            S3D_DRV_D3D9_CHECK(
505                    m_ProgCtx->m_Env, ConstTab->SetVector(D3dDev, Var, &Vec4));
506        }
507    }
508   
509    if(ParamBlkState.m_DirtyMask
510        & s3d_CDrvD3d9ParamBlkState::Dirty_Light)
511    {
512        const s3d_CDrvD3d9ProgHLSLLightArray *LightTrackArray
513                = &TrackBlk.m_LightTrackArray;
514        s3d_CSysIntps MaxProgLightCnt = LightTrackArray->GetCnt();
515
516        s3d_CSysIntps nLightCnt = ParamBlk.m_CurLightCnt;
517        const D3DLIGHT9 *Light = ParamBlk.m_LightArray;
518
519        if(nLightCnt > MaxProgLightCnt)
520            nLightCnt = MaxProgLightCnt;
521
522        const s3d_CDrvD3d9ProgHLSLLight *ProgLight
523                = LightTrackArray->GetPtrRaw();
524        s3d_CSysIntps iLight;
525        for(iLight = 0; iLight < nLightCnt; iLight++)
526        {
527            D3DXHANDLE Var = ProgLight->m_AmbientVar;
528            if(Var)
529            {
530                const D3DXVECTOR4 *Vec4
531                        = reinterpret_cast<const D3DXVECTOR4 *>(
532                                &Light->Ambient);
533                S3D_DRV_D3D9_CHECK(
534                        m_ProgCtx->m_Env, ConstTab->SetVector(
535                                D3dDev, Var, Vec4));
536            }
537            Var = ProgLight->m_DiffuseVar;
538            if(Var)
539            {
540                const D3DXVECTOR4 *Vec4
541                        = reinterpret_cast<const D3DXVECTOR4 *>(
542                                &Light->Diffuse);
543                S3D_DRV_D3D9_CHECK(
544                        m_ProgCtx->m_Env, ConstTab->SetVector(
545                                D3dDev, Var, Vec4));
546            }
547            Var = ProgLight->m_SpecularVar;
548            if(Var)
549            {
550                const D3DXVECTOR4 *Vec4
551                        = reinterpret_cast<const D3DXVECTOR4 *>(
552                                &Light->Specular);
553                S3D_DRV_D3D9_CHECK(
554                        m_ProgCtx->m_Env, ConstTab->SetVector(
555                                D3dDev, Var, Vec4));
556            }
557            Var = ProgLight->m_PosVar;
558            if(Var)
559            {
560                const D3DXVECTOR4 *Vec4
561                        = reinterpret_cast<const D3DXVECTOR4 *>(
562                                &Light->Position);
563                S3D_DRV_D3D9_CHECK(
564                        m_ProgCtx->m_Env, ConstTab->SetVector(
565                                D3dDev, Var, Vec4));
566            }
567            Var = ProgLight->m_DirVar;
568            if(Var)
569            {
570                const D3DXVECTOR4 *Vec4
571                        = reinterpret_cast<const D3DXVECTOR4 *>(
572                                &Light->Direction);
573                S3D_DRV_D3D9_CHECK(
574                        m_ProgCtx->m_Env, ConstTab->SetVector(
575                                D3dDev, Var, Vec4));
576            }
577            Var = ProgLight->m_AttenVar;
578            if(Var)
579            {
580                float Atten[4];
581                Atten[0] = Light->Attenuation0; //AttenConst
582                Atten[1] = Light->Attenuation1; //AttenLinear
583                Atten[2] = Light->Attenuation2; //AttenQuadr
584                Atten[3] = Light->Range;
585                S3D_DRV_D3D9_CHECK(
586                        m_ProgCtx->m_Env, ConstTab->SetFloatArray(
587                            D3dDev, Var, Atten, 4));
588            }
589            Light++;
590            ProgLight++;
591        }
592       
593        D3DXHANDLE Var = TrackBlk.m_ActiveLightCntVar;
594        if(Var)
595        {
596            S3D_DRV_D3D9_CHECK(
597                    m_ProgCtx->m_Env, ConstTab->SetInt(
598                        D3dDev, Var, INT(nLightCnt)));
599        }
600       
601        if(nLightCnt < MaxProgLightCnt)
602        {
603            TrackLightingBlack(
604                    ParamBlk, ParamBlkState, TrackBlk, nLightCnt);
605        }
606    }
607}
608
609void s3d_CDrvD3d9ProgHLSL::TrackLightingBlack(
610        const s3d_CDrvD3d9ParamBlk &ParamBlk,
611        const s3d_CDrvD3d9ParamBlkState &ParamBlkState,
612        s3d_CDrvD3d9ProgHLSLTrackBlk &TrackBlk,
613        s3d_CSysIntps FromLight)
614{
615    LPDIRECT3DDEVICE9 D3dDev = m_ProgCtx->m_D3dDev;
616    LPD3DXCONSTANTTABLE ConstTab = TrackBlk.m_ConstTab;
617
618    const s3d_CDrvD3d9ProgHLSLLightArray *LightArray
619            = &TrackBlk.m_LightTrackArray;
620    s3d_CSysIntps nLightCnt = LightArray->GetCnt();
621    s3d_CSysIntps iLight;
622    for(iLight = FromLight; iLight < nLightCnt; iLight++)
623    {
624        const s3d_CDrvD3d9ProgHLSLLight *ProgLight
625                = &LightArray->RefAtRaw(iLight);
626        const D3DXVECTOR4 Vec4(0, 0, 0, 0);
627        D3DXHANDLE Var = ProgLight->m_AmbientVar;
628        if(Var)
629        {
630            S3D_DRV_D3D9_CHECK(
631                    m_ProgCtx->m_Env, ConstTab->SetVector(
632                        D3dDev, Var, &Vec4));
633        }
634        Var = ProgLight->m_DiffuseVar;
635        if(Var)
636        {
637            S3D_DRV_D3D9_CHECK(
638                    m_ProgCtx->m_Env, ConstTab->SetVector(
639                        D3dDev, Var, &Vec4));
640        }
641        Var = ProgLight->m_SpecularVar;
642        if(Var)
643        {
644            S3D_DRV_D3D9_CHECK(
645                    m_ProgCtx->m_Env, ConstTab->SetVector(
646                        D3dDev, Var, &Vec4));
647        }
648        Var = ProgLight->m_PosVar;
649        if(Var)
650        {
651            S3D_DRV_D3D9_CHECK(
652                    m_ProgCtx->m_Env, ConstTab->SetVector(
653                        D3dDev, Var, &Vec4));
654        }
655        Var = ProgLight->m_DirVar;
656        if(Var)
657        {
658            S3D_DRV_D3D9_CHECK(
659                    m_ProgCtx->m_Env, ConstTab->SetVector(
660                        D3dDev, Var, &Vec4));
661        }
662        Var = ProgLight->m_AttenVar;
663        if(Var)
664        {
665            S3D_DRV_D3D9_CHECK(
666                    m_ProgCtx->m_Env, ConstTab->SetVector(
667                        D3dDev, Var, &Vec4));
668        }
669    }
670}
671
672void s3d_CDrvD3d9ProgHLSL::TrackTransfBone(
673        s3d_CSysIntps BoneIdxCnt, const s3d_CSysInt32u *BoneIdxData,
674        s3d_CSysIntps MatBoneCnt, const D3DXMATRIXA16 *MatBoneArray,
675        s3d_CDrvD3d9ProgHLSLTrackBlk &TrackBlk)
676{
677    if(!BoneIdxData)
678        return;
679    if(!MatBoneArray)
680        return;
681
682    LPDIRECT3DDEVICE9 D3dDev = m_ProgCtx->m_D3dDev;
683    LPD3DXCONSTANTTABLE ConstTab = TrackBlk.m_ConstTab;
684    if(!ConstTab)
685        return;
686
687    const s3d_CSysChar *Info = TrackBlk.m_CodeInfo.GetChars();
688
689    const s3d_CDrvD3d9ProgHLSLTrackMatArray *TrackMatArray
690            = &TrackBlk.m_BoneTrackArray;
691
692    LPD3DXMATRIXA16 BoneMatData
693            = reinterpret_cast<LPD3DXMATRIXA16>(
694                alloca(S3D_SYS_SIZEOFS(D3DXMATRIXA16) * BoneIdxCnt));
695    s3d_CSysIntps iBoneIdx;
696    for(iBoneIdx = 0; iBoneIdx < BoneIdxCnt; iBoneIdx++)
697    {
698        s3d_CSysIntps MatBoneIdx = BoneIdxData[iBoneIdx];
699        if(MatBoneIdx >= MatBoneCnt)
700            D3DXMatrixIdentity(&BoneMatData[iBoneIdx]);
701        else
702            BoneMatData[iBoneIdx] = MatBoneArray[MatBoneIdx];
703    }
704
705    const s3d_CDrvD3d9ProgHLSLTrackMat *TrackMat = TrackMatArray->GetPtrRaw();
706    s3d_CSysIntps nTrackMat = TrackMatArray->GetCnt();
707    s3d_CSysIntps iTrackMat;
708    for(iTrackMat = 0; iTrackMat < nTrackMat; iTrackMat++)
709    {
710        D3DXHANDLE Var = TrackMat->m_Var;
711        if(!Var)
712            continue;
713
714        int Trans = TrackMat->m_Trans;
715        switch(TrackMat->m_Chan)
716        {
717            case s3d_CDrvUtilGfxProg::TrackChan_Bone:
718            {
719                int TrackCnt = TrackMat->m_Cnt;
720                if(BoneIdxCnt < TrackCnt)
721                    TrackCnt = BoneIdxCnt;
722                TrackMatTrans(
723                        Var, Trans, BoneMatData, TrackCnt, ConstTab, D3dDev);
724                break;
725            }
726            default:
727            {
728                S3D_SYS_ASSERT(0);
729            }
730        }
731        TrackMat++;
732    }
733}
734
735///////////////////////////////////////////////////////////////////////////////
736
737void s3d_CDrvD3d9ProgHLSLUtil::CreateShader(
738        s3d_CUtilNotifGather *NotifGather, s3d_CUtilSnkChunk *Param,
739        s3d_CDrvD3d9ProgCtx *ProgCtx, bool VertShader, s3d_CDrvD3d9Prog *Prog,
740        s3d_CDrvD3d9ProgHLSLTrackBlk &TrackBlk)
741{
742    if(!ProgCtx)
743        return;
744
745    s3d_CUtilMsgHandler *MsgHandler = ProgCtx->m_MsgHandler;
746
747    s3d_CUtilSnkExtract SnkExtract;
748    SnkExtract.Assign(MsgHandler, Param);
749
750    s3d_CLibStreamPreproStatePtr PreproState
751            = S3D_SYS_NEW s3d_CLibStreamPreproState;
752    s3d_CDrvD3d9ProgHLSLUtil::ExtractPredefine(
753            ProgCtx, PreproState, SnkExtract);
754
755    /*@{ @declare{shaderprog.param}{<d3d9_hlsl_shader>.code_variant_array}
756            {$ [chunk]...[chunk]}
757        Each chunk specifies a D3D HLSL shader source code file for a
758        specific shader version.
759        If there is more than one @code{code_variant} the one that first
760        successfully compiles is taken.
761    @}*/
762    s3d_CUtilSnkChunkArray CodeArray;
763    s3d_CUtilStr CodeArrayInfo;
764    SnkExtract.ExtractChunkArray(
765            CodeArrayInfo, CodeArray, "code_variant_array", true);
766
767    s3d_CUtilStr CodeName, CodeInfo;
768    s3d_CSysIntps nCode = CodeArray.GetCnt();
769    s3d_CSysIntps iCode;
770    for(iCode = 0; iCode < nCode; iCode++)
771    {
772        s3d_CUtilSnkExtract CodeSnkExtract;
773        s3d_CUtilSnkChunk *CodeChunk = CodeArray.GetAt(iCode);
774        CodeSnkExtract.Assign(MsgHandler, CodeChunk);
775
776        /*@{ @declare{shaderprog.param}
777                {<d3d9_hlsl_shader>.code_variant_array.profile}{$ [str]}
778            Shader profile which should be used to compile shader program.
779            Use empty string for highest profile supported by gfx hardware.
780        @}*/
781        s3d_CUtilStr ReqVer = CodeSnkExtract.ExtractStr("profile", false);
782/*
783        if(!s3d_CDrvD3d9ProgUtil::IsVersAllowed(MaxMajor, MaxMinor, ReqVer))
784            continue;
785*/
786        /*@{ @declare{shaderprog.param}
787                {<d3d9_hlsl_shader>.code_variant_array.code}{$ [str]}
788            Specifies the D3D HLSL shader source code file.
789        @}*/
790        CodeSnkExtract.ExtractStr(CodeInfo, CodeName, "code", true);
791
792        /*@{ @declare{shaderprog.param}
793                {<d3d9_hlsl_shader>.code_variant_array.debug_code_file}
794                {$ [str]}
795            Specifies the shader source file that is used for debugging.
796        @}*/
797        s3d_CUtilStr DbgCodeName
798                = CodeSnkExtract.ExtractStr("debug_code_file", false);
799
800        /*@{ @declare{shaderprog.param}
801                {<d3d9_hlsl_shader>.code_variant_array.entry_point}
802                {$ [str]}
803            Function name which is executed,
804            usually something like main_vs_2x0 or main_fs_2x0.
805        @}*/
806        s3d_CUtilStr EntryPoint
807                = CodeSnkExtract.ExtractStr("entry_point", true);
808
809        s3d_CUtilStr Profile;
810        if(VertShader)
811        {
812            if(ReqVer.IsEmpty())
813                Profile = D3DXGetVertexShaderProfile(ProgCtx->m_D3dDev);
814            else
815                Profile = s3d_CDrvD3d9ProgUtil::GenProfileString(ReqVer, "vs");
816        }
817        else
818        {
819            if(ReqVer.IsEmpty())
820                Profile = D3DXGetPixelShaderProfile(ProgCtx->m_D3dDev);
821            else
822                Profile = s3d_CDrvD3d9ProgUtil::GenProfileString(ReqVer, "ps");
823        }
824
825        CodeSnkExtract.CheckForUnknown();
826
827        s3d_CDrvD3d9Buf CodeBuf;
828        if(ProgCtx->m_D3dParam->m_ShaderDebug && !DbgCodeName.IsEmpty())
829        {
830            s3d_CDrvD3d9ProgHLSLUtil::CompileFromFile(
831                    NotifGather, ProgCtx,
832                    CodeInfo, DbgCodeName, EntryPoint, Profile,
833                    PreproState, CodeBuf, TrackBlk.m_ConstTab);
834        }
835        else
836        {
837            s3d_CDrvD3d9ProgHLSLUtil::CompileFromRes(
838                    NotifGather, ProgCtx,
839                    CodeInfo, CodeName, EntryPoint, Profile,
840                    PreproState, CodeBuf, TrackBlk.m_ConstTab);
841        }
842        if(!CodeBuf)
843            continue;
844
845        const DWORD *Function
846                = reinterpret_cast<const DWORD *>(
847                    CodeBuf->GetBufferPointer());
848        DWORD ShaderVers = D3DXGetShaderVersion(Function);
849
850        HRESULT Result = D3DERR_INVALIDCALL;
851        LPDIRECT3DDEVICE9 D3dDev = ProgCtx->m_D3dDev;
852        if(VertShader)
853        {
854            if(ShaderVers <= ProgCtx->m_MaxVS)
855            {
856                S3D_DRV_D3D9_CALLCHECK(
857                        ProgCtx->m_Env, Result, D3dDev->CreateVertexShader(
858                            Function, &Prog->m_VertShader.EmptyRef()));
859            }
860            else
861            {
862                s3d_CUtilMsg m;
863                m.m_Code = "drv/imp/directx/d3d9/drv_d3d9_proghlsl.vsvers";
864                m.m_StdTempl = "D3D: "
865                        "HLSL program '[1]' requires GPU with vertex shader "
866                        "version '[2]' but GPU has only '[3]'.";
867                m.AddInfo(CodeInfo);
868                m.AddInfo(CodeName);
869                m.AddInfo(s3d_CDrvD3d9ProgUtil::StrOfVers(ShaderVers));
870                m.AddInfo(s3d_CDrvD3d9ProgUtil::StrOfVers(ProgCtx->m_MaxVS));
871                s3d_UtilMsgReportNote(ProgCtx->m_MsgHandler, m);
872            }
873        }
874        else
875        {
876            if(ShaderVers <= ProgCtx->m_MaxPS)
877            {
878                S3D_DRV_D3D9_CALLCHECK(
879                        ProgCtx->m_Env, Result, D3dDev->CreatePixelShader(
880                            Function, &Prog->m_PixShader.EmptyRef()));
881            }
882            else
883            {
884                s3d_CUtilMsg m;
885                m.m_Code = "drv/imp/directx/d3d9/drv_d3d9_proghlsl.psvers";
886                m.m_StdTempl = "D3D: "
887                        "HLSL program '[1]' requires GPU with pixel shader "
888                        "version '[2]' but GPU has only '[3]'.";
889                m.AddInfo(CodeInfo);
890                m.AddInfo(CodeName);
891                m.AddInfo(s3d_CDrvD3d9ProgUtil::StrOfVers(ShaderVers));
892                m.AddInfo(s3d_CDrvD3d9ProgUtil::StrOfVers(ProgCtx->m_MaxPS));
893                s3d_UtilMsgReportNote(ProgCtx->m_MsgHandler, m);
894            }
895        }
896
897        if(FAILED(Result))
898        {
899            TrackBlk.m_ConstTab.Reset();
900            continue;
901        }
902
903        if(VertShader)
904        {
905            s3d_CDrvD3d9ProgUtil::GetProgDecl(
906                    ProgCtx, Prog->m_VertProgDecl,
907                    CodeBuf->GetBufferSize(), Function);
908           
909            s3d_CDrvD3d9ProgUtil::ExtractComprFmt(
910                    ProgCtx, CodeInfo, CodeName, Prog, SnkExtract);
911        }
912
913        s3d_CDrvD3d9ProgHLSLUtil::InitTrackBlk(
914                    ProgCtx, CodeInfo, CodeName, TrackBlk, SnkExtract);
915
916        SnkExtract.CheckForUnknown();
917       
918        break;
919    }
920}
921
922void s3d_CDrvD3d9ProgHLSLUtil::ExtractPredefine(
923        const s3d_CDrvD3d9ProgCtx *ProgCtx,
924        s3d_CLibStreamPreproState *PreproState,
925        s3d_CUtilSnkExtract &SnkExtract)
926{
927    /*@{ @declare{shaderprog.param}
928            {<d3d9_hlsl_shader>.predefine_array}{$ [chunk]...[chunk]}
929        Array of chunks defining macros used at compile time.
930        @listing
931        {
932            @sident{shaderprog}{<d3d9_hlsl_shader>.predefine_array}
933            {
934                @sident{shaderprog}{<d3d9_hlsl_shader>.predefine_array@$
935                            .name} "S3D_FEATURE_MF"
936            }
937            {
938                @sident{shaderprog}{<d3d9_hlsl_shader>.predefine_array@$
939                            .name} "S3D_FEATURE_MF_CNT"
940                @sident{shaderprog}{<d3d9_hlsl_shader>.predefine_array@$
941                            .val} "5"
942            }
943        }
944    @}*/
945    s3d_CUtilSnkChunkArray ChunkArray;
946    SnkExtract.ExtractChunkArray(ChunkArray, "predefine_array", false);
947    int i;
948    for(i = 0; i < ChunkArray.GetCntInt(); i++)
949    {
950        s3d_CUtilSnkExtract SnkExtract;
951        s3d_CUtilSnkChunk *Chunk = ChunkArray.GetAt(i);
952        SnkExtract.Assign(ProgCtx->m_MsgHandler, Chunk);
953
954        /*@{ @declare{shaderprog.param}
955                {<d3d9_hlsl_shader>.predefine_array.name}{$ [str]}
956            Name of macro.
957        @}*/
958        s3d_CUtilStr Name, NameInfo;
959        SnkExtract.ExtractStr(NameInfo, Name, "name", true);
960
961        /*@{ @declare{shaderprog.param}
962                {<d3d9_hlsl_shader>.predefine_array.val}{$ [str]}
963            Value of macro.
964        @}*/
965        s3d_CUtilStr Def = SnkExtract.ExtractStr("val", false);
966
967        PreproState->DefineSimple(ProgCtx->m_MsgHandler, NameInfo, Name, Def);
968        SnkExtract.CheckForUnknown();
969    }
970}
971
972void s3d_CDrvD3d9ProgHLSLUtil::ExtractParamArray(
973        const s3d_CDrvD3d9ProgCtx *ProgCtx,
974        s3d_CUtilStr_cr CodeInfo, s3d_CUtilStr_cr CodeName,
975        const LPD3DXCONSTANTTABLE ConstTab,
976        s3d_CDrvD3d9ProgHLSLParamArray &ParamArray,
977        s3d_CDrvD3d9ProgHLSLVarSet &VarSet,
978        s3d_CUtilSnkExtract &SnkExtract)
979{
980    ParamArray.Reset();
981
982    /*@{ @declare{shaderprog.param}
983            {<d3d9_hlsl_shader>.param_array}{$ [chunk]...[chunk]}
984        Each entry maps @ident{comp}{<shaderprog.map_prog_array>.dest_progvar}
985        to shader code variable.
986        See also @ident{comp}{<shaderprog.map_prog_array>}.
987        @listing
988        {
989            @sident{shaderprog}{<d3d9_hlsl_shader>.param_array}
990            {
991                @sident{shaderprog}{<d3d9_hlsl_shader>.param_array@$
992                            .src_progvar} "prog_cenrange"
993                @sident{shaderprog}{<d3d9_hlsl_shader>.param_array@$
994                            .dest_codevar} "lightCenRange"
995                @sident{shaderprog}{<d3d9_hlsl_shader>.param_array@$
996                            .type} "float4"
997            }
998        }
999    @}*/
1000    s3d_CUtilSnkChunkArray ParamChunkArray;
1001    SnkExtract.ExtractChunkArray(ParamChunkArray, "param_array", false);
1002    s3d_CSysIntps nParamChunk = ParamChunkArray.GetCnt();
1003    s3d_CSysIntps iParamChunk;
1004    for(iParamChunk = 0; iParamChunk < nParamChunk; iParamChunk++)
1005    {
1006        s3d_CUtilSnkExtract SnkExtract;
1007        SnkExtract.Assign(ProgCtx->m_MsgHandler, ParamChunkArray[iParamChunk]);
1008
1009        s3d_CUtilStr ParamInfo;
1010        s3d_CUtilAtomPtr ParamAtom;
1011
1012        /*@{ @declare{shaderprog.param}
1013                {<d3d9_hlsl_shader>.param_array.src_progvar}{$ [str]}
1014            Shader source variable.
1015            See @ident{comp}{<shaderprog.map_prog_array>.dest_progvar}.
1016        @}*/
1017        s3d_CUtilSnkExtractUtil::ExtractAtom(
1018                ParamInfo, ParamAtom, ProgCtx->m_AtomMgr,
1019                SnkExtract, "src_progvar", true);
1020
1021        /*@{ @declare{shaderprog.param}
1022                {<d3d9_hlsl_shader>.param_array.dest_codevar}{$ [str]}
1023            Shader code destination variable.
1024        @}*/
1025        s3d_CUtilStr ParamDestVar
1026            = SnkExtract.ExtractStr("dest_codevar", true);
1027
1028        /*@{ @declare{shaderprog.param}
1029                {<d3d9_hlsl_shader>.param_array.type}{$ [str]}
1030            Type of shader code variable. Can be one of @code{float4},
1031            @code{float4x4[_transp|_inv|_invtransp]}.
1032        @}*/
1033        s3d_CUtilStr TypeStr;
1034        s3d_CUtilStr TypeInfo;
1035        SnkExtract.ExtractStr(TypeInfo, TypeStr, "type", true);
1036        s3d_CUtilSnkExtractEnum SnkExtractEnum;
1037        SnkExtractEnum.Assign(ProgCtx->m_MsgHandler, TypeInfo, TypeStr);
1038        int Type = -1;
1039        if(SnkExtractEnum.Check("float4"))
1040            Type = s3d_CDrvUtilGfxProg::ParamType_Float4;
1041        else if(SnkExtractEnum.Check("float4x4"))
1042            Type = s3d_CDrvUtilGfxProg::ParamType_Float4x4;
1043        else if(SnkExtractEnum.Check("float4x4_transp"))
1044            Type = s3d_CDrvUtilGfxProg::ParamType_Float4x4_Transp;
1045        else if(SnkExtractEnum.Check("float4x4_inv"))
1046            Type = s3d_CDrvUtilGfxProg::ParamType_Float4x4_Inv;
1047        else if(SnkExtractEnum.Check("float4x4_invtransp"))
1048            Type = s3d_CDrvUtilGfxProg::ParamType_Float4x4_InvTransp;
1049        else
1050            SnkExtractEnum.ErrorUnknown();
1051
1052        SnkExtract.CheckForUnknown();
1053
1054        s3d_CDrvD3d9ProgHLSLParam Param;
1055        Param.m_Info = ParamInfo;
1056        S3D_DRV_D3D9_RESOLVEVAR(Param.m_Var, ParamInfo, ParamDestVar);
1057        Param.m_Type = Type;
1058        ParamArray.InsertBack(
1059                s3d_CDrvD3d9ProgHLSLParamEntry(ParamAtom, Param));
1060    }
1061
1062    s3d_UtilArraySortDefault(ParamArray);
1063   
1064    ParamArray.Compactify();
1065}
1066
1067void s3d_CDrvD3d9ProgHLSLUtil::ExtractTexSize(
1068        const s3d_CDrvD3d9ProgCtx *ProgCtx,
1069        s3d_CUtilStr_cr CodeInfo, s3d_CUtilStr_cr CodeName,
1070        const LPD3DXCONSTANTTABLE ConstTab,
1071        s3d_CDrvD3d9ProgHLSLVarArray &TexSizeArray,
1072        s3d_CDrvD3d9ProgHLSLVarArray &TexRcpSizeArray,
1073        s3d_CDrvD3d9ProgHLSLVarSet &VarSet,
1074        s3d_CUtilSnkExtract &SnkExtract)
1075{
1076    /*@{ @declare{shaderprog.param}
1077            {<d3d9_hlsl_shader>.tex_size_codevar_array}{$ [str]...[str]}
1078        Array of shader code variables to upload texture dimensions to.
1079        @table
1080        {
1081            { @code{texsize_codevar.x} } { Width }
1082        }                                                   
1083        {
1084            { @code{texsize_codevar.y} } { Height }
1085        }                                                   
1086        {
1087            { @code{texsize_codevar.z} } { Depth }
1088        }
1089        {
1090            { @code{texsize_codevar.w} } { <undefined> }
1091        }
1092        For example:
1093        @listing
1094        {
1095            @sident{shaderprog}{<d3d9_hlsl_shader>@$
1096                .tex_size_codevar_array} "tex00_size" "" "tex02_size"
1097        }
1098        Uploads size of texture currently bound to sampler 0 and 2, @it{""}
1099        disables upload of texture bound to sampler 1.
1100
1101    @}*/
1102    s3d_CUtilStrArray TexSizeStrArray;
1103    s3d_CUtilStr TexSizeInfo;
1104    SnkExtract.ExtractStrArray(
1105            TexSizeInfo, TexSizeStrArray, "tex_size_codevar_array", false);
1106
1107    /*@{ @declare{shaderprog.param}
1108            {<d3d9_hlsl_shader>.tex_rcpsize_codevar_array}{$ [str]...[str]}
1109        Array of shader code variables to upload reciprocal texture
1110        dimensions to.
1111       
1112        See also
1113            @ident{shaderprog}{<d3d9_hlsl_shader>.tex_size_codevar_array}.
1114        @table
1115        {
1116            { @code{texrcpsize_codevar.x} } { 1 / Width }
1117        }                                                   
1118        {
1119            { @code{texrcpsize_codevar.y} } { 1 / Height }
1120        }                                                   
1121        {
1122            { @code{texrcpsize_codevar.z} } { 1 / Depth }
1123        }
1124        {
1125            { @code{texrcpsize_codevar.w} } { <undefined> }
1126        }
1127    @}*/
1128    s3d_CUtilStrArray TexRcpStrSizeArray;
1129    s3d_CUtilStr TexRcpSizeInfo;
1130    SnkExtract.ExtractStrArray(
1131            TexRcpSizeInfo, TexRcpStrSizeArray,
1132            "tex_rcpsize_codevar_array", false);
1133
1134    TexSizeArray.Reset();
1135    s3d_CSysIntps nTexSize = TexSizeStrArray.GetCnt();
1136    if(nTexSize >= ProgCtx->m_MaxSampCnt)
1137    {
1138        s3d_CDrvDxError e;
1139        e.m_Code =
1140                "drv/imp/directx/d3d9/drv_d3d9_proghlsl.invalid_tex_size_cnt.";
1141        e.m_StdTempl = "Too many HLSL tex_size_codevar_array entries '[1]'."
1142                " Must be less than or equal to [2].";
1143        e.AddInfo(TexSizeInfo);
1144        e.AddInfo(s3d_CUtilStrUtil::StrOfInt(nTexSize));
1145        e.AddInfo(s3d_CUtilStrUtil::StrOfInt(ProgCtx->m_MaxSampCnt));
1146        s3d_UtilMsgReportError(ProgCtx->m_MsgHandler, e);
1147    }
1148    int iTexSize;
1149    for(iTexSize = 0; iTexSize < nTexSize; iTexSize++)
1150    {
1151        s3d_CUtilStr VarName = TexSizeStrArray.GetAt(iTexSize);
1152        D3DXHANDLE TexSizeVar = 0;
1153        S3D_DRV_D3D9_RESOLVEVAR(TexSizeVar, TexSizeInfo, VarName);
1154        TexSizeArray.InsertBack(TexSizeVar);
1155    }
1156
1157    TexRcpSizeArray.Reset();
1158    s3d_CSysIntps nRcpTexSize = TexRcpStrSizeArray.GetCnt();
1159    if(nRcpTexSize >= ProgCtx->m_MaxSampCnt)
1160    {
1161        s3d_CDrvDxError e;
1162        e.m_Code = "drv/imp/directx/d3d9/drv_d3d9_proghlsl"
1163                ".invalid_tex_rcpsize_cnt.";
1164        e.m_StdTempl = "Too many HLSL tex_rcpsize_codevar_array entries '[1]'."
1165                " Must be less than or equal to [2].";
1166        e.AddInfo(TexSizeInfo);
1167        e.AddInfo(s3d_CUtilStrUtil::StrOfInt(nRcpTexSize));
1168        e.AddInfo(s3d_CUtilStrUtil::StrOfInt(ProgCtx->m_MaxSampCnt));
1169        s3d_UtilMsgReportError(ProgCtx->m_MsgHandler, e);
1170    }
1171    int iRcpTexSize;
1172    for(iRcpTexSize = 0; iRcpTexSize < nRcpTexSize; iRcpTexSize++)
1173    {
1174        s3d_CUtilStr VarName = TexRcpStrSizeArray.GetAt(iRcpTexSize);
1175        D3DXHANDLE TexRcpSizeVar = 0;
1176        S3D_DRV_D3D9_RESOLVEVAR(TexRcpSizeVar, TexRcpSizeInfo, VarName);
1177        TexRcpSizeArray.InsertBack(TexRcpSizeVar);
1178    }
1179   
1180    TexSizeArray.Compactify();
1181    TexRcpSizeArray.Compactify();
1182}
1183
1184void s3d_CDrvD3d9ProgHLSLUtil::ExtractTrackArray(
1185        const s3d_CDrvD3d9ProgCtx *ProgCtx,
1186        s3d_CUtilStr_cr CodeInfo, s3d_CUtilStr_cr CodeName,
1187        const LPD3DXCONSTANTTABLE ConstTab,
1188        s3d_CDrvD3d9ProgHLSLTrackMatArray &MatTrackArray,
1189        s3d_CDrvD3d9ProgHLSLTrackMatArray &BoneTrackArray,
1190        s3d_CDrvD3d9ProgHLSLVarSet &VarSet,
1191        s3d_CUtilSnkExtract &SnkExtract)
1192{
1193    /*@{ @declare{shaderprog.param}
1194            {<d3d9_hlsl_shader>.tracking}{$ [chunk]...[chunk]}
1195        Track matrices to shader code variables.
1196        @listing
1197        {
1198            @sident{shaderprog}{<d3d9_hlsl_shader>.tracking}
1199            {
1200                @sident{shaderprog}{<d3d9_hlsl_shader>.tracking@$
1201                    .codevar} "matProj"
1202                @sident{shaderprog}{<d3d9_hlsl_shader>.tracking@$
1203                    .slot} 0
1204                @sident{shaderprog}{<d3d9_hlsl_shader>.tracking@$
1205                    .chan} "proj"
1206                @sident{shaderprog}{<d3d9_hlsl_shader>.tracking@$
1207                    .trans} "identity"
1208            }
1209        }
1210    @}*/
1211    s3d_CUtilSnkChunkArray TrackArray;
1212    s3d_CUtilStr TrackInfo;
1213    SnkExtract.ExtractChunkArray(
1214            TrackInfo, TrackArray, "tracking", false);
1215
1216    MatTrackArray.Reset();
1217    BoneTrackArray.Reset();
1218
1219    int iTrack;
1220    for(iTrack = 0; iTrack < TrackArray.GetCnt(); iTrack++)
1221    {
1222        s3d_CUtilSnkChunk *TrackChunk = TrackArray.GetAt(iTrack);
1223        s3d_CUtilSnkExtractEnum SnkExtractEnum;
1224        s3d_CUtilSnkExtract SnkExtract;
1225        SnkExtract.Assign(ProgCtx->m_MsgHandler, TrackChunk);
1226
1227        s3d_CDrvD3d9ProgHLSLTrackMat Track;
1228
1229        /*@{ @declare{shaderprog.param}
1230                {<d3d9_hlsl_shader>.tracking.chan}{$ [str]}
1231            chan can be one of:
1232            @table
1233            {
1234                { [ identity | proj | view | projview | tex | bone ] }
1235            }
1236        @}*/
1237        s3d_CUtilStr ChanName, ChanInfo;
1238        SnkExtract.ExtractStr(ChanInfo, ChanName, "chan", true, "");
1239        SnkExtractEnum.Assign(ProgCtx->m_MsgHandler, ChanInfo, ChanName);
1240        Track.m_Chan = s3d_CDrvUtilGfxProg::TrackChan_Identity;
1241        if(SnkExtractEnum.Check("view"))
1242            Track.m_Chan = s3d_CDrvUtilGfxProg::TrackChan_View;
1243        else if(SnkExtractEnum.Check("proj"))
1244            Track.m_Chan = s3d_CDrvUtilGfxProg::TrackChan_Proj;
1245        else if(SnkExtractEnum.Check("projview"))
1246            Track.m_Chan = s3d_CDrvUtilGfxProg::TrackChan_ProjView;
1247        else if(SnkExtractEnum.Check("identity"))
1248            Track.m_Chan = s3d_CDrvUtilGfxProg::TrackChan_Identity;
1249        else if(SnkExtractEnum.Check("attr"))
1250            Track.m_Chan = s3d_CDrvUtilGfxProg::TrackChan_Attr;
1251        else if(SnkExtractEnum.Check("bone"))
1252            Track.m_Chan = s3d_CDrvUtilGfxProg::TrackChan_Bone;
1253        else
1254            SnkExtractEnum.ErrorUnknown();
1255
1256        /*@{ @declare{shaderprog.param}
1257            {<d3d9_hlsl_shader>.tracking.slot}{$ [int]}
1258            Used for selecting texture matrix for the texture that is bound to
1259            sampler @it{slot}. Has no effect on matrices other than texture or
1260            bone. Default is 0.
1261        @}*/
1262        s3d_CUtilStr TrackSlotInfo;
1263        SnkExtract.ExtractInt(TrackSlotInfo, Track.m_Slot, "slot", false, 0);
1264        if(Track.m_Slot < 0 || Track.m_Slot >= ProgCtx->m_MaxAttrCnt)
1265        {
1266            s3d_CDrvDxError e;
1267            e.m_Code = "drv/imp/directx/d3d9/drv_d3d9_proghlsl.invalid_slot.";
1268            e.m_StdTempl = "Invalid HLSL tracking slot value '[1]'. "
1269                "Must be greater or equal 0 and less than [2].";
1270            e.AddInfo(TrackSlotInfo);
1271            e.AddInfo(s3d_CUtilStrUtil::StrOfInt(Track.m_Slot));
1272            e.AddInfo(s3d_CUtilStrUtil::StrOfInt(ProgCtx->m_MaxAttrCnt));
1273            s3d_UtilMsgReportError(ProgCtx->m_MsgHandler, e);
1274           
1275            Track.m_Slot = 0;
1276        }
1277
1278        /*@{ @declare{shaderprog.param}
1279                {<d3d9_hlsl_shader>.tracking.trans}{$ [str]}
1280            trans can be one of:
1281            @table
1282            {
1283                { [ identity | inv | transp | invtransp ] }
1284            }
1285        @}*/
1286        s3d_CUtilStr TransName, TransInfo;
1287        SnkExtract.ExtractStr(TransInfo, TransName, "trans", true, "");
1288
1289        SnkExtractEnum.Assign(
1290                ProgCtx->m_MsgHandler, TransInfo, TransName);
1291        if(SnkExtractEnum.Check("identity"))
1292            Track.m_Trans = s3d_CDrvUtilGfxProg::TrackTrans_Identity;
1293        else if(SnkExtractEnum.Check("inv"))
1294            Track.m_Trans = s3d_CDrvUtilGfxProg::TrackTrans_Inv;
1295        else if(SnkExtractEnum.Check("transp"))
1296            Track.m_Trans = s3d_CDrvUtilGfxProg::TrackTrans_Transp;
1297        else if(SnkExtractEnum.Check("invtransp"))
1298            Track.m_Trans = s3d_CDrvUtilGfxProg::TrackTrans_InvTransp;
1299        else
1300        {
1301            Track.m_Trans = s3d_CDrvUtilGfxProg::TrackTrans_Identity;
1302            SnkExtractEnum.ErrorUnknown();
1303        }
1304
1305        /*@{ @declare{shaderprog.param}
1306                {<d3d9_hlsl_shader>.tracking.codevar}{$ [str]}
1307            Shader code variable where matrix is uploaded to.
1308        @}*/
1309        s3d_CUtilStr VarName, VarInfo;
1310        SnkExtract.ExtractStr(VarInfo, VarName, "codevar", true);
1311        S3D_DRV_D3D9_RESOLVEVAR(Track.m_Var, VarInfo, VarName);
1312        if(Track.m_Var)
1313        {
1314            D3DXCONSTANT_DESC ConstDesc;
1315            s3d_SysMemset(&ConstDesc, 0, S3D_SYS_SIZEOFS(ConstDesc));
1316            UINT ConstDescCnt = 1;
1317            S3D_DRV_D3D9_CHECK(
1318                    ProgCtx->m_Env, ConstTab->GetConstantDesc(
1319                        Track.m_Var, &ConstDesc, &ConstDescCnt));
1320            Track.m_Cnt = s3d_SysMax(UINT(1), ConstDesc.Elements);
1321
1322            if(Track.m_Chan == s3d_CDrvUtilGfxProg::TrackChan_Bone)
1323                BoneTrackArray.InsertBack(Track);
1324            else
1325                MatTrackArray.InsertBack(Track);
1326        }
1327
1328        SnkExtract.CheckForUnknown();
1329    }
1330   
1331    MatTrackArray.Compactify();
1332    BoneTrackArray.Compactify();
1333}
1334
1335
1336void s3d_CDrvD3d9ProgHLSLUtil::ExtractLightArray(
1337        const s3d_CDrvD3d9ProgCtx *ProgCtx,
1338        s3d_CUtilStr_cr CodeInfo, s3d_CUtilStr_cr CodeName,
1339        const LPD3DXCONSTANTTABLE ConstTab,
1340        D3DXHANDLE &ActiveLightCntVar,
1341        s3d_CDrvD3d9ProgHLSLLightArray &LightTrackArray,
1342        s3d_CDrvD3d9ProgHLSLVarSet &VarSet,
1343        s3d_CUtilSnkExtract &SnkExtract)
1344{
1345    /*@{ @declare{shaderprog.param}
1346            {<d3d9_hlsl_shader>.light_array}{$ [chunk]...[chunk]}
1347        Specifies how many lights a shader can handle and the shader code
1348        variable names where to upload light values.
1349        Typical @ident{shaderprog}{<d3d9_hlsl_shader>.light_array} entry.
1350        @listing
1351        {
1352            @sident{shaderprog}{<d3d9_hlsl_shader>.light_array}
1353            {
1354                @sident{shaderprog}{<d3d9_hlsl_shader>.light_array@$
1355                    .cnt} 2
1356                @sident{shaderprog}{<d3d9_hlsl_shader>.light_array@$
1357                    .pos_codevar} "lightArray[$].pos"
1358                @sident{shaderprog}{<d3d9_hlsl_shader>.light_array@$
1359                    .dir_codevar} "lightArray[$].dir"
1360                @sident{shaderprog}{<d3d9_hlsl_shader>.light_array@$
1361                    .ambient_codevar} "lightArray[$].ambient"
1362                @sident{shaderprog}{<d3d9_hlsl_shader>.light_array@$
1363                    .diffuse_codevar} "lightArray[$].diffuse"
1364                @sident{shaderprog}{<d3d9_hlsl_shader>.light_array@$
1365                    .specular_codevar} "lightArray[$].specular"
1366                @sident{shaderprog}{<d3d9_hlsl_shader>.light_array@$
1367                    .atten_codevar} "lightArray[$].atten"
1368            }
1369        }
1370        This chunk e.g. will be 2 (cnt) times replicated. '$' is a placeholder,
1371        which is replaced in this case with index 0 and 1 so it can be used
1372        in the shader as lightArray[0].pos and lightArray[1].pos.
1373    @}*/
1374    s3d_CUtilSnkChunkPtr LightChunk;
1375    s3d_CUtilStr LightInfo;
1376    SnkExtract.ExtractChunk(
1377            LightInfo, LightChunk, "light_array", false);
1378
1379    /*@{ @declare{shaderprog.param}
1380            {<d3d9_hlsl_shader>.light_activecnt_codevar}{$ [str]}
1381          In D3D shader version >= 2.0. this var is used for uploading
1382          the currently active light count.
1383    @}*/
1384    s3d_CUtilStr VarName, VarInfo;
1385    SnkExtract.ExtractStr(VarInfo, VarName, "light_activecnt_codevar", false);
1386    ActiveLightCntVar = 0;
1387    if(!VarName.IsEmpty())
1388    {
1389        S3D_DRV_D3D9_RESOLVEVAR(ActiveLightCntVar, VarInfo, VarName);
1390    }
1391
1392    LightTrackArray.Reset();
1393    if(!LightChunk)
1394        return;
1395
1396    s3d_CUtilSnkExtract SnkLightExtract;
1397    SnkLightExtract.Assign(ProgCtx->m_MsgHandler, LightChunk);
1398
1399    /*@{ @declare{shaderprog.param}
1400            {<d3d9_hlsl_shader>.light_array.cnt}{$ [int]}
1401        Number of lights supported by this shader program.
1402    @}*/
1403    s3d_CUtilStr LightCntInfo;
1404    int LightCnt;
1405    SnkLightExtract.ExtractInt(LightCntInfo, LightCnt, "cnt", true, 0);
1406    if(LightCnt > ProgCtx->m_MaxLightCnt)
1407    {
1408        s3d_CDrvDxError e;
1409        e.m_Code = "drv/imp/directx/d3d9/drv_d3d9_proghlsl.invalid_lightcnt.";
1410        e.m_StdTempl = "Invalid HLSL tracking light count value '[1]'. "
1411            "Must be greater or equal 0 and less than [2].";
1412        e.AddInfo(LightCntInfo);
1413        e.AddInfo(s3d_CUtilStrUtil::StrOfInt(LightCnt));
1414        e.AddInfo(s3d_CUtilStrUtil::StrOfInt(ProgCtx->m_MaxLightCnt));
1415        s3d_UtilMsgReportError(ProgCtx->m_MsgHandler, e);
1416
1417        LightCnt = ProgCtx->m_MaxLightCnt;
1418    }
1419
1420    /*@{ @declare{shaderprog.param}
1421            {<d3d9_hlsl_shader>.light_array.pos_codevar}{$ [str]}
1422        Light position (in viewspace) shader code variable.
1423    @}*/
1424    s3d_CUtilStr Pos, PosInfo;
1425    SnkLightExtract.ExtractStr(PosInfo, Pos, "pos_codevar", true);
1426
1427    /*@{ @declare{shaderprog.param}
1428            {<d3d9_hlsl_shader>.light_array.dir_codevar}{$ [str]}
1429        Light direction (in viewspace) shader code variable.
1430    @}*/
1431    s3d_CUtilStr Dir, DirInfo;
1432    SnkLightExtract.ExtractStr(DirInfo, Dir, "dir_codevar", true);
1433
1434    /*@{ @declare{shaderprog.param}
1435            {<d3d9_hlsl_shader>.light_array.ambient_codevar}{$ [str]}
1436        Light ambient color shader code variable.
1437    @}*/
1438    s3d_CUtilStr Ambient, AmbientInfo;
1439    SnkLightExtract.ExtractStr(AmbientInfo, Ambient, "ambient_codevar", true);
1440
1441    /*@{ @declare{shaderprog.param}
1442            {<d3d9_hlsl_shader>.light_array.diffuse_codevar}{$ [str]}
1443        Light diffuse color shader code variable.
1444    @}*/
1445    s3d_CUtilStr Diffuse, DiffuseInfo;
1446    SnkLightExtract.ExtractStr(
1447                DiffuseInfo, Diffuse, "diffuse_codevar", true);
1448
1449    /*@{ @declare{shaderprog.param}
1450            {<d3d9_hlsl_shader>.light_array.specular_codevar}{$ [str]}
1451        Light specular color shader code variable.
1452    @}*/
1453    s3d_CUtilStr Specular, SpecularInfo;
1454    SnkLightExtract.ExtractStr(
1455                SpecularInfo, Specular, "specular_codevar", true);
1456
1457    /*@{ @declare{shaderprog.param}
1458            {<d3d9_hlsl_shader>.light_array.atten_codevar}{$ [str]}
1459        Light attenuation shader code variable.
1460        @table
1461        {
1462            { @code{atten_codevar.x} } { AttenConst }
1463        }
1464        {
1465            { @code{atten_codevar.y} } { AttenLinear }
1466        }
1467        {
1468            { @code{atten_codevar.z} } { AttenQuadr }
1469        }
1470        {
1471            { @code{atten_codevar.w} } { Range }
1472        }
1473    @}*/
1474    s3d_CUtilStr Atten, AttenInfo;
1475    SnkLightExtract.ExtractStr(
1476                AttenInfo, Atten, "atten_codevar", true);
1477
1478    SnkLightExtract.CheckForUnknown();
1479    s3d_CUtilStrBuf ParamName;
1480    s3d_CUtilStrBuf StrIdx;
1481    int iLightParam;
1482    for(iLightParam = 0; iLightParam < LightCnt; iLightParam++)
1483    {
1484        s3d_CDrvD3d9ProgHLSLLight Light;
1485        StrIdx.Clear();
1486        StrIdx.AppendInt(iLightParam);
1487
1488        ParamName.Assign(Pos);
1489        ParamName.Replace("$", StrIdx.GetChars());
1490        S3D_DRV_D3D9_RESOLVEVAR(Light.m_PosVar, PosInfo, ParamName);
1491
1492        ParamName.Assign(Dir);
1493        ParamName.Replace("$", StrIdx.GetChars());
1494        S3D_DRV_D3D9_RESOLVEVAR(Light.m_DirVar, DirInfo, ParamName);
1495
1496        ParamName.Assign(Ambient);
1497        ParamName.Replace("$", StrIdx.GetChars());
1498        S3D_DRV_D3D9_RESOLVEVAR(Light.m_AmbientVar, AmbientInfo, ParamName);
1499
1500        ParamName.Assign(Diffuse);
1501        ParamName.Replace("$", StrIdx.GetChars());
1502        S3D_DRV_D3D9_RESOLVEVAR(Light.m_DiffuseVar, DiffuseInfo, ParamName);
1503
1504        ParamName.Assign(Specular);
1505        ParamName.Replace("$", StrIdx.GetChars());
1506        S3D_DRV_D3D9_RESOLVEVAR(Light.m_SpecularVar, SpecularInfo, ParamName);
1507
1508        ParamName.Assign(Atten);
1509        ParamName.Replace("$", StrIdx.GetChars());
1510        S3D_DRV_D3D9_RESOLVEVAR(Light.m_AttenVar, AttenInfo, ParamName);
1511
1512        LightTrackArray.InsertBack(Light);
1513    }
1514
1515    LightTrackArray.Compactify();
1516}
1517
1518void s3d_CDrvD3d9ProgHLSLUtil::ExtractMtl(
1519        const s3d_CDrvD3d9ProgCtx *ProgCtx,
1520        s3d_CUtilStr_cr CodeInfo, s3d_CUtilStr_cr CodeName,
1521        const LPD3DXCONSTANTTABLE ConstTab,
1522        s3d_CDrvD3d9ProgHLSLTrackMtrl &Mtl,
1523        s3d_CDrvD3d9ProgHLSLVarSet &VarSet,
1524        s3d_CUtilSnkExtract &SnkExtract)
1525{
1526    /*@{ @declare{shaderprog.param}
1527            {<d3d9_hlsl_shader>.mtl}{$ [chunk]}
1528    @}*/
1529    s3d_CUtilSnkChunkPtr MtlChunk;
1530    MtlChunk = SnkExtract.ExtractChunk("mtl", false);
1531
1532    s3d_CUtilSnkExtract MtrlSnkExtract;
1533    MtrlSnkExtract.Assign(ProgCtx->m_MsgHandler, MtlChunk);
1534
1535    /*@{ @declare{shaderprog.param}
1536            {<d3d9_hlsl_shader>.mtl.power_codevar}{$ [str]}
1537        Mtl power variable.
1538        @table
1539        {
1540            { @code{power_codevar.x} } { MtlPower }
1541        }
1542        {
1543            { @code{power_codevar.y} } { MtlPower }
1544        }
1545        {
1546            { @code{power_codevar.z} } { MtlPower }
1547        }
1548        {
1549            { @code{power_codevar.w} } { MtlPower }
1550        }
1551    @}*/
1552    s3d_CUtilStr VarName, VarInfo;
1553    MtrlSnkExtract.ExtractStr(VarInfo, VarName, "power_codevar", false);
1554    D3DXHANDLE PowerVar = 0;
1555    if(!VarName.IsEmpty())
1556    {
1557        S3D_DRV_D3D9_RESOLVEVAR(PowerVar, VarInfo, VarName);
1558    }
1559
1560    /*@{ @declare{shaderprog.param}
1561            {<d3d9_hlsl_shader>.mtl.emissive_codevar}{$ [str]}
1562        Mtl emissive color variable.
1563        @table
1564        {
1565            { @code{emissive_codevar.x} } { MtlEmissive.r }
1566        }                                                   
1567        {                                                   
1568            { @code{emissive_codevar.y} } { MtlEmissive.g }
1569        }                                                   
1570        {                                                   
1571            { @code{emissive_codevar.z} } { MtlEmissive.b }
1572        }                                                   
1573        {                                                   
1574            { @code{emissive_codevar.w} } { MtlEmissive.a }
1575        }
1576    @}*/
1577    MtrlSnkExtract.ExtractStr(
1578            VarInfo, VarName, "emissive_codevar", false);
1579    D3DXHANDLE EmissiveVar = 0;
1580    if(!VarName.IsEmpty())
1581    {
1582        S3D_DRV_D3D9_RESOLVEVAR(EmissiveVar, VarInfo, VarName);
1583    }
1584
1585    Mtl.m_PowerVar = PowerVar;
1586    Mtl.m_EmissiveVar = EmissiveVar;
1587    MtrlSnkExtract.CheckForUnknown();
1588}
1589
1590void s3d_CDrvD3d9ProgHLSLUtil::ExtractFog(
1591        const s3d_CDrvD3d9ProgCtx *ProgCtx,
1592        s3d_CUtilStr_cr CodeInfo, s3d_CUtilStr_cr CodeName,
1593        const LPD3DXCONSTANTTABLE ConstTab,
1594        D3DXHANDLE &FogVar,
1595        s3d_CDrvD3d9ProgHLSLVarSet &VarSet,
1596        s3d_CUtilSnkExtract &SnkExtract)
1597{
1598    /*@{ @declare{shaderprog.param}
1599            {<d3d9_hlsl_shader>.fog_codevar}{$ [str]}
1600        Fog color and denisity variable.
1601        @table
1602        {
1603            { @code{fog_codevar.x} } { FogColor.r }
1604        }                                                   
1605        {                                                   
1606            { @code{fog_codevar.y} } { FogColor.g }
1607        }                                                   
1608        {                                                   
1609            { @code{fog_codevar.z} } { FogColor.b }
1610        }                                                   
1611        {                                                   
1612            { @code{fog_codevar.w} } { FogDensity }
1613        }
1614    @}*/
1615    s3d_CUtilStr VarName, VarInfo;
1616    SnkExtract.ExtractStr(VarInfo, VarName, "fog_codevar", false);
1617    FogVar = 0;
1618    if(!VarName.IsEmpty())
1619    {
1620        S3D_DRV_D3D9_RESOLVEVAR(FogVar, VarInfo, VarName);
1621    }
1622}
1623
1624void s3d_CDrvD3d9ProgHLSLUtil::InitTrackBlk(
1625        const s3d_CDrvD3d9ProgCtx *ProgCtx,
1626        s3d_CUtilStr_cr CodeInfo, s3d_CUtilStr_cr CodeName,
1627        s3d_CDrvD3d9ProgHLSLTrackBlk &TrackBlk,
1628        s3d_CUtilSnkExtract &SnkExtract)
1629{
1630    TrackBlk.m_CodeInfo = CodeInfo;
1631    TrackBlk.m_CodeName = CodeName;
1632
1633    const LPD3DXCONSTANTTABLE ConstTab = TrackBlk.m_ConstTab;
1634    s3d_CDrvD3d9ProgHLSLVarSet VarSet;
1635    s3d_CDrvD3d9ProgHLSLUtil::ExtractParamArray(
1636            ProgCtx, CodeInfo, CodeName, ConstTab,
1637            TrackBlk.m_ParamArray, VarSet, SnkExtract);
1638    s3d_CDrvD3d9ProgHLSLUtil::ExtractTexSize(
1639            ProgCtx, CodeInfo, CodeName, ConstTab,
1640            TrackBlk.m_TexSizeArray, TrackBlk.m_TexRcpSizeArray,
1641            VarSet, SnkExtract);
1642    s3d_CDrvD3d9ProgHLSLUtil::ExtractTrackArray(
1643            ProgCtx, CodeInfo, CodeName, ConstTab,
1644            TrackBlk.m_MatTrackArray, TrackBlk.m_BoneTrackArray,
1645            VarSet, SnkExtract);
1646    s3d_CDrvD3d9ProgHLSLUtil::ExtractLightArray(
1647            ProgCtx, CodeInfo, CodeName, ConstTab,
1648            TrackBlk.m_ActiveLightCntVar, TrackBlk.m_LightTrackArray,
1649            VarSet, SnkExtract);
1650    s3d_CDrvD3d9ProgHLSLUtil::ExtractMtl(
1651            ProgCtx, CodeInfo, CodeName, ConstTab,
1652            TrackBlk.m_Mtl, VarSet, SnkExtract);
1653    s3d_CDrvD3d9ProgHLSLUtil::ExtractFog(
1654            ProgCtx, CodeInfo, CodeName, ConstTab,
1655            TrackBlk.m_FogVar, VarSet, SnkExtract);
1656
1657    s3d_CDrvD3d9ProgHLSLUtil::EnumAllVars(
1658            ProgCtx, CodeInfo, CodeName, ConstTab, VarSet);
1659}
1660
1661bool s3d_CDrvD3d9ProgHLSLUtil::CompileFromRes(
1662        s3d_CUtilNotifGather *NotifGather,
1663        const s3d_CDrvD3d9ProgCtx *ProgCtx,
1664        s3d_CUtilStr_cr CodeInfo, s3d_CUtilStr_cr CodeName,
1665        s3d_CUtilStr_cr EntryPoint, s3d_CUtilStr_cr Profile,
1666        s3d_CLibStreamPreproState *PreproState,
1667        s3d_CDrvD3d9Buf &CodeBuf, s3d_CDrvD3d9ConstTable &ConstTab)
1668{
1669    if(!ProgCtx)
1670        return false;
1671
1672    s3d_CUtilMsgHandler *MsgHandler = ProgCtx->m_MsgHandler;
1673    s3d_CCompResMgr *ResMgr = ProgCtx->m_ResMgr;
1674    s3d_CUtilMemPool *MemPool = ProgCtx->m_MemPool;
1675    s3d_CUtilMemPoolFrm MemPoolFrm(MemPool);
1676
1677    int Generosity = s3d_CCompResMgr::Generosity_AllowMissing;
1678    s3d_CUtilStr ResInfo;
1679    s3d_CUtilStreamPtr ResStream;
1680    bool Final = false;
1681    s3d_CUtilNotifEntryPtr NotifEntry = S3D_SYS_NEW s3d_CUtilNotifEntry;
1682    ResMgr->GetResource(
1683            CodeInfo, CodeName, true, Generosity,
1684            ResInfo, ResStream, Final, NotifEntry);
1685    if(NotifGather)
1686        NotifGather->AddNotifEntry(NotifEntry);
1687    if(!ResStream)
1688        return false;
1689
1690    s3d_CUtilStreamPos ResSize = ResStream->GetSize();
1691    if(ResSize == 0)
1692        return false;
1693
1694    UINT D3dStreamLen = UINT(ResSize);
1695    s3d_CSysIntm *ResData = new(MemPool) s3d_CSysIntm[D3dStreamLen + 1];
1696    ResStream->Read(D3dStreamLen, ResData);
1697    ResData[ResSize] = 0;
1698
1699    if(s3d_CDrvD3d9ProgUtil::CreateCodeBufOfBinData(
1700            ProgCtx, CodeBuf, D3dStreamLen, ResData))
1701        return true;
1702
1703    s3d_CUtilMap<s3d_CUtilStr, s3d_CUtilStr> StreamNameMap;
1704    // Errors contain no filename for the main file:
1705    StreamNameMap.SetAt("", ResInfo);
1706
1707    s3d_CDrvD3d9ProgIncMgr ProgIncMgr(
1708            MsgHandler, CodeInfo, MemPool, ResMgr,
1709            NotifGather, &StreamNameMap);
1710
1711    s3d_CUtilOwnArray<D3DXMACRO> D3dMacroArray;
1712    s3d_CDrvD3d9ProgUtil::D3dMarcoArrayOfPreprocArray(
1713            D3dMacroArray, PreproState);
1714
1715    s3d_CDrvD3d9Buf ErrBuf;
1716    const char *D3dStream = reinterpret_cast<char*>(ResData);
1717    DWORD Flags = 0;
1718    int DxResult = D3DXCompileShader(
1719            D3dStream, D3dStreamLen, D3dMacroArray.Get(), &ProgIncMgr,
1720            EntryPoint.GetChars(), Profile.GetChars(), Flags,
1721            &CodeBuf.EmptyRef(), &ErrBuf.EmptyRef(), &ConstTab.EmptyRef());
1722
1723    // ErrBuf can be valid even if assembling was successful, e.g. warnings.
1724    s3d_CDrvD3d9ProgReportMap Report(0, 0, &StreamNameMap);
1725    if(!Report.ReportCompilingBuffer(
1726            ProgCtx->m_Env, CodeInfo, ErrBuf, DxResult))
1727        return false;
1728
1729    return true;
1730}
1731
1732bool s3d_CDrvD3d9ProgHLSLUtil::CompileFromFile(
1733        s3d_CUtilNotifGather *NotifGather,
1734        const s3d_CDrvD3d9ProgCtx *ProgCtx,
1735        s3d_CUtilStr_cr CodeInfo, s3d_CUtilStr_cr CodeName,
1736        s3d_CUtilStr_cr EntryPoint, s3d_CUtilStr_cr Profile,
1737        s3d_CLibStreamPreproState *PreproState,
1738        s3d_CDrvD3d9Buf &CodeBuf, s3d_CDrvD3d9ConstTable &ConstTab)
1739{
1740    if(!ProgCtx)
1741        return false;
1742   
1743    s3d_CUtilMsgHandler *MsgHandler = ProgCtx->m_MsgHandler;
1744    s3d_CCompResMgr *ResMgr = ProgCtx->m_ResMgr;
1745    s3d_CUtilMemPool *MemPool = ProgCtx->m_MemPool;
1746
1747    s3d_CDrvD3d9Buf ErrBuf;
1748    s3d_CUtilMap<s3d_CUtilStr, s3d_CUtilStr> StreamNameMap;
1749    // Errors contain no filename for the main file:
1750    StreamNameMap.SetAt("", CodeName);
1751
1752     int DxResult = 0;
1753    // Own scope for MemPoolFrm, used by ProgIncMgr
1754    {
1755        s3d_CUtilMemPoolFrm MemPoolFrm(ProgCtx->m_MemPool);
1756        s3d_CDrvD3d9ProgIncMgr ProgIncMgr(
1757                MsgHandler, CodeInfo, MemPool, ResMgr,
1758                NotifGather, &StreamNameMap);
1759
1760        s3d_CUtilOwnArray<D3DXMACRO> D3dMacroArray;
1761        s3d_CDrvD3d9ProgUtil::D3dMarcoArrayOfPreprocArray(
1762                D3dMacroArray, PreproState);
1763
1764        DWORD Flags = D3DXSHADER_DEBUG;
1765        DxResult = D3DXCompileShaderFromFile(
1766                CodeName.GetChars(), D3dMacroArray.Get(), &ProgIncMgr,
1767                EntryPoint.GetChars(), Profile.GetChars(), Flags,
1768                &CodeBuf.EmptyRef(), &ErrBuf.EmptyRef(), 0);
1769    }
1770    // ErrBuf can be valid even if assembling was successful, e.g. warnings.
1771    s3d_CDrvD3d9ProgReportMap Report(0, 0, &StreamNameMap);
1772    if(!Report.ReportCompilingBuffer(
1773            ProgCtx->m_Env, CodeInfo, ErrBuf, DxResult))
1774        return false;
1775
1776    return true;
1777}
1778
1779void s3d_CDrvD3d9ProgHLSLUtil::ResolveVar(
1780        const s3d_CDrvD3d9ProgCtx *ProgCtx,
1781        s3d_CUtilStr_cr Info, s3d_CUtilStr_cr CodeName,
1782        LPD3DXCONSTANTTABLE ConstTab,
1783        D3DXHANDLE &Var, s3d_CUtilStr_cr VarName,
1784        s3d_CDrvD3d9ProgHLSLVarSet &VarSet)
1785{
1786    Var = 0;
1787    if(!ProgCtx)
1788        return;
1789    if(VarName.IsEmpty())
1790        return;
1791   
1792    if(ConstTab)
1793        Var = ConstTab->GetConstantByName(0, VarName.GetChars());
1794   
1795    if(!Var)
1796    {
1797/*
1798        s3d_CDrvDxError e;
1799        e.m_Code = "drv/imp/directx/d3d9/drv_d3d9_proghlsl.unused_codevar.";
1800        e.m_StdTempl = "Unused tracking variable '[1]' for "
1801                       "D3D HLSL shader \"[2]\" ";
1802        e.AddInfo(Info);
1803        e.AddInfo(VarName);
1804        e.AddInfo(CodeName);
1805        s3d_UtilMsgReportError(ProgCtx->m_MsgHandler, e);
1806*/
1807        return;
1808    }
1809
1810    bool AlreadyDefined = VarSet.DefineAt(Var);
1811    if(AlreadyDefined)
1812    {
1813        s3d_CDrvDxError e;
1814        e.m_Code = "drv/imp/directx/d3d9/drv_d3d9_proghlsl.multiple_tracked.";
1815        e.m_StdTempl = "Variable '[1]' is tracked more than once in"
1816                       "D3D HLSL shader \"[2]\" ";
1817        e.AddInfo(Info);
1818        e.AddInfo(VarName);
1819        e.AddInfo(CodeName);
1820        s3d_UtilMsgReportError(ProgCtx->m_MsgHandler, e);
1821    }
1822}
1823
1824void s3d_CDrvD3d9ProgHLSLUtil::EnumAllVars(
1825        const s3d_CDrvD3d9ProgCtx *ProgCtx,
1826        s3d_CUtilStr_cr CodeInfo, s3d_CUtilStr_cr CodeName,
1827        LPD3DXCONSTANTTABLE ConstTab,
1828        const s3d_CDrvD3d9ProgHLSLVarSet &VarSet)
1829{
1830    D3DXCONSTANTTABLE_DESC ConstTabDesc;
1831    S3D_DRV_D3D9_CHECK(
1832            ProgCtx->m_Env, ConstTab->GetDesc(&ConstTabDesc));
1833    UINT nConst = ConstTabDesc.Constants;
1834    UINT iConst;
1835    for(iConst = 0; iConst < nConst; iConst++)
1836    {
1837        D3DXHANDLE Var = 0;
1838        S3D_DRV_D3D9_HRESCALL(
1839                ProgCtx->m_Env, Var, ConstTab->GetConstant(
1840                    0, iConst));
1841        EnumVar(
1842                ProgCtx, CodeInfo, CodeName, ConstTab, Var, 0, VarSet);
1843    }       
1844}
1845
1846void s3d_CDrvD3d9ProgHLSLUtil::EnumVar(
1847        const s3d_CDrvD3d9ProgCtx *ProgCtx,
1848        s3d_CUtilStr_cr CodeInfo, s3d_CUtilStr_cr CodeName,
1849        LPD3DXCONSTANTTABLE ConstTab,
1850        D3DXHANDLE Var, s3d_CUtilStr_cr VarName,
1851        const s3d_CDrvD3d9ProgHLSLVarSet &VarSet)
1852{
1853    if(!ProgCtx)
1854        return;
1855    if(!ConstTab)
1856        return;
1857
1858    D3DXCONSTANT_DESC ConstDesc;
1859    s3d_SysMemset(&ConstDesc, 0, S3D_SYS_SIZEOFS(ConstDesc));
1860    UINT ConstDescCnt = 1;
1861    S3D_DRV_D3D9_CHECK(
1862            ProgCtx->m_Env, ConstTab->GetConstantDesc(
1863                Var, &ConstDesc, &ConstDescCnt));
1864
1865    s3d_CUtilStrBuf VarNameBuf;
1866    VarNameBuf.Append(VarName);
1867    VarNameBuf.Append(ConstDesc.Name);
1868
1869    s3d_CDrvD3d9ProgHLSLUtil::CheckVarInitialized(
1870            ProgCtx, CodeInfo, CodeName, Var, VarNameBuf, ConstDesc, VarSet);
1871
1872    UINT nElem = ConstDesc.Elements;
1873    UINT iElem;
1874    for(iElem = 0; iElem < nElem; iElem++)
1875    {
1876        D3DXHANDLE ElemVar = 0;
1877        S3D_DRV_D3D9_HRESCALL(
1878                ProgCtx->m_Env, ElemVar, ConstTab->GetConstantElement(
1879                    Var, iElem));
1880
1881        UINT nStruct = ConstDesc.StructMembers;
1882        UINT iStruct;
1883        for(iStruct = 0; iStruct < nStruct; iStruct++)
1884        {
1885            D3DXHANDLE StructVar = 0;
1886            S3D_DRV_D3D9_HRESCALL(
1887                    ProgCtx->m_Env, StructVar, ConstTab->GetConstant(
1888                        ElemVar, iStruct));
1889
1890            D3DXCONSTANT_DESC ElemConstDesc;
1891            s3d_SysMemset(&ElemConstDesc, 0, S3D_SYS_SIZEOFS(ElemConstDesc));
1892            UINT ElemConstDescCnt = 1;
1893            S3D_DRV_D3D9_CHECK(
1894                    ProgCtx->m_Env, ConstTab->GetConstantDesc(
1895                        StructVar, &ElemConstDesc, &ElemConstDescCnt));   
1896
1897            VarNameBuf.Reset();
1898            VarNameBuf = VarName;
1899            VarNameBuf.Append(ConstDesc.Name);
1900            VarNameBuf.Append("[");
1901            VarNameBuf.Append(s3d_CUtilStrUtil::StrOfInt(iElem));
1902            VarNameBuf.Append("].");
1903
1904            EnumVar(
1905                    ProgCtx, CodeInfo, CodeName, ConstTab,
1906                    StructVar, VarNameBuf, VarSet);
1907        }
1908
1909        D3DXCONSTANT_DESC ElemConstDesc;
1910        s3d_SysMemset(&ElemConstDesc, 0, S3D_SYS_SIZEOFS(ElemConstDesc));
1911        UINT ElemConstDescCnt = 1;
1912        S3D_DRV_D3D9_CHECK(
1913                ProgCtx->m_Env, ConstTab->GetConstantDesc(
1914                    ElemVar, &ElemConstDesc, &ElemConstDescCnt));   
1915       
1916        VarNameBuf.Reset();
1917        VarNameBuf = VarName;
1918        VarNameBuf.Append(ElemConstDesc.Name);
1919        VarNameBuf.Append("[");
1920        VarNameBuf.Append(s3d_CUtilStrUtil::StrOfInt(iElem));
1921        VarNameBuf.Append("]");
1922
1923        s3d_CDrvD3d9ProgHLSLUtil::CheckVarInitialized(
1924                ProgCtx, CodeInfo, CodeName,
1925                Var, VarNameBuf, ElemConstDesc, VarSet);
1926    }
1927}
1928
1929void s3d_CDrvD3d9ProgHLSLUtil::CheckVarInitialized(
1930        const s3d_CDrvD3d9ProgCtx *ProgCtx,
1931        s3d_CUtilStr_cr CodeInfo, s3d_CUtilStr_cr CodeName,
1932        D3DXHANDLE Var, s3d_CUtilStr_cr VarName,
1933        const D3DXCONSTANT_DESC &VarDesc,
1934        const s3d_CDrvD3d9ProgHLSLVarSet &VarSet)
1935{
1936    if(!VarDesc.DefaultValue && !VarSet.IsDefined(Var))
1937    {
1938        if(VarDesc.RegisterSet != D3DXRS_SAMPLER
1939            && VarDesc.Class != D3DXPC_STRUCT)
1940        {
1941            s3d_CDrvD3d9Error e;
1942            e.m_Code = "drv/imp/directx/d3d9/drv_d3d9_proghlsl.undef_codevar.";
1943            e.m_StdTempl = "Uninitialized code variable '[1]' for "
1944                        "D3D HLSL shader \"[2]\" ";
1945            e.AddInfo(CodeInfo);
1946            e.AddInfo(VarName);
1947            e.AddInfo(CodeName);
1948            s3d_UtilMsgReportError(ProgCtx->m_MsgHandler, e);
1949        }
1950    }
1951}
1952
1953///////////////////////////////////////////////////////////////////////////////
Note: See TracBrowser for help on using the repository browser.