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

Revision 2236, 58.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//@cpp
15
16#include "drv_d3d9_progasm.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#include <malloc.h>
30
31///////////////////////////////////////////////////////////////////////////////
32/*@{
33
34@declare{shaderprog.param}{<d3d9_asm_shader>}{$ [chunk]}
35
36Parameters for d3d assembly @ident{shaderprog}{d3d9.asm_vertshader}
37and @ident{shaderprog}{d3d9.asm_pixshader}.
38This is a pseudo chunk name.
39
40@}*/
41///////////////////////////////////////////////////////////////////////////////
42
43void s3d_CDrvD3d9ProgAsmTrackBlkVert::SetShaderConstF(
44        s3d_CDrvD3d9ProgCtx *ProgCtx,
45        UINT ConstAddr, const float *ConstVal, UINT ConstCnt) const
46{
47    S3D_DRV_D3D9_CHECK(
48            ProgCtx->m_Env, ProgCtx->m_D3dDev->SetVertexShaderConstantF(
49                ConstAddr, ConstVal, ConstCnt));
50}
51
52void s3d_CDrvD3d9ProgAsmTrackBlkVert::SetShaderConstI(
53        s3d_CDrvD3d9ProgCtx *ProgCtx,
54        UINT ConstAddr, const int *ConstVal, UINT ConstCnt) const
55{
56    S3D_DRV_D3D9_CHECK(
57            ProgCtx->m_Env, ProgCtx->m_D3dDev->SetVertexShaderConstantI(
58                ConstAddr, ConstVal, ConstCnt));
59}
60
61///////////////////////////////////////////////////////////////////////////////
62
63void s3d_CDrvD3d9ProgAsmTrackBlkPix::SetShaderConstF(
64        s3d_CDrvD3d9ProgCtx *ProgCtx,
65        UINT ConstAddr, const float *ConstVal, UINT ConstCnt) const
66{
67    S3D_DRV_D3D9_CHECK(
68            ProgCtx->m_Env, ProgCtx->m_D3dDev->SetPixelShaderConstantF(
69                ConstAddr, ConstVal, ConstCnt));
70}
71
72void s3d_CDrvD3d9ProgAsmTrackBlkPix::SetShaderConstI(
73        s3d_CDrvD3d9ProgCtx *ProgCtx,
74        UINT ConstAddr, const int *ConstVal, UINT ConstCnt) const
75{
76    S3D_DRV_D3D9_CHECK(
77            ProgCtx->m_Env, ProgCtx->m_D3dDev->SetPixelShaderConstantI(
78                ConstAddr, ConstVal, ConstCnt));
79}
80
81///////////////////////////////////////////////////////////////////////////////
82
83s3d_CDrvD3d9ProgAsm::s3d_CDrvD3d9ProgAsm(
84        s3d_CUtilNotifGather *NotifGather, s3d_CUtilStr_cr Info,
85        s3d_CDrvD3d9ProgCtx *ProgCtx,
86        s3d_CUtilSnkChunk *ParamVert, s3d_CUtilSnkChunk *ParamPix)
87{
88    m_ProgCtx = ProgCtx;
89    m_Info = Info;
90
91    const s3d_CDrvD3d9Param *D3dParam = ProgCtx->m_D3dParam;
92    if(D3dParam->m_ReportProg)
93        m_ReportMsgHandler = ProgCtx->m_MsgHandler;
94
95    if(ParamVert)
96    {
97        s3d_CDrvD3d9ProgAsmUtil::CreateShader(
98                NotifGather, ParamVert, ProgCtx, true, this,
99                        m_VertTrackBlk);
100    }
101
102    if(ParamPix)
103    {
104        s3d_CDrvD3d9ProgAsmUtil::CreateShader(
105                NotifGather, ParamPix, ProgCtx, false, this, m_PixTrackBlk);
106    }
107}
108
109void s3d_CDrvD3d9ProgAsm::TrackParams(
110        s3d_CDrvGfxParam_cr GfxParam,
111        const s3d_CDrvD3d9ParamBlk &ParamBlk,
112        const s3d_CDrvD3d9ParamBlkState &ParamBlkState)
113{
114    TrackParams(GfxParam, ParamBlk, ParamBlkState, m_VertTrackBlk);
115    TrackParams(GfxParam, ParamBlk, ParamBlkState, m_PixTrackBlk);
116}
117
118void s3d_CDrvD3d9ProgAsm::TrackTransfBone(
119        s3d_CSysIntps BoneIdxCnt, const s3d_CSysInt32u *BoneIdxData,
120        s3d_CSysIntps MatBoneCnt, const D3DXMATRIXA16 *MatBoneArray)
121{
122    TrackTransfBone(
123            BoneIdxCnt, BoneIdxData, MatBoneCnt, MatBoneArray,
124            m_VertTrackBlk);
125    TrackTransfBone(
126            BoneIdxCnt, BoneIdxData, MatBoneCnt, MatBoneArray,
127            m_PixTrackBlk);
128}
129
130void s3d_CDrvD3d9ProgAsm::CalcVertBufDesc(
131        const s3d_CDrvGfxCharge *Charge,
132        s3d_CDrvD3d9VertBufDesc &VertBufDesc) const
133{
134    s3d_CDrvD3d9ProgUtil::CalcVertBufDesc(
135            m_ProgCtx, Charge, m_VertProgDecl.m_ProgUsage,
136            m_VertComprFmt, VertBufDesc);
137}
138
139bool s3d_CDrvD3d9ProgAsm::IsValid()
140{
141    if(!m_VertTrackBlk.m_CodeName.IsEmpty() && !m_VertShader)
142        return false;
143    if(!m_PixTrackBlk.m_CodeName.IsEmpty() && !m_PixShader)
144        return false;
145    return true;
146}
147
148void s3d_CDrvD3d9ProgAsm::GetVertProgCodeInfoName(
149        s3d_CUtilStr &CodeInfo, s3d_CUtilStr &CodeName) const
150{
151    CodeInfo = m_VertTrackBlk.m_CodeInfo;
152    CodeName = m_VertTrackBlk.m_CodeName;
153}
154
155void s3d_CDrvD3d9ProgAsm::GetPixProgCodeInfoName(
156        s3d_CUtilStr &CodeInfo, s3d_CUtilStr &CodeName) const
157{
158    CodeInfo = m_PixTrackBlk.m_CodeInfo;
159    CodeName = m_PixTrackBlk.m_CodeName;
160}
161
162///////////////////////////////////////////////////////////////////////////////
163
164void s3d_CDrvD3d9ProgAsm::TrackMatTrans(
165        const int &Addr, int Trans,
166        const D3DXMATRIXA16 *Mat, s3d_CSysIntps Cnt,
167        s3d_CDrvD3d9ProgAsmTrackBlk &TrackBlk)
168{
169    UINT ConstCnt = UINT(Cnt << 2);
170    switch(Trans)
171    {
172        case s3d_CDrvUtilGfxProg::TrackTrans_Identity:
173        {
174            const float *ConstVal = reinterpret_cast<const float *>(Mat);
175            TrackBlk.SetShaderConstF(m_ProgCtx, Addr, ConstVal, ConstCnt);
176            break;
177        }
178        case s3d_CDrvUtilGfxProg::TrackTrans_Inv:
179        {
180            D3DXMATRIXA16 *InvMat
181                    = reinterpret_cast<D3DXMATRIXA16 *>
182                        (alloca(Cnt * S3D_SYS_SIZEOFS(D3DXMATRIXA16)));
183            s3d_CSysIntps i;
184            for(i = 0; i < Cnt; i++)
185                D3DXMatrixInverse(&InvMat[i], 0, Mat);
186
187            const float *ConstVal = reinterpret_cast<const float *>(InvMat);
188            TrackBlk.SetShaderConstF(m_ProgCtx, Addr, ConstVal, ConstCnt);
189            break;
190        }
191        case s3d_CDrvUtilGfxProg::TrackTrans_Transp:
192        {
193            D3DXMATRIXA16 *TranspMat
194                    = reinterpret_cast<D3DXMATRIXA16 *>
195                        (alloca(Cnt * S3D_SYS_SIZEOFS(D3DXMATRIXA16)));
196            s3d_CSysIntps i;
197            for(i = 0; i < Cnt; i++)
198                D3DXMatrixTranspose(&TranspMat[i], Mat);
199
200            const float *ConstVal = reinterpret_cast<const float *>(TranspMat);
201            TrackBlk.SetShaderConstF(m_ProgCtx, Addr, ConstVal, ConstCnt);
202            break;
203        }
204        case s3d_CDrvUtilGfxProg::TrackTrans_InvTransp:
205        {
206            D3DXMATRIXA16 *InvTranspMat
207                    = reinterpret_cast<D3DXMATRIXA16 *>
208                        (alloca(Cnt * S3D_SYS_SIZEOFS(D3DXMATRIXA16)));
209            D3DXMATRIXA16 *TranspMat
210                    = reinterpret_cast<D3DXMATRIXA16 *>
211                        (alloca(Cnt * S3D_SYS_SIZEOFS(D3DXMATRIXA16)));
212            s3d_CSysIntps i;
213            for(i = 0; i < Cnt; i++)
214            {
215                D3DXMatrixTranspose(&TranspMat[i], Mat);
216                D3DXMatrixInverse(&InvTranspMat[i], 0, &TranspMat[i]);
217            }
218
219            const float *ConstVal = reinterpret_cast<const float *>(
220                    InvTranspMat);
221            TrackBlk.SetShaderConstF(m_ProgCtx, Addr, ConstVal, ConstCnt);
222            break;
223        }
224        default:
225            S3D_SYS_ASSERT(0);
226            break;
227    }
228}
229
230void s3d_CDrvD3d9ProgAsm::TrackParams(
231        s3d_CDrvGfxParam_cr GfxParam,
232        const s3d_CDrvD3d9ParamBlk &ParamBlk,
233        const s3d_CDrvD3d9ParamBlkState &ParamBlkState,
234        s3d_CDrvD3d9ProgAsmTrackBlk &TrackBlk)
235{
236    LPDIRECT3DDEVICE9 D3dDev = m_ProgCtx->m_D3dDev;
237    if(!D3dDev)
238        return;
239
240    const s3d_CSysChar *Info = TrackBlk.m_CodeInfo.GetChars();
241
242    const s3d_CDrvD3d9ProgAsmTrackMatArray *TrackMatArray
243            = &TrackBlk.m_MatTrackArray;
244    s3d_CSysIntps nTrackMat = TrackMatArray->GetCnt();
245    s3d_CSysIntps iTrackMat;
246    for(iTrackMat = 0; iTrackMat < nTrackMat; iTrackMat++)
247    {
248        const s3d_CDrvD3d9ProgAsmTrackMat *TrackMat
249                = &TrackMatArray->RefAtRaw(iTrackMat);
250        int Addr = TrackMat->m_Addr;
251        if(Addr < 0)
252            continue;
253
254        int Trans = TrackMat->m_Trans;
255        switch(TrackMat->m_Chan)
256        {
257            case s3d_CDrvUtilGfxProg::TrackChan_View:
258            {
259                if(ParamBlkState.m_DirtyMask
260                    & s3d_CDrvD3d9ParamBlkState::Dirty_MatView)
261                {
262                    TrackMatTrans(
263                            Addr, Trans, &ParamBlk.m_MatView, 1, TrackBlk);
264                }
265                break;
266            }
267            case s3d_CDrvUtilGfxProg::TrackChan_Proj:
268            {
269                if(ParamBlkState.m_DirtyMask
270                    & s3d_CDrvD3d9ParamBlkState::Dirty_MatProj)
271                {
272                    TrackMatTrans(
273                            Addr, Trans, &ParamBlk.m_MatProj, 1, TrackBlk);
274                }
275                break;
276            }
277            case s3d_CDrvUtilGfxProg::TrackChan_ProjView:
278            {
279                if((ParamBlkState.m_DirtyMask
280                        & s3d_CDrvD3d9ParamBlkState::Dirty_MatView)
281                    || (ParamBlkState.m_DirtyMask
282                        & s3d_CDrvD3d9ParamBlkState::Dirty_MatProj))
283                {
284                    D3DXMATRIXA16 ProjView;
285                    D3DXMatrixMultiply(
286                            &ProjView,
287                            &ParamBlk.m_MatProj, &ParamBlk.m_MatView);
288                    TrackMatTrans(Addr, Trans, &ProjView, 1, TrackBlk);
289                }
290                break;
291            }
292            case s3d_CDrvUtilGfxProg::TrackChan_Identity:
293            {
294                S3D_SYS_ASSERT(0);
295                break;
296            }
297            case s3d_CDrvUtilGfxProg::TrackChan_Attr:
298            {
299                if(ParamBlkState.m_DirtyMask
300                    & s3d_CDrvD3d9ParamBlkState::Dirty_MatGen)
301                {
302                    int Slot = TrackMat->m_Slot;
303                    int Cnt = s3d_SysMin(
304                            TrackMat->m_Cnt, m_ProgCtx->m_MaxAttrCnt);
305                    const D3DXMATRIXA16 *Mat = &ParamBlk.m_MatGenArray[Slot];
306                    TrackMatTrans(Addr, Trans, Mat, Cnt, TrackBlk);
307                }
308                break;
309            }
310            default:
311                break;
312        }
313    }
314
315    if(ParamBlk.m_UseConstColorAlpha)
316        TrackNoLighting(ParamBlk, ParamBlkState, TrackBlk);
317    else
318        TrackLighting(ParamBlk, ParamBlkState, TrackBlk);
319
320    if(TrackBlk.m_FogAddr >= 0
321        && (ParamBlkState.m_DirtyMask
322            & s3d_CDrvD3d9ParamBlkState::Dirty_Fog))
323    {
324        TrackBlk.SetShaderConstF(
325                m_ProgCtx, TrackBlk.m_FogAddr,
326                ParamBlk.m_FogColDensity, 1);
327    }
328
329    const s3d_CDrvD3d9TexObjBasePtr *SampTexArray = ParamBlk.m_SampTexArray;
330    const s3d_CDrvD3d9ProgAsmAddrArray *TexSizeArray
331            = &TrackBlk.m_TexSizeArray;
332    s3d_CSysIntps nTex = TexSizeArray->GetCnt();
333    s3d_CSysIntps iTex;
334    for(iTex = 0; iTex < nTex; iTex++)
335    {
336        const int Addr = TexSizeArray->GetAtRaw(iTex);
337        if(Addr >= 0)
338        {
339            float Vec4[4] = {0,0,0,0};
340            s3d_CDrvD3d9TexObjBase *Tex = 0;
341            if(iTex < m_ProgCtx->m_MaxSampCnt)
342                Tex = SampTexArray[iTex];
343            if(Tex)
344            {
345                Vec4[0] = s3d_SysFloatOfInt<float>(Tex->m_Width);
346                Vec4[1] = s3d_SysFloatOfInt<float>(Tex->m_Height);
347                Vec4[2] = s3d_SysFloatOfInt<float>(Tex->m_Depth);
348                Vec4[3] = 0;
349            }
350            TrackBlk.SetShaderConstF(m_ProgCtx, Addr, Vec4, 1);
351        }
352    }
353
354    const s3d_CDrvD3d9ProgAsmAddrArray *TexRcpSizeArray
355            = &TrackBlk.m_TexRcpSizeArray;
356    nTex = TexRcpSizeArray->GetCnt();
357    for(iTex = 0; iTex < nTex; iTex++)
358    {
359        int Addr = TexRcpSizeArray->GetAtRaw(iTex);
360        if(Addr >= 0)
361        {
362            float Vec4[4] = {0,0,0,0};
363            s3d_CDrvD3d9TexObjBase *Tex = 0;
364            if(iTex < m_ProgCtx->m_MaxSampCnt)
365                Tex = SampTexArray[iTex];
366            if(Tex)
367            {
368                Vec4[0] = 1 / s3d_SysFloatOfInt<float>(Tex->m_Width);
369                Vec4[1] = 1 / s3d_SysFloatOfInt<float>(Tex->m_Height);
370                Vec4[2] = 1 / s3d_SysFloatOfInt<float>(Tex->m_Depth);
371                Vec4[3] = 0;
372            }
373            TrackBlk.SetShaderConstF(m_ProgCtx, Addr, Vec4, 1);
374        }
375    }
376
377    s3d_CDrvUtilVarFetch VarFetch(
378            m_ProgCtx->m_MsgHandler, GfxParam.m_Blk);
379
380    s3d_CDrvD3d9ProgAsmParamEntry *ParamArray
381            = TrackBlk.m_ParamArray.GetPtrRaw();
382    s3d_CSysIntps nParam = TrackBlk.m_ParamArray.GetCnt();
383    s3d_CSysIntps iParam;
384    for(iParam = 0; iParam < nParam; iParam++)
385    {
386        s3d_CDrvD3d9ProgAsmParamEntry *Param = &ParamArray[iParam];
387        s3d_CDrvVarSlot *VarSlot
388                = VarFetch.FetchNextSlot(
389                        Param->m_Val.m_Info.GetChars(), Param->m_Key,
390                        Param->m_Val.m_HadError,
391                        Param->m_Val.m_HadError);
392        s3d_CUtilRecogBase *VarRecog
393                = s3d_DrvVarFetchWary(m_ProgCtx->m_MsgHandler, Info,
394                    GfxParam.m_Blk, *VarSlot);
395       
396        if(!VarRecog)
397            continue;
398
399        const s3d_CDrvD3d9ProgAsmParam *ParamEntry = &Param->m_Val;
400        int Addr = ParamEntry->m_Addr;
401        if(Addr < 0)
402            continue;
403        const s3d_CSysChar *ParamInfo = ParamEntry->m_Info.GetChars();
404        switch(ParamEntry->m_Type)
405        {
406            case s3d_CDrvUtilGfxProg::ParamType_Float4:
407            {
408                const s3d_CDrvVarVec4f *DrvVar
409                        = s3d_DrvVarCast<s3d_CDrvVarVec4f>(
410                            m_ProgCtx->m_MsgHandler, ParamInfo,
411                            GfxParam.m_Blk,
412                            *VarSlot, VarRecog);
413                if(DrvVar)
414                {
415                    const float *ConstVal
416                            = reinterpret_cast<const float*>(&DrvVar->m_Val);
417                    TrackBlk.SetShaderConstF(m_ProgCtx, Addr, ConstVal, 1);
418                }
419                break;
420            }
421
422            case s3d_CDrvUtilGfxProg::ParamType_Float4x4:
423            case s3d_CDrvUtilGfxProg::ParamType_Float4x4_Transp:
424            case s3d_CDrvUtilGfxProg::ParamType_Float4x4_Inv:
425            case s3d_CDrvUtilGfxProg::ParamType_Float4x4_InvTransp:
426            {
427                const s3d_CDrvVarMat4x4f *DrvVar;
428                DrvVar = s3d_DrvVarCast<s3d_CDrvVarMat4x4f>(
429                        m_ProgCtx->m_MsgHandler, ParamInfo, GfxParam.m_Blk,
430                        *VarSlot, VarRecog);
431                if(DrvVar)
432                {
433                    D3DXMATRIXA16 Mat;
434                    const s3d_CUtilMat4x4f *EngMat = &DrvVar->m_Val;
435                    Mat._11 = EngMat->m_xx;
436                    Mat._21 = EngMat->m_yx;
437                    Mat._31 = EngMat->m_zx;
438                    Mat._41 = EngMat->m_wx;
439                    Mat._12 = EngMat->m_xy;
440                    Mat._22 = EngMat->m_yy;
441                    Mat._32 = EngMat->m_zy;
442                    Mat._42 = EngMat->m_wy;
443                    Mat._13 = EngMat->m_xz;
444                    Mat._23 = EngMat->m_yz;
445                    Mat._33 = EngMat->m_zz;
446                    Mat._43 = EngMat->m_wz;
447                    Mat._14 = EngMat->m_xw;
448                    Mat._24 = EngMat->m_yw;
449                    Mat._34 = EngMat->m_zw;
450                    Mat._44 = EngMat->m_ww;
451                    int Trans = ParamEntry->m_Type; /*s3d_CDrvUtilGfxProg::TransOfParamType(
452                            ParamEntry->m_Type);*/
453                    TrackMatTrans(Addr, Trans, &Mat, 1, TrackBlk);
454               }
455                break;
456            }
457            default:
458                S3D_SYS_ASSERT(0);
459                break;
460        }
461    }
462}
463
464void s3d_CDrvD3d9ProgAsm::TrackNoLighting(
465        const s3d_CDrvD3d9ParamBlk &ParamBlk,
466        const s3d_CDrvD3d9ParamBlkState &ParamBlkState,
467        s3d_CDrvD3d9ProgAsmTrackBlk &TrackBlk)
468{
469    LPDIRECT3DDEVICE9 D3dDev = m_ProgCtx->m_D3dDev;
470   
471    int Addr = TrackBlk.m_Mtl.m_EmissiveAddr;
472    if(Addr >= 0)
473    {
474        const float *Vec4
475                = reinterpret_cast<const float *>(&ParamBlk.m_ColorAlphaVal);
476        TrackBlk.SetShaderConstF(m_ProgCtx, Addr, Vec4, 1);
477    }
478
479    Addr = TrackBlk.m_ActiveLightCntAddr;
480    if(Addr >= 0)
481    {
482        int Vec4[4];
483        Vec4[0] = 0;
484        Vec4[1] = 0;
485        Vec4[2] = 0;
486        Vec4[3] = 0;
487        TrackBlk.SetShaderConstI(m_ProgCtx, Addr, Vec4, 1);
488    }
489    s3d_CSysIntps FromLight = 0;
490    TrackLightingBlack(ParamBlk, ParamBlkState, TrackBlk, FromLight);
491}
492
493void s3d_CDrvD3d9ProgAsm::TrackLighting(
494        const s3d_CDrvD3d9ParamBlk &ParamBlk,
495        const s3d_CDrvD3d9ParamBlkState &ParamBlkState,
496        s3d_CDrvD3d9ProgAsmTrackBlk &TrackBlk)
497{
498    LPDIRECT3DDEVICE9 D3dDev = m_ProgCtx->m_D3dDev;
499   
500    if(ParamBlkState.m_DirtyMask
501        & s3d_CDrvD3d9ParamBlkState::Dirty_Mtl)
502    {
503        int Addr = TrackBlk.m_Mtl.m_EmissiveAddr;
504        if(Addr >= 0)
505        {
506            const float *Vec4
507                    = reinterpret_cast<const float *>(
508                        &ParamBlk.m_Mtl.Emissive);
509            TrackBlk.SetShaderConstF(m_ProgCtx, Addr, Vec4, 1);
510        }
511        Addr = TrackBlk.m_Mtl.m_PowerAddr;
512        if(Addr >= 0)
513        {
514            float Vec4[4];
515            Vec4[0] = ParamBlk.m_Mtl.Power;
516            Vec4[1] = ParamBlk.m_Mtl.Power;
517            Vec4[2] = ParamBlk.m_Mtl.Power;
518            Vec4[3] = ParamBlk.m_Mtl.Power;
519            TrackBlk.SetShaderConstF(m_ProgCtx, Addr, Vec4, 1);
520        }
521    }
522   
523    if(ParamBlkState.m_DirtyMask
524        & s3d_CDrvD3d9ParamBlkState::Dirty_Light)
525    {
526        const s3d_CDrvD3d9ProgAsmLightArray *LightTrackArray
527                = &TrackBlk.m_LightTrackArray;
528        s3d_CSysIntps MaxProgLightCnt = LightTrackArray->GetCnt();
529
530        s3d_CSysIntps nLightCnt = ParamBlk.m_CurLightCnt;
531        const D3DLIGHT9 *Light = ParamBlk.m_LightArray;
532
533        if(nLightCnt > MaxProgLightCnt)
534            nLightCnt = MaxProgLightCnt;
535
536        const s3d_CDrvD3d9ProgAsmLight *ProgLight
537                = LightTrackArray->GetPtrRaw();
538
539        s3d_CSysIntps iLight;
540        for(iLight = 0; iLight < nLightCnt; iLight++)
541        {
542            int Addr = ProgLight->m_AmbientAddr;
543            if(Addr >= 0)
544            {
545                const float *Vec4
546                        = reinterpret_cast<const float *>(&Light->Ambient);
547                TrackBlk.SetShaderConstF(m_ProgCtx, Addr, Vec4, 1);
548            }
549            Addr = ProgLight->m_DiffuseAddr;
550            if(Addr >= 0)
551            {
552                const float *Vec4
553                        = reinterpret_cast<const float *>(&Light->Diffuse);
554                TrackBlk.SetShaderConstF(m_ProgCtx, Addr, Vec4, 1);
555            }
556            Addr = ProgLight->m_SpecularAddr;
557            if(Addr >= 0)
558            {
559                const float *Vec4
560                        = reinterpret_cast<const float *>(&Light->Specular);
561                TrackBlk.SetShaderConstF(m_ProgCtx, Addr, Vec4, 1);
562            }
563            Addr = ProgLight->m_PosAddr;
564            if(Addr >= 0)
565            {
566                const float *Vec4
567                        = reinterpret_cast<const float *>(&Light->Position);
568                TrackBlk.SetShaderConstF(m_ProgCtx, Addr, Vec4, 1);
569            }
570            Addr = ProgLight->m_DirAddr;
571            if(Addr >= 0)
572            {
573                const float *Vec4
574                        = reinterpret_cast<const float *>(&Light->Direction);
575                TrackBlk.SetShaderConstF(m_ProgCtx, Addr, Vec4, 1);
576            }
577            Addr = ProgLight->m_AttenAddr;
578            if(Addr >= 0)
579            {
580                float Atten[4];
581                Atten[0] = Light->Attenuation0;
582                Atten[1] = Light->Attenuation1;
583                Atten[2] = Light->Attenuation2;
584                Atten[3] = Light->Range;
585                TrackBlk.SetShaderConstF(m_ProgCtx, Addr, Atten, 1);
586            }
587            Light++;
588            ProgLight++;
589        }
590        int Addr = TrackBlk.m_ActiveLightCntAddr;
591        if(Addr >= 0)
592        {
593            int Vec4[4];
594            Vec4[0] = int(nLightCnt);
595            Vec4[1] = int(nLightCnt);
596            Vec4[2] = int(nLightCnt);
597            Vec4[3] = int(nLightCnt);
598            TrackBlk.SetShaderConstI(m_ProgCtx, Addr, Vec4, 1);
599        }
600        if(nLightCnt < MaxProgLightCnt)
601        {
602            TrackLightingBlack(
603                    ParamBlk, ParamBlkState, TrackBlk, nLightCnt);
604        }
605    }
606}
607
608void s3d_CDrvD3d9ProgAsm::TrackLightingBlack(
609        const s3d_CDrvD3d9ParamBlk &ParamBlk,
610        const s3d_CDrvD3d9ParamBlkState &ParamBlkState,
611        s3d_CDrvD3d9ProgAsmTrackBlk &TrackBlk,
612        s3d_CSysIntps FromLight)
613{
614    LPDIRECT3DDEVICE9 D3dDev = m_ProgCtx->m_D3dDev;
615
616    const s3d_CDrvD3d9ProgAsmLightArray *LightArray
617            = &TrackBlk.m_LightTrackArray;
618    s3d_CSysIntps nLightCnt = LightArray->GetCnt();
619    s3d_CSysIntps iLight;
620    for(iLight = FromLight; iLight < nLightCnt; iLight++)
621    {
622        const s3d_CDrvD3d9ProgAsmLight *ProgLight
623                = &LightArray->RefAtRaw(iLight);
624        const float Vec4[4] = {0, 0, 0, 0};
625        int Addr = ProgLight->m_AmbientAddr;
626        if(Addr >= 0)
627            TrackBlk.SetShaderConstF(m_ProgCtx, Addr, Vec4, 1);
628        Addr = ProgLight->m_DiffuseAddr;
629        if(Addr >= 0)
630            TrackBlk.SetShaderConstF(m_ProgCtx, Addr, Vec4, 1);
631        Addr = ProgLight->m_SpecularAddr;
632        if(Addr >= 0)
633            TrackBlk.SetShaderConstF(m_ProgCtx, Addr, Vec4, 1);
634        Addr = ProgLight->m_PosAddr;
635        if(Addr >= 0)
636            TrackBlk.SetShaderConstF(m_ProgCtx, Addr, Vec4, 1);
637        Addr = ProgLight->m_DirAddr;
638        if(Addr >= 0)
639            TrackBlk.SetShaderConstF(m_ProgCtx, Addr, Vec4, 1);
640        Addr = ProgLight->m_AttenAddr;
641        if(Addr >= 0)
642            TrackBlk.SetShaderConstF(m_ProgCtx, Addr, Vec4, 1);
643    }
644}
645
646void s3d_CDrvD3d9ProgAsm::TrackTransfBone(
647        s3d_CSysIntps BoneIdxCnt, const s3d_CSysInt32u *BoneIdxData,
648        s3d_CSysIntps MatBoneCnt, const D3DXMATRIXA16 *MatBoneArray,
649        s3d_CDrvD3d9ProgAsmTrackBlk &TrackBlk)
650{
651    if(!BoneIdxData)
652        return;
653    if(!MatBoneArray)
654        return;
655
656    LPDIRECT3DDEVICE9 D3dDev = m_ProgCtx->m_D3dDev;
657    const s3d_CSysChar *Info = TrackBlk.m_CodeInfo.GetChars();
658
659    LPD3DXMATRIXA16 BoneMatData
660            = reinterpret_cast<LPD3DXMATRIXA16>(
661                alloca(S3D_SYS_SIZEOFS(D3DXMATRIXA16) * BoneIdxCnt));
662    s3d_CSysIntps iBoneIdx;
663    for(iBoneIdx = 0; iBoneIdx < BoneIdxCnt; iBoneIdx++)
664    {
665        s3d_CSysIntps MatBoneIdx = BoneIdxData[iBoneIdx];
666        if(MatBoneIdx >= MatBoneCnt)
667            continue;
668        BoneMatData[iBoneIdx] = MatBoneArray[MatBoneIdx];
669    }
670
671    const s3d_CDrvD3d9ProgAsmTrackMatArray *TrackMatArray
672            = &TrackBlk.m_BoneTrackArray;
673    s3d_CSysIntps nTrackMat = TrackMatArray->GetCnt();
674    s3d_CSysIntps iTrackMat;
675    for(iTrackMat = 0; iTrackMat < nTrackMat; iTrackMat++)
676    {
677        const s3d_CDrvD3d9ProgAsmTrackMat *TrackMat
678                = &TrackMatArray->RefAtRaw(iTrackMat);
679        int Addr = TrackMat->m_Addr;
680        if(Addr < 0)
681            continue;
682
683        int Trans = TrackMat->m_Trans;
684        switch(TrackMat->m_Chan)
685        {
686            case s3d_CDrvUtilGfxProg::TrackChan_Bone:
687            {
688                TrackMatTrans(
689                        Addr, Trans, BoneMatData, BoneIdxCnt, TrackBlk);
690                break;
691            }
692            default:
693            {
694                S3D_SYS_ASSERT(0);
695            }
696        }
697    }
698}
699
700///////////////////////////////////////////////////////////////////////////////
701
702void s3d_CDrvD3d9ProgAsmUtil::CreateShader(
703        s3d_CUtilNotifGather *NotifGather, s3d_CUtilSnkChunk *Param,
704        s3d_CDrvD3d9ProgCtx *ProgCtx, bool VertShader,
705        s3d_CDrvD3d9Prog *Prog,
706        s3d_CDrvD3d9ProgAsmTrackBlk &TrackBlk)
707{
708    if(!ProgCtx)
709        return;
710
711    s3d_CUtilMsgHandler *MsgHandler = ProgCtx->m_MsgHandler;
712
713    s3d_CUtilSnkExtract SnkExtract;
714    SnkExtract.Assign(MsgHandler, Param);
715
716    s3d_CLibStreamPreproStatePtr PreproState
717            = S3D_SYS_NEW s3d_CLibStreamPreproState;
718    s3d_CDrvD3d9ProgAsmUtil::ExtractPredefine(
719            ProgCtx, PreproState, SnkExtract);
720
721    /*@{ @declare{shaderprog.param}
722            {<d3d9_asm_shader>.code_variant_array}{$ [chunk]...[chunk]}
723        Each chunk specifies a D3D assembly shader source code file for a
724        specific shader version.
725        If there is more than one @code{code_variant} the one that first
726        successfully compiles is taken.
727    @}*/
728    s3d_CUtilSnkChunkArray CodeArray;
729    s3d_CUtilStr CodeArrayInfo;
730    SnkExtract.ExtractChunkArray(
731            CodeArrayInfo, CodeArray, "code_variant_array", true);
732
733    s3d_CUtilStr CodeName, CodeInfo;
734    s3d_CSysIntps nCode = CodeArray.GetCnt();
735    s3d_CSysIntps iCode;
736    for(iCode = 0; iCode < nCode; iCode++)
737    {
738        s3d_CUtilSnkExtract CodeSnkExtract;
739        s3d_CUtilSnkChunk *CodeChunk = CodeArray.GetAt(iCode);
740        CodeSnkExtract.Assign(MsgHandler, CodeChunk);
741
742        /*@{ @declare{shaderprog.param}
743                {<d3d9_asm_shader>.code_variant_array.req_ver}{$ [str]}
744            Shader version required to run this shader implementation.
745        @}*/
746        s3d_CUtilStr ReqVer = CodeSnkExtract.ExtractStr("req_ver", false);
747/*
748        if(!s3d_CDrvD3d9ProgUtil::IsVersAllowed(MaxMajor, MaxMinor, ReqVer))
749            continue;
750*/
751        /*@{ @declare{shaderprog.param}
752                {<d3d9_asm_shader>.code_variant_array.code}
753                {$ [str]}
754            Specifies the D3D assembly shader source code file.
755        @}*/
756        CodeSnkExtract.ExtractStr(CodeInfo, CodeName, "code", true);
757
758        /*@{ @declare{shaderprog.param}
759                {<d3d9_asm_shader>.code_variant_array.debug_code_file}
760                {$ [str]}
761            Specifies the shader source file that is used for debugging.
762        @}*/
763        s3d_CUtilStr DbgCodeName
764                = CodeSnkExtract.ExtractStr("debug_code_file", false);
765
766        CodeSnkExtract.CheckForUnknown();
767
768        s3d_CDrvD3d9Buf CodeBuf;
769        if(ProgCtx->m_D3dParam->m_ShaderDebug && !DbgCodeName.IsEmpty())
770        {
771            s3d_CDrvD3d9ProgAsmUtil::AssembleFromFile(
772                    NotifGather, ProgCtx, CodeInfo, DbgCodeName,
773                    PreproState, CodeBuf);
774        }
775        else
776        {
777            s3d_CDrvD3d9ProgAsmUtil::AssembleFromRes(
778                    NotifGather, ProgCtx, CodeInfo, CodeName,
779                    PreproState, CodeBuf);
780        }
781        if(!CodeBuf)
782            continue;
783
784        const DWORD *Function
785                = reinterpret_cast<const DWORD *>(
786                    CodeBuf->GetBufferPointer());
787        DWORD ShaderVers = D3DXGetShaderVersion(Function);
788
789        HRESULT Result = D3DERR_INVALIDCALL;
790        LPDIRECT3DDEVICE9 D3dDev = ProgCtx->m_D3dDev;
791        if(VertShader)
792        {
793            if(ShaderVers <= ProgCtx->m_MaxVS)
794            {
795                S3D_DRV_D3D9_CALLCHECK(
796                        ProgCtx->m_Env, Result, D3dDev->CreateVertexShader(
797                            Function, &Prog->m_VertShader.EmptyRef()));
798            }
799            else
800            {
801                s3d_CUtilMsg m;
802                m.m_Code = "drv/imp/directx/d3d9/drv_d3d9_progasm.vsvers";
803                m.m_StdTempl = "D3D: "
804                        "Asm program '[1]' requires GPU with vertex shader "
805                        "version '[2]' but GPU has only '[3]'.";
806                m.AddInfo(CodeInfo);
807                m.AddInfo(CodeName);
808                m.AddInfo(s3d_CDrvD3d9ProgUtil::StrOfVers(ShaderVers));
809                m.AddInfo(s3d_CDrvD3d9ProgUtil::StrOfVers(ProgCtx->m_MaxVS));
810                s3d_UtilMsgReportNote(ProgCtx->m_MsgHandler, m);
811            }
812        }
813        else
814        {
815            if(ShaderVers <= ProgCtx->m_MaxPS)
816            {
817                S3D_DRV_D3D9_CALLCHECK(
818                        ProgCtx->m_Env, Result, D3dDev->CreatePixelShader(
819                            Function, &Prog->m_PixShader.EmptyRef()));
820            }
821            else
822            {
823                s3d_CUtilMsg m;
824                m.m_Code = "drv/imp/directx/d3d9/drv_d3d9_progasm.psvers";
825                m.m_StdTempl = "D3D: "
826                        "Asm program '[1]' requires GPU with pixel shader "
827                        "version '[2]' but GPU has only '[3]'.";
828                m.AddInfo(CodeInfo);
829                m.AddInfo(CodeName);
830                m.AddInfo(s3d_CDrvD3d9ProgUtil::StrOfVers(ShaderVers));
831                m.AddInfo(s3d_CDrvD3d9ProgUtil::StrOfVers(ProgCtx->m_MaxPS));
832                s3d_UtilMsgReportNote(ProgCtx->m_MsgHandler, m);
833            }
834        }
835
836        if(FAILED(Result))
837            continue;
838
839        if(VertShader)
840        {
841            s3d_CDrvD3d9ProgUtil::GetProgDecl(
842                    ProgCtx, Prog->m_VertProgDecl,
843                    CodeBuf->GetBufferSize(), Function);
844
845            s3d_CDrvD3d9ProgUtil::ExtractComprFmt(
846                    ProgCtx, CodeInfo, CodeName, Prog, SnkExtract);
847        }
848        s3d_CDrvD3d9ProgAsmUtil::InitTrackBlk(
849                    ProgCtx, CodeInfo, CodeName, TrackBlk, SnkExtract);
850
851        SnkExtract.CheckForUnknown();
852       
853        break;
854    }
855}
856
857void s3d_CDrvD3d9ProgAsmUtil::ExtractPredefine(
858        const s3d_CDrvD3d9ProgCtx *ProgCtx,
859        s3d_CLibStreamPreproState *PreproState,
860        s3d_CUtilSnkExtract &SnkExtract)
861{
862    /*@{ @declare{shaderprog.param}{<d3d9_asm_shader>.predefine_array}
863            {$ [chunk]...[chunk]}
864        See @ident{shaderprog}{<d3d9_hlsl_shader>.predefine_array}.
865    @}*/
866    s3d_CUtilSnkChunkArray ChunkArray;
867    SnkExtract.ExtractChunkArray(ChunkArray, "predefine_array", false);
868    int i;
869    for(i = 0; i < ChunkArray.GetCntInt(); i++)
870    {
871        s3d_CUtilSnkExtract SnkExtract;
872        s3d_CUtilSnkChunk *Chunk = ChunkArray.GetAt(i);
873        SnkExtract.Assign(ProgCtx->m_MsgHandler, Chunk);
874        /*@{ @declare{shaderprog.param}
875                {<d3d9_asm_shader>.predefine.name}{$ [str]}
876            See @ident{shaderprog}{<d3d9_hlsl_shader>.predefine_array.name}.
877        @}*/
878        s3d_CUtilStr Name, NameInfo;
879        SnkExtract.ExtractStr(NameInfo, Name, "name", true);
880        /*@{ @declare{shaderprog.param}
881                {<d3d9_asm_shader>.predefine.val}{$ [str]}
882            See @ident{shaderprog}{<d3d9_hlsl_shader>.predefine_array.val}.
883        @}*/
884        s3d_CUtilStr Def = SnkExtract.ExtractStr("val", false);
885
886        PreproState->DefineSimple(ProgCtx->m_MsgHandler, NameInfo, Name, Def);
887        SnkExtract.CheckForUnknown();
888    }
889}
890
891void s3d_CDrvD3d9ProgAsmUtil::ExtractParamArray(
892        const s3d_CDrvD3d9ProgCtx *ProgCtx,
893        s3d_CUtilStr_cr CodeInfo, s3d_CUtilStr_cr CodeName,
894        s3d_CDrvD3d9ProgAsmParamArray &ParamArray,
895        s3d_CUtilSnkExtract &SnkExtract)
896{
897    ParamArray.Reset();
898
899    /*@{ @declare{shaderprog.param}
900            {<d3d9_asm_shader>.param_array}{$ [chunk]...[chunk]}
901        Each entry maps @ident{comp}{<shaderprog.map_prog_array>.dest_progvar}
902        to shader code const address.
903        See also @ident{comp}{<shaderprog.map_prog_array>}.
904        @listing
905        {
906            @sident{shaderprog}{<d3d9_asm_shader>.param_array}
907            {
908                @sident{shaderprog}{<d3d9_asm_shader>.param_array@$
909                            .src_progvar} "prog_cenrange"
910                @sident{shaderprog}{<d3d9_asm_shader>.param_array@$
911                            .dest_codeaddr} 42
912                @sident{shaderprog}{<d3d9_asm_shader>.param_array@$
913                            .type} "float4"
914            }
915        }
916    @}*/
917    s3d_CUtilSnkChunkArray ParamChunkArray;
918    SnkExtract.ExtractChunkArray(ParamChunkArray, "param_array", false);
919    s3d_CSysIntps nParamChunk = ParamChunkArray.GetCnt();
920    s3d_CSysIntps iParamChunk;
921    for(iParamChunk = 0; iParamChunk < nParamChunk; iParamChunk++)
922    {
923        s3d_CUtilSnkExtract SnkExtract;
924        SnkExtract.Assign(ProgCtx->m_MsgHandler, ParamChunkArray[iParamChunk]);
925
926        /*@{ @declare{shaderprog.param}
927                {<d3d9_asm_shader>.param_array.src_progvar}{$ [str]}
928            Shader source variable.
929            See @ident{comp}{<shaderprog.map_prog_array>.dest_progvar}.
930        @}*/
931        s3d_CUtilStr ParamInfo;
932        s3d_CUtilAtomPtr ParamAtom;
933        s3d_CUtilSnkExtractUtil::ExtractAtom(
934                ParamInfo, ParamAtom, ProgCtx->m_AtomMgr,
935                SnkExtract, "src_progvar", true);
936        /*@{ @declare{shaderprog.param}
937                {<d3d9_asm_shader>.param_array.dest_codeaddr}{$ [int]}
938            Shader code destination address.
939        @}*/
940        int ParamDestAddr = SnkExtract.ExtractInt("dest_codeaddr", true, -1);
941
942        /*@{ @declare{shaderprog.param}
943                {<d3d9_asm_shader>.param_array.type}{$ [str]}
944            See @ident{shaderprog}{<d3d9_hlsl_shader>.param_array.type}.
945        @}*/
946        s3d_CUtilStr TypeStr;
947        s3d_CUtilStr TypeInfo;
948        SnkExtract.ExtractStr(TypeInfo, TypeStr, "type", true);
949        s3d_CUtilSnkExtractEnum SnkExtractEnum;
950        SnkExtractEnum.Assign(ProgCtx->m_MsgHandler, TypeInfo, TypeStr);
951        int Type = -1;
952        if(SnkExtractEnum.Check("float4"))
953            Type = s3d_CDrvUtilGfxProg::ParamType_Float4;
954        else if(SnkExtractEnum.Check("float4x4"))
955            Type = s3d_CDrvUtilGfxProg::ParamType_Float4x4;
956        else if(SnkExtractEnum.Check("float4x4_transp"))
957            Type = s3d_CDrvUtilGfxProg::ParamType_Float4x4_Transp;
958        else if(SnkExtractEnum.Check("float4x4_inv"))
959            Type = s3d_CDrvUtilGfxProg::ParamType_Float4x4_Inv;
960        else if(SnkExtractEnum.Check("float4x4_invtransp"))
961            Type = s3d_CDrvUtilGfxProg::ParamType_Float4x4_InvTransp;
962        else
963            SnkExtractEnum.ErrorUnknown();
964
965        SnkExtract.CheckForUnknown();
966
967        s3d_CDrvD3d9ProgAsmParam Param;
968        Param.m_Info = ParamInfo;
969        Param.m_Addr = ParamDestAddr;
970        Param.m_Type = Type;
971        ParamArray.InsertBack(s3d_CDrvD3d9ProgAsmParamEntry(ParamAtom, Param));
972    }
973
974    s3d_UtilArraySortDefault(ParamArray);
975   
976    ParamArray.Compactify();
977}
978
979void s3d_CDrvD3d9ProgAsmUtil::ExtractTexSize(
980        const s3d_CDrvD3d9ProgCtx *ProgCtx,
981        s3d_CUtilStr_cr CodeInfo, s3d_CUtilStr_cr CodeName,
982        s3d_CDrvD3d9ProgAsmAddrArray &TexSizeAddrArray,
983        s3d_CDrvD3d9ProgAsmAddrArray &TexRcpSizeAddrArray,
984        s3d_CUtilSnkExtract &SnkExtract)
985{
986    TexSizeAddrArray.Reset();
987    TexRcpSizeAddrArray.Reset();
988
989    /*@{ @declare{shaderprog.param}
990            {<d3d9_asm_shader>.tex_size_codeaddr_array}{$ [int]...[int]}
991        Array of shader code const addresses to upload texture dimensions to.
992        @table
993        {
994            { @code{texsize_codeaddr.x} } { Width }
995        }                                                   
996        {
997            { @code{texsize_codeaddr.y} } { Height }
998        }                                                   
999        {
1000            { @code{texsize_codeaddr.z} } { Depth }
1001        }
1002        {
1003            { @code{texsize_codeaddr.w} } { <undefined> }
1004        }
1005        For example:
1006        @listing
1007        {
1008            @sident{shaderprog}{<d3d9_asm_shader>@$
1009                .tex_size_codeaddr_array} 20 -1 40
1010        }
1011        Uploads size of texture currently bound to sampler 0 and 2, @it{-1}
1012        disables upload of texture bound to sampler 1.
1013
1014    @}*/
1015    s3d_CUtilStr TexSizeAddrArrayInfo;
1016    SnkExtract.ExtractIntArray(
1017            TexSizeAddrArrayInfo, TexSizeAddrArray,
1018            "tex_size_codeaddr_array", false);
1019    /*@{ @declare{shaderprog.param}
1020            {<d3d9_asm_shader>.tex_rcpsize_codeaddr_array}{$ [int]...[int]}
1021        Array of shader code const addresses to upload reciprocal texture
1022        dimensions to.
1023        See also
1024            @ident{shaderprog}{<d3d9_asm_shader>.tex_size_codeaddr_array}.
1025    @}*/
1026    s3d_CUtilStr TexRcpSizeAddrArrayInfo;
1027    SnkExtract.ExtractIntArray(
1028            TexRcpSizeAddrArrayInfo, TexRcpSizeAddrArray,
1029            "tex_rcpsize_codeaddr_array", false);
1030
1031    s3d_CSysIntps nTexSize = TexSizeAddrArray.GetCnt();
1032    if(nTexSize >= ProgCtx->m_MaxSampCnt)
1033    {
1034        s3d_CDrvDxError e;
1035        e.m_Code =
1036                "drv/imp/directx/d3d9/drv_d3d9_progasm.invalid_tex_size_cnt.";
1037        e.m_StdTempl = "Too many ASM tex_size_codeaddr_array entries '[1]'."
1038                " Must be less than or equal to [2].";
1039        e.AddInfo(TexSizeAddrArrayInfo);
1040        e.AddInfo(s3d_CUtilStrUtil::StrOfInt(nTexSize));
1041        e.AddInfo(s3d_CUtilStrUtil::StrOfInt(ProgCtx->m_MaxSampCnt));
1042        s3d_UtilMsgReportError(ProgCtx->m_MsgHandler, e);
1043    }
1044    s3d_CSysIntps nRcpTexSize = TexRcpSizeAddrArray.GetCnt();
1045    if(nRcpTexSize >= ProgCtx->m_MaxSampCnt)
1046    {
1047        s3d_CDrvDxError e;
1048        e.m_Code =
1049                "drv/imp/directx/d3d9/drv_d3d9_progasm"
1050                ".invalid_rcptex_size_cnt.";
1051        e.m_StdTempl = "Too many ASM tex_rcpsize_codeaddr_array entries '[1]'."
1052                " Must be less than or equal to [2].";
1053        e.AddInfo(TexRcpSizeAddrArrayInfo);
1054        e.AddInfo(s3d_CUtilStrUtil::StrOfInt(nRcpTexSize));
1055        e.AddInfo(s3d_CUtilStrUtil::StrOfInt(ProgCtx->m_MaxSampCnt));
1056        s3d_UtilMsgReportError(ProgCtx->m_MsgHandler, e);
1057    }
1058
1059    TexSizeAddrArray.Compactify();
1060    TexRcpSizeAddrArray.Compactify();
1061}
1062
1063void s3d_CDrvD3d9ProgAsmUtil::ExtractTrackArray(
1064        const s3d_CDrvD3d9ProgCtx *ProgCtx,
1065        s3d_CUtilStr_cr CodeInfo, s3d_CUtilStr_cr CodeName,
1066        s3d_CDrvD3d9ProgAsmTrackMatArray &MatTrackArray,
1067        s3d_CDrvD3d9ProgAsmTrackMatArray &BoneTrackArray,
1068        s3d_CUtilSnkExtract &SnkExtract)
1069{
1070    /*@{ @declare{shaderprog.param}
1071            {<d3d9_asm_shader>.tracking}{$ [chunk]...[chunk]}
1072        Track matrices to shader code const addresses.
1073        @listing
1074        {
1075            @sident{shaderprog}{<d3d9_asm_shader>.tracking}
1076            {
1077                @sident{shaderprog}{<d3d9_asm_shader>.tracking@$
1078                    .codeaddr} 0
1079                @sident{shaderprog}{<d3d9_asm_shader>.tracking@$
1080                    .cnt} 1
1081                @sident{shaderprog}{<d3d9_asm_shader>.tracking@$
1082                    .slot} 0
1083                @sident{shaderprog}{<d3d9_asm_shader>.tracking@$
1084                    .chan} "proj"
1085                @sident{shaderprog}{<d3d9_asm_shader>.tracking@$
1086                    .trans} "identity"
1087            }
1088        }
1089        One matrix needs 4 constants.
1090    @}*/
1091    s3d_CUtilSnkChunkArray TrackArray;
1092    s3d_CUtilStr TrackInfo;
1093    SnkExtract.ExtractChunkArray(
1094            TrackInfo, TrackArray, "tracking", false);
1095
1096    MatTrackArray.Reset();
1097    BoneTrackArray.Reset();
1098
1099    int iTrack;
1100    for(iTrack = 0; iTrack < TrackArray.GetCnt(); iTrack++)
1101    {
1102        s3d_CUtilSnkChunk *TrackChunk = TrackArray.GetAt(iTrack);
1103        s3d_CUtilSnkExtractEnum SnkExtractEnum;
1104        s3d_CUtilSnkExtract SnkExtract;
1105        SnkExtract.Assign(ProgCtx->m_MsgHandler, TrackChunk);
1106
1107        s3d_CDrvD3d9ProgAsmTrackMat Track;
1108
1109        /*@{ @declare{shaderprog.param}
1110                {<d3d9_asm_shader>.tracking.chan}{$ [str]}
1111            See @ident{shaderprog}{<d3d9_hlsl_shader>.tracking.chan}.
1112        @}*/
1113        s3d_CUtilStr ChanName, ChanInfo;
1114        SnkExtract.ExtractStr(ChanInfo, ChanName, "chan", true, "");
1115        SnkExtractEnum.Assign(ProgCtx->m_MsgHandler, ChanInfo, ChanName);
1116        Track.m_Chan = s3d_CDrvUtilGfxProg::TrackChan_Identity;
1117        if(SnkExtractEnum.Check("view"))
1118            Track.m_Chan = s3d_CDrvUtilGfxProg::TrackChan_View;
1119        else if(SnkExtractEnum.Check("proj"))
1120            Track.m_Chan = s3d_CDrvUtilGfxProg::TrackChan_Proj;
1121        else if(SnkExtractEnum.Check("projview"))
1122            Track.m_Chan = s3d_CDrvUtilGfxProg::TrackChan_ProjView;
1123        else if(SnkExtractEnum.Check("identity"))
1124            Track.m_Chan = s3d_CDrvUtilGfxProg::TrackChan_Identity;
1125        else if(SnkExtractEnum.Check("attr"))
1126            Track.m_Chan = s3d_CDrvUtilGfxProg::TrackChan_Attr;
1127        else if(SnkExtractEnum.Check("bone"))
1128            Track.m_Chan = s3d_CDrvUtilGfxProg::TrackChan_Bone;
1129        else
1130            SnkExtractEnum.ErrorUnknown();
1131
1132        /*@{ @declare{shaderprog.param}
1133                {<d3d9_asm_shader>.tracking.slot}{$ [int]}
1134            See @ident{shaderprog}{<d3d9_hlsl_shader>.tracking.slot}.
1135        @}*/
1136        s3d_CUtilStr TrackSlotInfo;
1137        SnkExtract.ExtractInt(TrackSlotInfo, Track.m_Slot, "slot", true, 0);
1138        if(Track.m_Slot < 0 || Track.m_Slot >= ProgCtx->m_MaxAttrCnt)
1139        {
1140            s3d_CDrvDxError e;
1141            e.m_Code = "drv/imp/directx/d3d9/drv_d3d9_progasm.invalid_slot.";
1142            e.m_StdTempl = "Invalid ASM tracking slot value '[1]'. "
1143                "Must be greater or equal 0 and less than [2].";
1144            e.AddInfo(TrackSlotInfo);
1145            e.AddInfo(s3d_CUtilStrUtil::StrOfInt(Track.m_Slot));
1146            e.AddInfo(s3d_CUtilStrUtil::StrOfInt(ProgCtx->m_MaxAttrCnt));
1147            s3d_UtilMsgReportError(ProgCtx->m_MsgHandler, e);
1148           
1149            Track.m_Slot = 0;
1150        }
1151
1152        /*@{ @declare{shaderprog.param}
1153                {<d3d9_asm_shader>.tracking.cnt}{$ [int]}
1154        @}*/
1155        Track.m_Cnt = SnkExtract.ExtractInt("cnt", true, 1);
1156        if(Track.m_Cnt < 0)
1157            Track.m_Cnt = 0;
1158
1159        /*@{ @declare{shaderprog.param}
1160                {<d3d9_asm_shader>.tracking.trans}{$ [str]}
1161            See @ident{shaderprog}{<d3d9_hlsl_shader>.tracking.trans}.
1162        @}*/
1163        s3d_CUtilStr TransName, TransInfo;
1164        SnkExtract.ExtractStr(TransInfo, TransName, "trans", true, "");
1165
1166        SnkExtractEnum.Assign(
1167                ProgCtx->m_MsgHandler, TransInfo, TransName);
1168        if(SnkExtractEnum.Check("identity"))
1169            Track.m_Trans = s3d_CDrvUtilGfxProg::TrackTrans_Identity;
1170        else if(SnkExtractEnum.Check("inv"))
1171            Track.m_Trans = s3d_CDrvUtilGfxProg::TrackTrans_Inv;
1172        else if(SnkExtractEnum.Check("transp"))
1173            Track.m_Trans = s3d_CDrvUtilGfxProg::TrackTrans_Transp;
1174        else if(SnkExtractEnum.Check("invtransp"))
1175            Track.m_Trans = s3d_CDrvUtilGfxProg::TrackTrans_InvTransp;
1176        else
1177        {
1178            Track.m_Trans = s3d_CDrvUtilGfxProg::TrackTrans_Identity;
1179            SnkExtractEnum.ErrorUnknown();
1180        }
1181
1182        /*@{ @declare{shaderprog.param}
1183                {<d3d9_asm_shader>.tracking.codeaddr}{$ [int]}
1184            Shader constant register address where matrix is uploaded to.
1185        @}*/
1186        Track.m_Addr = SnkExtract.ExtractInt("codeaddr", true, -1);
1187        if(Track.m_Addr >= 0)
1188        {
1189            if(Track.m_Chan == s3d_CDrvUtilGfxProg::TrackChan_Bone)
1190                BoneTrackArray.InsertBack(Track);
1191            else
1192                MatTrackArray.InsertBack(Track);
1193        }
1194
1195        SnkExtract.CheckForUnknown();
1196    }
1197   
1198    MatTrackArray.Compactify();
1199    BoneTrackArray.Compactify();
1200}
1201
1202
1203void s3d_CDrvD3d9ProgAsmUtil::ExtractLightArray(
1204        const s3d_CDrvD3d9ProgCtx *ProgCtx,
1205        s3d_CUtilStr_cr CodeInfo, s3d_CUtilStr_cr CodeName,
1206        int &ActiveLightCntAddr, s3d_CDrvD3d9ProgAsmLightArray
1207                &LightTrackArray,
1208        s3d_CUtilSnkExtract &SnkExtract)
1209{
1210    /*@{ @declare{shaderprog.param}
1211            {<d3d9_asm_shader>.light_array}{$ [chunk]...[chunk]}
1212        Specifies how many lights a shader can handle and the shader code
1213        const address where to upload light values.
1214        @listing
1215        {
1216            @sident{shaderprog}{<d3d9_asm_shader>.light_array}
1217            {
1218                @sident{shaderprog}{<d3d9_asm_shader>.light_array@$
1219                    .cnt} 2
1220                @sident{shaderprog}{<d3d9_asm_shader>.light_array@$
1221                    .stride} 5
1222                @sident{shaderprog}{<d3d9_asm_shader>.light_array@$
1223                    .pos_codeaddr} 20
1224                @sident{shaderprog}{<d3d9_asm_shader>.light_array@$
1225                    .dir_codeaddr} -1
1226                @sident{shaderprog}{<d3d9_asm_shader>.light_array@$
1227                    .ambient_codeaddr} 21
1228                @sident{shaderprog}{<d3d9_asm_shader>.light_array@$
1229                    .diffuse_codeaddr} 22
1230                @sident{shaderprog}{<d3d9_asm_shader>.light_array@$
1231                    .specular_codeaddr} 23
1232                @sident{shaderprog}{<d3d9_asm_shader>.light_array@$
1233                    .atten_codeaddr} 24
1234            }
1235        }
1236        In this example first light position will be uploaded to address
1237        @it{20}, direction will be skipped, ambient color to address @it{21}
1238        and so on. Second light position will be uploaded to address @it{25}
1239        ( pos_codeaddr + stride * index ), etc.
1240    @}*/
1241    s3d_CUtilSnkChunkPtr LightChunk;
1242    s3d_CUtilStr LightInfo;
1243    SnkExtract.ExtractChunk(
1244            LightInfo, LightChunk, "light_array", false);
1245
1246    /*@{ @declare{shaderprog.param}
1247            {<d3d9_asm_shader>.light_activecnt_codeaddr}{$ [int]}
1248          In D3D shader version >= 2.0. this address is used for uploading
1249          the active light cnt.
1250    @}*/
1251    ActiveLightCntAddr
1252            = SnkExtract.ExtractInt("light_activecnt_codeaddr", false, -1);
1253   
1254    LightTrackArray.Reset();
1255    if(!LightChunk)
1256        return;
1257
1258    s3d_CUtilSnkExtract SnkLightExtract;
1259    SnkLightExtract.Assign(ProgCtx->m_MsgHandler, LightChunk);
1260
1261    /*@{ @declare{shaderprog.param}
1262            {<d3d9_asm_shader>.light_array.cnt}{$ [int]}
1263        Number of lights supported by this shader program.
1264    @}*/
1265    s3d_CUtilStr LightCntInfo;
1266    int LightCnt = SnkLightExtract.ExtractInt("cnt", true);
1267    if(LightCnt > ProgCtx->m_MaxLightCnt)
1268    {
1269        s3d_CDrvDxError e;
1270        e.m_Code = "drv/imp/directx/d3d9/drv_d3d9_progasm.invalid_lightcnt.";
1271        e.m_StdTempl = "Invalid ASM tracking light count value '[1]'. "
1272            "Must be greater or equal 0 and less than [2].";
1273        e.AddInfo(LightCntInfo);
1274        e.AddInfo(s3d_CUtilStrUtil::StrOfInt(LightCnt));
1275        e.AddInfo(s3d_CUtilStrUtil::StrOfInt(ProgCtx->m_MaxLightCnt));
1276        s3d_UtilMsgReportError(ProgCtx->m_MsgHandler, e);
1277
1278        LightCnt = ProgCtx->m_MaxLightCnt;
1279    }
1280
1281
1282    /*@{ @declare{shaderprog.param}
1283            {<d3d9_asm_shader>.light_array.stride}{$ [int]}
1284        Stride of each light component.
1285        @listing
1286        {
1287            light[n].comp_codeaddr = comp_codeaddr + stride * n
1288            n := [0..cnt]
1289        }
1290    @}*/
1291    int Stride = SnkLightExtract.ExtractInt("stride", true);
1292
1293    /*@{ @declare{shaderprog.param}
1294            {<d3d9_asm_shader>.light_array.pos_codeaddr}{$ [int]}
1295        Light position (in viewspace) shader code const address.
1296    @}*/
1297    int PosAddr = SnkLightExtract.ExtractInt("pos_codeaddr", true, -1);
1298
1299    /*@{ @declare{shaderprog.param}
1300            {<d3d9_asm_shader>.light_array.dir_codeaddr}{$ [int]}
1301        Light direction (in viewspace) shader code const address.
1302    @}*/
1303    int DirAddr = SnkLightExtract.ExtractInt("dir_codeaddr", true, -1);
1304
1305    /*@{ @declare{shaderprog.param}
1306            {<d3d9_asm_shader>.light_array.ambient_codeaddr}{$ [int]}
1307        Light ambient color shader code const address.
1308    @}*/
1309    int AmbientAddr = SnkLightExtract.ExtractInt("ambient_codeaddr", true, -1);
1310
1311    /*@{ @declare{shaderprog.param}
1312            {<d3d9_asm_shader>.light_array.diffuse_codeaddr}{$ [int]}
1313        Light diffuse color shader code const address.
1314    @}*/
1315    int DiffuseAddr = SnkLightExtract.ExtractInt("diffuse_codeaddr", true, -1);
1316
1317    /*@{ @declare{shaderprog.param}
1318            {<d3d9_asm_shader>.light_array.specular_codeaddr}{$ [int]}
1319        Light specular color shader code const address.
1320    @}*/
1321    int SpecularAddr = SnkLightExtract.ExtractInt(
1322            "specular_codeaddr", true, -1);
1323
1324    /*@{ @declare{shaderprog.param}
1325            {<d3d9_asm_shader>.light_array.atten_codeaddr}{$ [int]}
1326        Light attenuation shader code const address.
1327        @table
1328        {
1329            { @code{atten_codeaddr.x} } { AttenConst }
1330        }
1331        {
1332            { @code{atten_codeaddr.y} } { AttenLinear }
1333        }
1334        {
1335            { @code{atten_codeaddr.z} } { AttenQuadr }
1336        }
1337        {
1338            { @code{atten_codeaddr.w} } { Range }
1339        }
1340    @}*/
1341    int AttenAddr = SnkLightExtract.ExtractInt("atten_codeaddr", true, -1);
1342
1343    SnkLightExtract.CheckForUnknown();
1344    int iLightParam;
1345    for(iLightParam = 0; iLightParam < LightCnt; iLightParam++)
1346    {
1347        s3d_CDrvD3d9ProgAsmLight Light;
1348        int LightOffs = Stride * iLightParam;
1349        if(PosAddr >= 0)
1350            Light.m_PosAddr = PosAddr + LightOffs;
1351        if(DirAddr >= 0)
1352            Light.m_DirAddr = DirAddr + LightOffs;
1353        if(AmbientAddr >= 0)
1354            Light.m_AmbientAddr = AmbientAddr + LightOffs;
1355        if(DiffuseAddr >= 0)
1356            Light.m_DiffuseAddr = DiffuseAddr + LightOffs;
1357        if(SpecularAddr >= 0)
1358            Light.m_SpecularAddr = SpecularAddr + LightOffs;
1359        if(AttenAddr >= 0)
1360            Light.m_AttenAddr = AttenAddr + LightOffs;
1361
1362        LightTrackArray.InsertBack(Light);
1363    }
1364
1365    LightTrackArray.Compactify();
1366}
1367
1368void s3d_CDrvD3d9ProgAsmUtil::ExtractMtl(
1369        const s3d_CDrvD3d9ProgCtx *ProgCtx,
1370        s3d_CUtilStr_cr CodeInfo, s3d_CUtilStr_cr CodeName,
1371        s3d_CDrvD3d9ProgAsmTrackMtrl &Mtl,
1372        s3d_CUtilSnkExtract &SnkExtract)
1373{
1374    /*@{ @declare{shaderprog.param}
1375            {<d3d9_asm_shader>.mtl}{$ [chunk]}
1376    @}*/
1377    s3d_CUtilSnkChunkPtr MtlChunk;
1378    MtlChunk = SnkExtract.ExtractChunk("mtl", false);
1379
1380    s3d_CUtilSnkExtract MtrlSnkExtract;
1381    MtrlSnkExtract.Assign(ProgCtx->m_MsgHandler, MtlChunk);
1382
1383    /*@{ @declare{shaderprog.param}
1384            {<d3d9_asm_shader>.mtl.power_codeaddr}{$ [int]}
1385        Mtl power shader const address.
1386        @table
1387        {
1388            { @code{power_codeaddr.x} } { MtlPower }
1389        }
1390        {
1391            { @code{power_codeaddr.y} } { MtlPower }
1392        }
1393        {
1394            { @code{power_codeaddr.z} } { MtlPower }
1395        }
1396        {
1397            { @code{power_codeaddr.w} } { MtlPower }
1398        }
1399    @}*/
1400    Mtl.m_PowerAddr
1401            = MtrlSnkExtract.ExtractInt("power_codeaddr", false, -1);
1402
1403    /*@{ @declare{shaderprog.param}
1404            {<d3d9_asm_shader>.mtl.emissive_codeaddr}{$ [int]}
1405        Mtl emissive shader const address.
1406        @table
1407        {
1408            { @code{emissive_codeaddr.x} } { MtlEmissive.r }
1409        }                                                   
1410        {                                                   
1411            { @code{emissive_codeaddr.y} } { MtlEmissive.g }
1412        }                                                   
1413        {                                                   
1414            { @code{emissive_codeaddr.z} } { MtlEmissive.b }
1415        }                                                   
1416        {                                                   
1417            { @code{emissive_codeaddr.w} } { MtlEmissive.a }
1418        }
1419    @}*/
1420    Mtl.m_EmissiveAddr
1421            = MtrlSnkExtract.ExtractInt("emissive_codeaddr", false, -1);
1422
1423    MtrlSnkExtract.CheckForUnknown();
1424}
1425
1426void s3d_CDrvD3d9ProgAsmUtil::ExtractFog(
1427        const s3d_CDrvD3d9ProgCtx *ProgCtx,
1428        s3d_CUtilStr_cr CodeInfo, s3d_CUtilStr_cr CodeName,
1429        int &FogAddr,
1430        s3d_CUtilSnkExtract &SnkExtract)
1431{
1432    /*@{ @declare{shaderprog.param}
1433            {<d3d9_asm_shader>.fog_codeaddr}{$ [int]}
1434        Fog color and denisity shader const address.
1435        @table
1436        {
1437            { @code{fog_codeaddr.x} } { FogColor.r }
1438        }                                                   
1439        {                                                   
1440            { @code{fog_codeaddr.y} } { FogColor.g }
1441        }                                                   
1442        {                                                   
1443            { @code{fog_codeaddr.z} } { FogColor.b }
1444        }                                                   
1445        {                                                   
1446            { @code{fog_codeaddr.w} } { FogDensity }
1447        }
1448    @}*/
1449    FogAddr = SnkExtract.ExtractInt("fog_codeaddr", false, -1);
1450}
1451
1452
1453void s3d_CDrvD3d9ProgAsmUtil::InitTrackBlk(
1454        const s3d_CDrvD3d9ProgCtx *ProgCtx,
1455        s3d_CUtilStr_cr CodeInfo, s3d_CUtilStr_cr CodeName,
1456        s3d_CDrvD3d9ProgAsmTrackBlk &TrackBlk,
1457        s3d_CUtilSnkExtract &SnkExtract)
1458{
1459    TrackBlk.m_CodeInfo = CodeInfo;
1460    TrackBlk.m_CodeName = CodeName;
1461
1462    s3d_CDrvD3d9ProgAsmUtil::ExtractParamArray(
1463            ProgCtx, CodeInfo, CodeName,
1464            TrackBlk.m_ParamArray, SnkExtract);
1465    s3d_CDrvD3d9ProgAsmUtil::ExtractTexSize(
1466            ProgCtx, CodeInfo, CodeName,
1467            TrackBlk.m_TexSizeArray, TrackBlk.m_TexRcpSizeArray,
1468            SnkExtract);
1469    s3d_CDrvD3d9ProgAsmUtil::ExtractTrackArray(
1470            ProgCtx, CodeInfo, CodeName,
1471            TrackBlk.m_MatTrackArray, TrackBlk.m_BoneTrackArray,
1472            SnkExtract);
1473    s3d_CDrvD3d9ProgAsmUtil::ExtractLightArray(
1474            ProgCtx, CodeInfo, CodeName,
1475            TrackBlk.m_ActiveLightCntAddr, TrackBlk.m_LightTrackArray,
1476            SnkExtract);
1477    s3d_CDrvD3d9ProgAsmUtil::ExtractMtl(
1478            ProgCtx, CodeInfo, CodeName,
1479            TrackBlk.m_Mtl, SnkExtract);
1480    s3d_CDrvD3d9ProgAsmUtil::ExtractFog(
1481            ProgCtx, CodeInfo, CodeName,
1482            TrackBlk.m_FogAddr, SnkExtract);
1483}
1484
1485bool s3d_CDrvD3d9ProgAsmUtil::AssembleFromRes(
1486        s3d_CUtilNotifGather *NotifGather,
1487        const s3d_CDrvD3d9ProgCtx *ProgCtx,
1488        s3d_CUtilStr_cr CodeInfo, s3d_CUtilStr_cr CodeName,
1489        s3d_CLibStreamPreproState *PreproState, s3d_CDrvD3d9Buf &CodeBuf)
1490{
1491    if(!ProgCtx)
1492        return false;
1493
1494    s3d_CUtilMsgHandler *MsgHandler = ProgCtx->m_MsgHandler;
1495    s3d_CCompResMgr *ResMgr = ProgCtx->m_ResMgr;
1496    s3d_CUtilMemPool *MemPool = ProgCtx->m_MemPool;
1497    s3d_CUtilMemPoolFrm MemPoolFrm(MemPool);
1498
1499    int Generosity = s3d_CCompResMgr::Generosity_AllowMissing;
1500    s3d_CUtilStr ResInfo;
1501    s3d_CUtilStreamPtr ResStream;
1502    bool Final = false;
1503    s3d_CUtilNotifEntryPtr NotifEntry = S3D_SYS_NEW s3d_CUtilNotifEntry;
1504    ResMgr->GetResource(
1505            CodeInfo, CodeName, true, Generosity,
1506            ResInfo, ResStream, Final, NotifEntry);
1507    if(NotifGather)
1508        NotifGather->AddNotifEntry(NotifEntry);
1509    if(!ResStream)
1510        return false;
1511
1512    s3d_CUtilStreamPos ResSize = ResStream->GetSize();
1513    if(ResSize == 0)
1514        return false;
1515
1516    UINT D3dStreamLen = UINT(ResSize);
1517    s3d_CSysIntm *ResData = new(MemPool) s3d_CSysIntm[D3dStreamLen + 1];
1518    ResStream->Read(D3dStreamLen, ResData);
1519    ResData[ResSize] = 0;
1520
1521    if(s3d_CDrvD3d9ProgUtil::CreateCodeBufOfBinData(
1522            ProgCtx, CodeBuf, D3dStreamLen, ResData))
1523        return true;
1524
1525    s3d_CUtilMap<s3d_CUtilStr, s3d_CUtilStr> StreamNameMap;
1526    // Errors contain no filename for the main file:
1527    StreamNameMap.SetAt("", ResInfo);
1528
1529    s3d_CDrvD3d9ProgIncMgr ProgIncMgr(
1530            MsgHandler, CodeInfo, MemPool, ResMgr,
1531            NotifGather, &StreamNameMap);
1532
1533    s3d_CUtilOwnArray<D3DXMACRO> D3dMacroArray;
1534    s3d_CDrvD3d9ProgUtil::D3dMarcoArrayOfPreprocArray(
1535            D3dMacroArray, PreproState);
1536
1537    s3d_CDrvD3d9Buf ErrBuf;
1538    const char *D3dStream = reinterpret_cast<char*>(ResData);
1539    DWORD Flags = 0;
1540    int DxResult = D3DXAssembleShader(
1541            D3dStream, D3dStreamLen, D3dMacroArray.Get(), &ProgIncMgr,
1542            Flags, &CodeBuf.EmptyRef(), &ErrBuf.EmptyRef());
1543
1544    // ErrBuf can be valid even if assembling was successful, e.g. warnings.
1545    s3d_CDrvD3d9ProgReportMap Report(0, 0, &StreamNameMap);
1546    if(!Report.ReportCompilingBuffer(
1547            ProgCtx->m_Env, CodeInfo, ErrBuf, DxResult))
1548        return false;
1549
1550    return true;
1551}
1552
1553bool s3d_CDrvD3d9ProgAsmUtil::AssembleFromFile(
1554        s3d_CUtilNotifGather *NotifGather, const s3d_CDrvD3d9ProgCtx
1555                *ProgCtx,
1556        s3d_CUtilStr_cr CodeInfo, s3d_CUtilStr_cr CodeName,
1557        s3d_CLibStreamPreproState *PreproState, s3d_CDrvD3d9Buf &CodeBuf)
1558{
1559    if(!ProgCtx)
1560        return false;
1561
1562    s3d_CUtilMsgHandler *MsgHandler = ProgCtx->m_MsgHandler;
1563    s3d_CCompResMgr *ResMgr = ProgCtx->m_ResMgr;
1564    s3d_CUtilMemPool *MemPool = ProgCtx->m_MemPool;
1565
1566    s3d_CUtilMap<s3d_CUtilStr, s3d_CUtilStr> StreamNameMap;
1567    // Errors contain no filename for the main file:
1568    StreamNameMap.SetAt("", CodeName);
1569
1570    s3d_CDrvD3d9Buf ErrBuf;
1571    int DxResult = 0;
1572    // Own scope for MemPoolFrm, used by ProgIncMgr
1573    {
1574        s3d_CUtilMemPoolFrm MemPoolFrm(MemPool);
1575
1576        s3d_CDrvD3d9ProgIncMgr ProgIncMgr(
1577                MsgHandler, CodeInfo, MemPool, ResMgr,
1578                NotifGather, &StreamNameMap);
1579
1580        s3d_CUtilOwnArray<D3DXMACRO> D3dMacroArray;
1581        s3d_CDrvD3d9ProgUtil::D3dMarcoArrayOfPreprocArray(
1582                D3dMacroArray, PreproState);
1583
1584        DWORD Flags = D3DXSHADER_DEBUG;
1585        DxResult = D3DXAssembleShaderFromFile(
1586                CodeName.GetChars(), D3dMacroArray.Get(), &ProgIncMgr,
1587                Flags, &CodeBuf.EmptyRef(), &ErrBuf.EmptyRef());
1588    }
1589
1590    // ErrBuf can be valid even if assembling was successful, e.g. warnings.
1591    s3d_CDrvD3d9ProgReportMap Report(0, 0, &StreamNameMap);
1592    if(!Report.ReportCompilingBuffer(
1593            ProgCtx->m_Env, CodeInfo, ErrBuf, DxResult))
1594        return false;
1595
1596    return true;
1597}
1598///////////////////////////////////////////////////////////////////////////////
Note: See TracBrowser for help on using the repository browser.