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

Revision 2236, 43.7 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_tex.h"
17#include "drv_d3d9_util.h"
18#include "drv/util/drv_util_gfxutil.h"
19#include "util/stream/util_streambin.h"
20#include "sys/core/sys_util.h"
21
22///////////////////////////////////////////////////////////////////////////////
23
24S3D_UTIL_RECOG_DEFINEINFO(s3d_CDrvD3d9TexObjBase);
25
26s3d_CDrvD3d9TexObjBase::s3d_CDrvD3d9TexObjBase()
27{
28    S3D_UTIL_RECOG_INITOBJ(s3d_CDrvD3d9TexObjBase);
29    m_Node.m_Data = this;
30}
31
32s3d_CDrvD3d9TexObjBase::~s3d_CDrvD3d9TexObjBase()
33{
34    s3d_CDrvD3d9Param *D3dParam = 0;
35    if(m_D3dCtx)
36        D3dParam = m_D3dCtx->m_D3dParam;
37    if(D3dParam && D3dParam->m_ReportTex)
38    {
39        s3d_CUtilMsg m;
40        m.m_Code = "drv/imp/directx/d3d9/drv_d3d9_tex.report_tex_destroy";
41        m.m_StdTempl = "D3D: "
42                "Destroying texture Addr=[1]. ";
43        m.AddInfo("");
44        m.AddInfo(s3d_CUtilStrUtil::StrOfPtr(this));
45        s3d_UtilMsgReportNote(m_D3dCtx->m_MsgHandler, m);
46    }
47    m_Node.Extract();
48}
49
50void s3d_CDrvD3d9TexObjBase::LoadData(
51        int Part, int Mipmap,
52        int Width, int Height, int Depth,
53        const s3d_CDrvGfxPixel *Data)
54{
55    if(!Data)
56        return;
57    if(!m_BaseTex)
58        return;
59
60    D3DFORMAT FmtCol = s3d_CDrvD3d9Util::LinearFmtOfSwizzledFmt(
61            m_TexFmt.m_FmtCol);
62    if(FmtCol != D3DFMT_X8R8G8B8 && FmtCol != D3DFMT_A8R8G8B8)
63    {
64        s3d_CDrvD3d9Device D3dDev;
65        S3D_DRV_D3D9_CHECK(
66                m_D3dCtx->m_Env, m_BaseTex->GetDevice(&D3dDev.EmptyRef()));
67        if(!D3dDev)
68            return;
69
70        s3d_CDrvD3d9Surf TmpSurf;
71        S3D_DRV_D3D9_CHECK(
72                m_D3dCtx->m_Env, D3dDev->CreateOffscreenPlainSurface(
73                    Width, Height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH,
74                    &TmpSurf.EmptyRef(), 0));
75        if(!TmpSurf)
76            return;
77
78        DWORD Flags = 0;
79        D3DLOCKED_RECT LockRect;
80        S3D_DRV_D3D9_CHECK(
81                m_D3dCtx->m_Env, TmpSurf->LockRect(&LockRect, 0, Flags));
82        s3d_CSysIntm *DestData
83                = reinterpret_cast<s3d_CSysIntm *>(LockRect.pBits);
84        if(!DestData)
85            return;
86        s3d_CSysIntps Stride = LockRect.Pitch;
87
88        s3d_CDrvD3d9TexMgr::CopyTexData2D(
89                DestData, Stride, Width, Height, Data);
90        S3D_DRV_D3D9_CHECK(
91                m_D3dCtx->m_Env, TmpSurf->UnlockRect());
92
93        S3D_DRV_D3D9_CHECK(
94                m_D3dCtx->m_Env, D3dLoadData(
95                    Part, Mipmap, Width, Height, Depth, TmpSurf));
96    }
97    else
98    {
99        S3D_DRV_D3D9_CHECK(
100                m_D3dCtx->m_Env, D3dLoadData(
101                    Part, Mipmap, Width, Height, Depth, Data));
102    }
103
104    if((m_Prop & s3d_CDrvGfxEng::TexProp_Mipmap) != 0
105        && (m_Prop & s3d_CDrvGfxEng::TexProp_RestrUsage) == 0)
106    {
107        if(m_TexFmt.m_FilterMipGen != D3DTEXF_NONE)
108        {
109            S3D_DRV_D3D9_CHECK(
110                    m_D3dCtx->m_Env, m_BaseTex->SetAutoGenFilterType(
111                        m_TexFmt.m_FilterMipGen));
112            m_BaseTex->GenerateMipSubLevels();
113        }
114        else if(m_Pool != D3DPOOL_DEFAULT
115                || (m_TexFmt.m_Usage & D3DUSAGE_DYNAMIC) != 0)
116        {
117            // Textures created in the default pool (
118            // D3DPOOL_DEFAULT) cannot be
119            // used with D3DXFilterTexture (
120            // unless created with D3DUSAGE_DYNAMIC)           
121            int MipLevel = Mipmap - 1;
122            if(MipLevel < 0)
123                MipLevel = 0;
124            PALETTEENTRY *Palette = 0;
125            S3D_DRV_D3D9_CHECK(
126                    m_D3dCtx->m_Env, D3DXFilterTexture(
127                        m_BaseTex, Palette, MipLevel, D3DX_FILTER_LINEAR));
128        }
129    }
130
131    if(m_D3dCtx->m_D3dParam->m_PreloadResources && m_Pool == D3DPOOL_MANAGED)
132    {
133        S3D_DRV_D3D9_CALL(m_D3dCtx->m_Env, m_BaseTex->PreLoad());
134    }
135}
136
137void s3d_CDrvD3d9TexObjBase::UpdateToFrm(
138        s3d_CSysInt32u FrmIdx)
139{
140}
141
142bool s3d_CDrvD3d9TexObjBase::IsVideoTex()
143{
144    return false;
145}
146
147///////////////////////////////////////////////////////////////////////////////
148
149s3d_CDrvD3d9TexObj::s3d_CDrvD3d9TexObj(
150        s3d_CDrvD3d9Ctx *D3dCtx,
151        int TexProp, int Width, int Height,
152        const s3d_CDrvD3d9TexFmt &TexFmt, D3DPOOL Pool)
153{
154    m_D3dCtx = D3dCtx;
155
156    m_Prop = TexProp;
157    m_Width = Width;
158    m_Height = Height;
159    m_Depth = 1;
160    m_TexFmt = TexFmt;
161    m_Pool = Pool;
162   
163    AllocTex();
164}
165
166s3d_CDrvD3d9TexObj::s3d_CDrvD3d9TexObj(
167        s3d_CDrvD3d9Ctx *D3dCtx,
168        int TexProp, int Width, int Height,
169        const s3d_CDrvD3d9TexFmt &TexFmt, D3DPOOL Pool,
170        LPDIRECT3DTEXTURE9 D3dTex)
171{
172    m_D3dCtx = D3dCtx;
173
174    m_Prop = TexProp;
175    m_Width = Width;
176    m_Height = Height;
177    m_Depth = 1;
178    m_TexFmt = TexFmt;
179    m_Pool = Pool;
180
181    m_BaseTex = D3dTex;
182    m_D3dTex = D3dTex;
183}
184
185void s3d_CDrvD3d9TexObj::AllocTex()
186{
187    m_BaseTex.Reset();
188    m_D3dTex.Reset();
189
190    int MipLevels = 1;
191    if((m_Prop & s3d_CDrvGfxEng::TexProp_Mipmap) != 0)
192        MipLevels = m_D3dCtx->m_D3dParam->m_MaxMipLevels;
193
194    if((m_Prop & s3d_CDrvGfxEng::TexProp_RestrUsage) != 0)
195    {
196        //S3D_SYS_ASSERT((m_Prop & s3d_CDrvGfxEng::TexProp_Filter) == 0);
197        S3D_SYS_ASSERT((m_Prop & s3d_CDrvGfxEng::TexProp_Mipmap) == 0);
198    }
199    // If color format is unknown, its a NVIDIA depthtex.
200    D3DFORMAT D3dTexFmt = m_TexFmt.m_FmtCol;
201    if(D3dTexFmt == D3DFMT_UNKNOWN)
202        D3dTexFmt = m_TexFmt.m_FmtDepth;
203   
204    S3D_DRV_D3D9_CHECK(
205            m_D3dCtx->m_Env, m_D3dCtx->m_D3dDev->CreateTexture(
206                m_Width, m_Height, MipLevels, m_TexFmt.m_Usage, D3dTexFmt,
207                m_Pool, &m_D3dTex.EmptyRef(), 0));
208
209    m_BaseTex = m_D3dTex;
210}
211
212HRESULT s3d_CDrvD3d9TexObj::D3dLoadData(
213        int Part, int Mipmap, int Width, int Height, int Depth,
214        const s3d_CDrvGfxPixel *Data)
215{
216    if(!m_D3dTex)
217        return D3DERR_INVALIDCALL;
218
219    int MipLevel = Mipmap - 1;
220    if(MipLevel < 0)
221        MipLevel = 0;
222
223    DWORD Flags = 0;
224    D3DLOCKED_RECT LockRect;
225    HRESULT Result = m_D3dTex->LockRect(MipLevel, &LockRect, 0, Flags);
226    s3d_CSysIntm *DestData
227            = reinterpret_cast<s3d_CSysIntm *>(LockRect.pBits);
228    if(DestData)
229    {
230        s3d_CSysIntps Stride = LockRect.Pitch;
231        s3d_CDrvD3d9TexMgr::CopyTexData2D(
232                DestData, Stride, Width, Height, Data);
233   
234        Result = m_D3dTex->UnlockRect(MipLevel);
235    }
236    return Result;
237}
238
239HRESULT s3d_CDrvD3d9TexObj::D3dLoadData(
240        int Part, int Mipmap, int Width, int Height, int Depth,
241        LPDIRECT3DSURFACE9 SrcSurf)
242{
243    if(!m_D3dTex)
244        return D3DERR_INVALIDCALL;
245
246    int MipLevel = Mipmap - 1;
247    if(MipLevel < 0)
248        MipLevel = 0;
249
250    s3d_CDrvD3d9Surf DestSurf;
251    HRESULT Result = m_D3dTex->GetSurfaceLevel(MipLevel, &DestSurf.EmptyRef());
252    if(DestSurf)
253    {
254        Result = D3DXLoadSurfaceFromSurface(
255                DestSurf, 0, 0, SrcSurf, 0, 0, D3DX_FILTER_NONE, 0);
256    }
257    return Result;
258}
259
260HRESULT s3d_CDrvD3d9TexObj::GetRenderTarget(
261        s3d_CDrvD3d9Surf &DestSurf, const s3d_CDrvGfxDest *GfxDest)
262{
263    DestSurf.Reset();
264
265    if(!m_D3dTex)
266        return D3DERR_INVALIDCALL;
267
268    HRESULT Result = m_D3dTex->GetSurfaceLevel(0, &DestSurf.EmptyRef());
269    return Result;
270}
271
272void s3d_CDrvD3d9TexObj::Park()
273{
274    if(m_Pool == D3DPOOL_DEFAULT)
275    {
276        m_BaseTex.Reset();
277        m_D3dTex.Reset();
278    }
279}
280
281void s3d_CDrvD3d9TexObj::Unpark()
282{
283    if(m_Pool == D3DPOOL_DEFAULT)
284        AllocTex();
285}
286
287///////////////////////////////////////////////////////////////////////////////
288
289s3d_CDrvD3d9TexCubeObj::s3d_CDrvD3d9TexCubeObj(
290        s3d_CDrvD3d9Ctx *D3dCtx,
291        int TexProp, int Width, int Height,
292        const s3d_CDrvD3d9TexFmt &TexFmt, D3DPOOL Pool)
293{
294    m_D3dCtx = D3dCtx;
295
296    m_Prop = TexProp;
297    m_Width = Width;
298    m_Height = Height;
299    m_Depth = 1;
300    m_TexFmt = TexFmt;
301    m_Pool = Pool;
302
303    AllocTex();
304}
305
306s3d_CDrvD3d9TexCubeObj::s3d_CDrvD3d9TexCubeObj(
307        s3d_CDrvD3d9Ctx *D3dCtx,
308        int TexProp, int Width, int Height,
309        const s3d_CDrvD3d9TexFmt &TexFmt, D3DPOOL Pool,
310        LPDIRECT3DCUBETEXTURE9 D3dCubeTex)
311{
312    m_D3dCtx = D3dCtx;
313
314    m_Prop = TexProp;
315    m_Width = Width;
316    m_Height = Height;
317    m_Depth = 1;
318    m_TexFmt = TexFmt;
319    m_Pool = Pool;
320   
321    m_BaseTex = D3dCubeTex;
322    m_D3dCubeTex = D3dCubeTex;
323}
324
325void s3d_CDrvD3d9TexCubeObj::AllocTex()
326{
327    m_BaseTex.Reset();
328    m_D3dCubeTex.Reset();
329
330    int MipLevels = 1;
331    if((m_Prop & s3d_CDrvGfxEng::TexProp_Mipmap) != 0)
332        MipLevels = m_D3dCtx->m_D3dParam->m_MaxMipLevels;
333
334    UINT EdgeLength = s3d_SysMax(m_Width, m_Height);
335    S3D_DRV_D3D9_CHECK(
336            m_D3dCtx->m_Env, m_D3dCtx->m_D3dDev->CreateCubeTexture(
337                EdgeLength, MipLevels, m_TexFmt.m_Usage, m_TexFmt.m_FmtCol,
338                m_Pool, &m_D3dCubeTex.EmptyRef(), 0));
339   
340    m_BaseTex = m_D3dCubeTex;
341}
342
343HRESULT s3d_CDrvD3d9TexCubeObj::D3dLoadData(
344        int Part, int Mipmap, int Width, int Height, int Depth,
345        const s3d_CDrvGfxPixel *Data)
346{
347    if(!m_D3dCubeTex)
348        return D3DERR_INVALIDCALL;
349
350    int MipLevel = Mipmap - 1;
351    if(MipLevel < 0)
352        MipLevel = 0;
353    D3DCUBEMAP_FACES CubeFace = s3d_CDrvD3d9TexMgr::GetFaceOfPart(Part);
354    DWORD Flags = 0;
355    D3DLOCKED_RECT LockRect;
356    HRESULT Result = m_D3dCubeTex->LockRect(
357            CubeFace, MipLevel, &LockRect, 0, Flags);
358    s3d_CSysIntm *DestData
359            = reinterpret_cast<s3d_CSysIntm *>(LockRect.pBits);
360    if(DestData)
361    {
362        s3d_CSysIntps Stride = LockRect.Pitch;
363        s3d_CDrvD3d9TexMgr::CopyTexData2D(
364                DestData, Stride, Width, Height, Data);
365
366        Result = m_D3dCubeTex->UnlockRect(CubeFace, MipLevel);
367    }
368    return Result;
369}
370
371HRESULT s3d_CDrvD3d9TexCubeObj::D3dLoadData(
372        int Part, int Mipmap, int Width, int Height, int Depth,
373        LPDIRECT3DSURFACE9 SrcSurf)
374{
375    if(!m_D3dCubeTex)
376        return D3DERR_INVALIDCALL;
377
378    int MipLevel = Mipmap - 1;
379    if(MipLevel < 0)
380        MipLevel = 0;
381    D3DCUBEMAP_FACES CubeFace = s3d_CDrvD3d9TexMgr::GetFaceOfPart(Part);
382
383    s3d_CDrvD3d9Surf DestSurf;
384    HRESULT Result = m_D3dCubeTex->GetCubeMapSurface(
385            CubeFace, MipLevel, &DestSurf.EmptyRef());
386    if(DestSurf)
387    {
388        Result = D3DXLoadSurfaceFromSurface(
389                DestSurf, 0, 0, SrcSurf, 0, 0, D3DX_FILTER_NONE, 0);
390    }
391    return Result;
392}
393
394HRESULT s3d_CDrvD3d9TexCubeObj::GetRenderTarget(
395        s3d_CDrvD3d9Surf &DestSurf, const s3d_CDrvGfxDest *Dest)
396{
397    DestSurf.Reset();
398
399    if(!m_D3dCubeTex)
400        return D3DERR_INVALIDCALL;
401
402    D3DCUBEMAP_FACES CubeFace = s3d_CDrvD3d9TexMgr::GetFaceOfPart(
403            Dest->m_Part);
404    HRESULT Result = m_D3dCubeTex->GetCubeMapSurface(
405            CubeFace, 0, &DestSurf.EmptyRef());
406    return Result;
407}
408
409void s3d_CDrvD3d9TexCubeObj::Park()
410{
411    if(m_Pool == D3DPOOL_DEFAULT)
412    {
413        m_BaseTex.Reset();
414        m_D3dCubeTex.Reset();
415    }
416}
417
418void s3d_CDrvD3d9TexCubeObj::Unpark()
419{
420    if(m_Pool == D3DPOOL_DEFAULT)
421        AllocTex();
422}
423
424///////////////////////////////////////////////////////////////////////////////
425
426s3d_CDrvD3d9TexVolObj::s3d_CDrvD3d9TexVolObj(
427        s3d_CDrvD3d9Ctx *D3dCtx,
428        int TexProp, int Width, int Height, int Depth,
429        const s3d_CDrvD3d9TexFmt &TexFmt, D3DPOOL Pool,
430        LPDIRECT3DVOLUMETEXTURE9 D3dVolTex)
431{
432    m_D3dCtx = D3dCtx;
433
434    m_Prop = TexProp;
435    m_Width = Width;
436    m_Height = Height;
437    m_Depth = Depth;
438    m_TexFmt = TexFmt;
439    m_Pool = Pool;
440   
441    m_BaseTex = D3dVolTex;
442    m_D3dVolTex = D3dVolTex;
443}
444
445void s3d_CDrvD3d9TexVolObj::AllocTex()
446{
447}
448
449HRESULT s3d_CDrvD3d9TexVolObj::D3dLoadData(
450        int Part, int Mipmap, int Width, int Height, int Depth,
451        const s3d_CDrvGfxPixel *SrcData)
452{
453    return 0;
454}
455
456HRESULT s3d_CDrvD3d9TexVolObj::D3dLoadData(
457        int Part, int Mipmap, int Width, int Height, int Depth,
458        LPDIRECT3DSURFACE9 SrcSurf)
459{
460    return 0;
461}
462
463HRESULT s3d_CDrvD3d9TexVolObj::GetRenderTarget(
464        s3d_CDrvD3d9Surf &DestSurf, const s3d_CDrvGfxDest *GfxDest)
465{
466    return 0;
467}
468
469bool s3d_CDrvD3d9TexVolObj::IsVideoTex()
470{
471    return false;
472}
473
474void s3d_CDrvD3d9TexVolObj::UpdateToFrm(
475        s3d_CSysInt32u FrmIdx)
476{
477}
478
479void s3d_CDrvD3d9TexVolObj::Park()
480{
481}
482
483void s3d_CDrvD3d9TexVolObj::Unpark()
484{
485}
486
487///////////////////////////////////////////////////////////////////////////////
488
489s3d_CDrvD3d9TexObjVideo::s3d_CDrvD3d9TexObjVideo(
490        s3d_CDrvD3d9Ctx *D3dCtx, s3d_CDrvVideoPlayer *VideoPlayer,
491        int TexProp, bool NeedSnap,
492        const s3d_CDrvD3d9TexFmt &TexFmt, D3DPOOL Pool)
493{
494    m_D3dCtx = D3dCtx;
495    m_VideoPlayer = VideoPlayer;
496
497    m_Prop = TexProp;
498    m_NeedSnap = NeedSnap;
499    m_Width = 0;
500    m_Height = 0;
501    m_Depth = 1;
502    m_TexFmt = TexFmt;
503    m_Pool = Pool;
504
505    m_VideoWidth = 0;
506    m_VideoHeight = 0;
507    m_LastFrmIdx = -1;
508
509    int Format = CalcVideoFormat(VideoPlayer);
510    if(VideoPlayer)
511        VideoPlayer->Appoint(Format, false);
512
513    UpdateToFrm(0);
514}
515
516void s3d_CDrvD3d9TexObjVideo::AllocTex()
517{
518    m_BaseTex.Reset();
519    m_D3dTex.Reset();
520
521    int MipLevels = 1;
522    D3DFORMAT D3dTexFmt = m_TexFmt.m_FmtCol;
523    if(D3dTexFmt == D3DFMT_UNKNOWN)
524        return;
525   
526    S3D_DRV_D3D9_CHECK(
527            m_D3dCtx->m_Env, m_D3dCtx->m_D3dDev->CreateTexture(
528                m_Width, m_Height, MipLevels, m_TexFmt.m_Usage, D3dTexFmt,
529                m_Pool, &m_D3dTex.EmptyRef(), 0));
530
531    m_BaseTex = m_D3dTex;
532}
533
534HRESULT s3d_CDrvD3d9TexObjVideo::D3dLoadData(
535        int Part, int Mipmap, int Width, int Height, int Depth,
536        const s3d_CDrvGfxPixel *Data)
537{
538    return D3DERR_INVALIDCALL;
539}
540
541HRESULT s3d_CDrvD3d9TexObjVideo::D3dLoadData(
542        int Part, int Mipmap, int Width, int Height, int Depth,
543        LPDIRECT3DSURFACE9 SrcSurf)
544{
545    return D3DERR_INVALIDCALL;
546}
547
548HRESULT s3d_CDrvD3d9TexObjVideo::GetRenderTarget(
549        s3d_CDrvD3d9Surf &DestSurf, const s3d_CDrvGfxDest *GfxDest)
550{
551    DestSurf.Reset();
552    return D3DERR_INVALIDCALL;
553}
554
555bool s3d_CDrvD3d9TexObjVideo::IsVideoTex()
556{
557    return true;
558}
559
560void s3d_CDrvD3d9TexObjVideo::UpdateToFrm(
561        s3d_CSysInt32u FrmIdx)
562{
563    if(!m_VideoPlayer)
564        return;
565
566    if(!m_VideoPlayer->IsAvail())
567        return;
568
569    int VideoWidth = 0;
570    int VideoHeight = 0;
571    m_VideoPlayer->GetSize(VideoWidth, VideoHeight);
572    if(!m_D3dTex || VideoWidth != m_VideoWidth || VideoHeight != m_VideoHeight)
573        SetVideoSize(VideoWidth, VideoHeight);
574   
575    // SetVideoSize internally call AllocTex and when it fails
576    // m_D3dTex might be invalid, hence check again.
577    if(!m_D3dTex)
578        return;
579
580    s3d_CSysInt32u DeltaFrmIdx = FrmIdx - m_LastFrmIdx;
581    if(DeltaFrmIdx == 0)
582        return;
583    m_LastFrmIdx = FrmIdx;
584    bool HadPause = (DeltaFrmIdx > 1);
585
586    int PosX = (m_Width - m_VideoWidth) >> 1;
587    int PosY = (m_Height - m_VideoHeight) >> 1;
588
589    RECT Rect;
590    Rect.left = PosX;
591    Rect.top = PosY;
592    Rect.right = PosX + m_VideoWidth;
593    Rect.bottom = PosY + m_VideoHeight;
594   
595    UINT Level = 0;
596    D3DLOCKED_RECT LockRect;
597    S3D_DRV_D3D9_CHECK(
598            m_D3dCtx->m_Env, m_D3dTex->LockRect(
599                Level, &LockRect, &Rect, 0));
600
601    s3d_CDrvVideoSurf VideoSurf;
602    VideoSurf.m_Width = m_VideoWidth;
603    VideoSurf.m_Height = m_VideoHeight;
604    VideoSurf.m_Stride = LockRect.Pitch;
605    VideoSurf.m_Format = s3d_CDrvVideoPlayer::Format_B8G8R8A8;
606    VideoSurf.m_Data = reinterpret_cast<s3d_CSysIntm*>(LockRect.pBits);
607
608    m_VideoPlayer->TransferPerform(VideoSurf, HadPause);
609
610    S3D_DRV_D3D9_CHECK(
611            m_D3dCtx->m_Env, m_D3dTex->UnlockRect(Level));
612}
613
614void s3d_CDrvD3d9TexObjVideo::Park()
615{
616    if(m_Pool == D3DPOOL_DEFAULT)
617    {
618        m_BaseTex.Reset();
619        m_D3dTex.Reset();
620    }
621}
622
623void s3d_CDrvD3d9TexObjVideo::Unpark()
624{
625    if(m_Pool == D3DPOOL_DEFAULT)
626        AllocTex();
627}
628
629void s3d_CDrvD3d9TexObjVideo::SetVideoSize(
630        int VideoWidth, int VideoHeight)
631{
632    int TexWidth = VideoWidth;
633    int TexHeight = VideoHeight;
634
635    SnapVideoSize(TexWidth, TexHeight);
636
637    if(m_Width != TexWidth || m_Height != TexHeight)
638    {
639        m_Width = TexWidth;
640        m_Height = TexHeight;
641        AllocTex();
642    }
643
644    m_VideoWidth = VideoWidth;
645    m_VideoHeight = VideoHeight;
646}
647
648void s3d_CDrvD3d9TexObjVideo::SnapVideoSize(
649        int &Width, int &Height)
650{
651    if(m_NeedSnap)
652    {
653        Width = (1 << s3d_CDrvUtilGfxUtil::BinLogDownInt(Width));
654        Height = (1 << s3d_CDrvUtilGfxUtil::BinLogDownInt(Height));
655    }
656   
657    s3d_SysSetToMax(Width, 1);
658    s3d_SysSetToMax(Height, 1);
659}
660
661int s3d_CDrvD3d9TexObjVideo::CalcVideoFormat(
662        s3d_CDrvVideoPlayer *VideoPlayer)
663{
664    if(!VideoPlayer)
665        return 0;
666
667    if(VideoPlayer->TransferLikesFormat(s3d_CDrvVideoPlayer::Format_B8G8R8A8))
668        return s3d_CDrvVideoPlayer::Format_B8G8R8A8;
669    if(VideoPlayer->TransferLikesFormat(s3d_CDrvVideoPlayer::Format_B8G8R8))
670        return s3d_CDrvVideoPlayer::Format_B8G8R8;
671    if(VideoPlayer->TransferSupportsFormat(
672            s3d_CDrvVideoPlayer::Format_B8G8R8A8))
673        return s3d_CDrvVideoPlayer::Format_B8G8R8A8;
674    if(VideoPlayer->TransferSupportsFormat(s3d_CDrvVideoPlayer::Format_B8G8R8))
675        return s3d_CDrvVideoPlayer::Format_B8G8R8;
676    return 0;
677}
678
679///////////////////////////////////////////////////////////////////////////////
680
681s3d_CDrvD3d9TexMgr::s3d_CDrvD3d9TexMgr(
682        s3d_CDrvD3d9Ctx *D3dCtx)
683{
684    m_D3dCtx = D3dCtx;
685
686    s3d_SysMemset(&m_AdapterMode, 0, S3D_SYS_SIZEOFS(m_AdapterMode));
687    S3D_DRV_D3D9_CHECK(
688            m_D3dCtx->m_Env, m_D3dCtx->m_D3d->GetAdapterDisplayMode(
689            m_D3dCtx->m_Adapter, &m_AdapterMode));
690    s3d_SysMemset(&m_DevCaps, 0, S3D_SYS_SIZEOFS(m_DevCaps));
691    S3D_DRV_D3D9_CHECK(
692            m_D3dCtx->m_Env, m_D3dCtx->m_D3dDev->GetDeviceCaps(&m_DevCaps));
693}
694
695s3d_CDrvD3d9TexMgr::~s3d_CDrvD3d9TexMgr()
696{
697}
698
699s3d_CDrvGfxTexPtr s3d_CDrvD3d9TexMgr::CreateTexDirect(
700        s3d_CUtilStr_cr Info,
701        int TexProp, int Width, int Height, int Depth)
702{
703    int EffTexProp = TexProp;
704
705    const s3d_CDrvD3d9Param *D3dParam = m_D3dCtx->m_D3dParam;
706    if(D3dParam->m_MinTexComprWidth > 0
707        && D3dParam->m_MinTexComprHeight > 0
708        && Width > D3dParam->m_MinTexComprWidth
709        && Height > D3dParam->m_MinTexComprHeight)
710    {
711        EffTexProp |= s3d_CDrvGfxEng::TexProp_Compress;
712    }
713
714    s3d_CDrvD3d9TexFmt TexFmt;
715    FindTexFmt(TexFmt, EffTexProp);
716   
717    s3d_CDrvD3d9TexObjBasePtr TexObjBase
718            = CreateTexDirectFmt(
719                    Info, EffTexProp, TexFmt, Width, Height, Depth, 0);
720
721    if(!TexObjBase)
722        return 0;
723
724    m_TexList.InsertBack(&TexObjBase->m_Node);
725
726    if(D3dParam->m_ReportTex)
727    {
728        s3d_CUtilMsg m;
729        m.m_Code = "drv/imp/directx/d3d9/drv_d3d9_tex.report_tex_create";
730        m.m_StdTempl = "D3D: "
731            "Creating texture Addr=[1] '[2]': "
732            "[3]x[4]x[5] Prop='[6]' ColFmt=[7] DepthFmt=[8].";
733        m.AddInfo("");
734        m.AddInfo(s3d_CUtilStrUtil::StrOfPtr(TexObjBase));
735        m.AddInfo(Info);
736        m.AddInfo(s3d_CUtilStrUtil::StrOfInt(Width));
737        m.AddInfo(s3d_CUtilStrUtil::StrOfInt(Height));
738        m.AddInfo(s3d_CUtilStrUtil::StrOfInt(Depth));
739        m.AddInfo(s3d_CDrvUtilGfxUtil::CalcStrOfTexProp(TexProp));
740        m.AddInfo(s3d_CDrvD3d9Util::StrOfFmt(TexFmt.m_FmtCol));
741        m.AddInfo(s3d_CDrvD3d9Util::StrOfFmt(TexFmt.m_FmtDepth));
742        s3d_UtilMsgReportNote(m_D3dCtx->m_MsgHandler, m);
743    }
744
745    return TexObjBase.Get();
746}
747
748s3d_CDrvGfxTexPtr s3d_CDrvD3d9TexMgr::CreateTexStream(
749        s3d_CUtilStr_cr Info, int TexProp,
750        s3d_CUtilStream *Stream)
751{
752    // Quick check format:
753    if(!Stream)
754        return 0;
755    s3d_CUtilStreamPos StreamSize = Stream->GetSize();
756/*
757    if(StreamSize < 4)
758        return 0;
759    Stream->SetPos(0);
760    DWORD DDSMagic = s3d_CUtilStreamBin::ReadInt32uLitEndian(Stream);
761    if(DDSMagic != 0x20534444) //"DDS "
762        return 0;
763*/
764
765    // Load data:
766
767    s3d_CUtilMemPoolFrm MemPoolFrm(m_D3dCtx->m_MemPool);
768
769    UINT DataLen = UINT(StreamSize);
770    s3d_CSysInt8u *Data = new(m_D3dCtx->m_MemPool) s3d_CSysInt8u[DataLen];
771    Stream->SetPos(0);
772    Stream->Read(DataLen, Data);
773
774    D3DXIMAGE_INFO ImageInfo;
775    memset(&ImageInfo, 0, sizeof(ImageInfo));
776
777    HRESULT DxResult = D3D_OK;
778    S3D_DRV_D3D9_HRESCALL(m_D3dCtx->m_Env, DxResult,
779            D3DXGetImageInfoFromFileInMemory(Data, DataLen, &ImageInfo));
780    if(DxResult != D3D_OK)
781        return 0;
782
783    int Width = 0;
784    int Height = 0;
785    int Depth = 0;
786    s3d_CDrvD3d9TexFmt TexFmt;
787
788    int MipLevels = ImageInfo.MipLevels;
789    if(TexProp & s3d_CDrvGfxEng::TexProp_Mipmap)
790        MipLevels = 0;
791
792    D3DRESOURCETYPE ResType = ImageInfo.ResourceType;
793    s3d_CDrvD3d9TexObjBasePtr TexObjBase;
794    switch(ResType)
795    {
796    case D3DRTYPE_TEXTURE:
797        {
798            s3d_CDrvD3d9Tex D3dTex;
799            S3D_DRV_D3D9_CHECK(m_D3dCtx->m_Env,
800                    D3DXCreateTextureFromFileInMemoryEx(
801                        m_D3dCtx->m_D3dDev, Data, DataLen, 0, 0, MipLevels, 0,
802                        D3DFMT_UNKNOWN, D3DPOOL_MANAGED,
803                        D3DX_DEFAULT, D3DX_DEFAULT, 0, 0, 0,
804                        &D3dTex.EmptyRef()));
805           
806            if(!D3dTex)
807                return 0;
808
809            HRESULT Result;
810            D3DSURFACE_DESC SurfDesc;
811            S3D_DRV_D3D9_CALLCHECK(
812                    m_D3dCtx->m_Env,
813                    Result, D3dTex->GetLevelDesc(0, &SurfDesc));
814            if(FAILED(Result))
815                return 0;
816
817            Width = SurfDesc.Width;
818            Height = SurfDesc.Height;
819            Depth = 1;
820            D3DPOOL Pool = SurfDesc.Pool;
821           
822            TexFmt.m_FmtCol = SurfDesc.Format;
823            TexFmt.m_FmtDepth = D3DFMT_UNKNOWN;
824            TexFmt.m_FilterMipGen = D3DTEXF_NONE;
825            TexFmt.m_CanFilter = true;
826            TexFmt.m_Usage = 0;
827            TexFmt.m_SRGBRead = false;
828            TexFmt.m_SRGBWrite = false;
829
830            TexObjBase = S3D_SYS_NEW s3d_CDrvD3d9TexObj(
831                    m_D3dCtx, TexProp, Width, Height, TexFmt, Pool, D3dTex);
832        }
833        break;
834    case D3DRTYPE_CUBETEXTURE:
835        {
836            s3d_CDrvD3d9CubeTex D3dCubeTex;
837            S3D_DRV_D3D9_CHECK(m_D3dCtx->m_Env,
838                    D3DXCreateCubeTextureFromFileInMemoryEx(
839                        m_D3dCtx->m_D3dDev, Data, DataLen, 0, MipLevels, 0,
840                        D3DFMT_UNKNOWN, D3DPOOL_MANAGED,
841                        D3DX_DEFAULT, D3DX_DEFAULT, 0, 0, 0,
842                        &D3dCubeTex.EmptyRef()));
843           
844            if(!D3dCubeTex)
845                return 0;
846           
847            HRESULT Result;
848            D3DSURFACE_DESC SurfDesc;
849            S3D_DRV_D3D9_CALLCHECK(
850                    m_D3dCtx->m_Env, Result, D3dCubeTex->GetLevelDesc(
851                        0, &SurfDesc));
852            if(FAILED(Result))
853                return 0;
854
855            Width = SurfDesc.Width;
856            Height = SurfDesc.Height;
857            Depth = 1;
858            D3DPOOL Pool = SurfDesc.Pool;
859
860            TexFmt.m_FmtCol = SurfDesc.Format;
861            TexFmt.m_FmtDepth = D3DFMT_UNKNOWN;
862            TexFmt.m_FilterMipGen = D3DTEXF_NONE;
863            TexFmt.m_CanFilter = true;
864            TexFmt.m_Usage = 0;
865            TexFmt.m_SRGBRead = false;
866            TexFmt.m_SRGBWrite = false;
867
868            TexObjBase = S3D_SYS_NEW s3d_CDrvD3d9TexCubeObj(
869                    m_D3dCtx, TexProp, Width, Height,
870                    TexFmt, Pool, D3dCubeTex);
871        }
872        break;
873    case D3DRTYPE_VOLUMETEXTURE:
874        {
875            s3d_CDrvD3d9VolTex D3dVolTex;
876            S3D_DRV_D3D9_CHECK(m_D3dCtx->m_Env,
877                    D3DXCreateVolumeTextureFromFileInMemoryEx(
878                        m_D3dCtx->m_D3dDev, Data, DataLen, 0, 0, 0,
879                        MipLevels, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED,
880                        D3DX_DEFAULT, D3DX_DEFAULT, 0, 0, 0,
881                        &D3dVolTex.EmptyRef()));
882
883            if(!D3dVolTex)
884                return 0;
885
886            HRESULT Result;
887            D3DVOLUME_DESC VolDesc;
888            S3D_DRV_D3D9_CALLCHECK(
889                    m_D3dCtx->m_Env, Result, D3dVolTex->GetLevelDesc(
890                        0, &VolDesc));
891            if(FAILED(Result))
892                return 0;
893
894            Width = VolDesc.Width;
895            Height = VolDesc.Height;
896            Depth = VolDesc.Depth;
897            D3DPOOL Pool = VolDesc.Pool;
898
899            TexFmt.m_FmtCol = VolDesc.Format;
900            TexFmt.m_FmtDepth = D3DFMT_UNKNOWN;
901            TexFmt.m_FilterMipGen = D3DTEXF_NONE;
902            TexFmt.m_CanFilter = true;
903            TexFmt.m_Usage = 0;
904            TexFmt.m_SRGBRead = false;
905            TexFmt.m_SRGBWrite = false;
906
907            TexObjBase = S3D_SYS_NEW s3d_CDrvD3d9TexVolObj(
908                    m_D3dCtx, TexProp, Width, Height, Depth,
909                    TexFmt, Pool, D3dVolTex);
910        }
911        break;
912    default:
913        return 0;
914    }
915
916    if(!TexObjBase)
917        return 0;
918
919    m_TexList.InsertBack(&TexObjBase->m_Node);
920
921    if(m_D3dCtx->m_D3dParam->m_ReportTex)
922    {
923        s3d_CUtilMsg m;
924        m.m_Code = "drv/imp/directx/d3d9/drv_d3d9_tex.report_tex_create";
925        m.m_StdTempl = "D3D: "
926            "Creating texture Addr=[1] '[2]': "
927            "[3]x[4]x[5] Prop='[6]' ColFmt=[7] DepthFmt=[8].";
928        m.AddInfo("");
929        m.AddInfo(s3d_CUtilStrUtil::StrOfPtr(TexObjBase));
930        m.AddInfo(Info);
931        m.AddInfo(s3d_CUtilStrUtil::StrOfInt(Width));
932        m.AddInfo(s3d_CUtilStrUtil::StrOfInt(Height));
933        m.AddInfo(s3d_CUtilStrUtil::StrOfInt(Depth));
934        m.AddInfo(s3d_CDrvUtilGfxUtil::CalcStrOfTexProp(TexProp));
935        m.AddInfo(s3d_CDrvD3d9Util::StrOfFmt(TexFmt.m_FmtCol));
936        m.AddInfo(s3d_CDrvD3d9Util::StrOfFmt(TexFmt.m_FmtDepth));
937        s3d_UtilMsgReportNote(m_D3dCtx->m_MsgHandler, m);
938    }
939
940    return TexObjBase.Get();
941}
942
943s3d_CDrvGfxTexPtr s3d_CDrvD3d9TexMgr::CreateTexVideo(
944        s3d_CUtilStr_cr Info, int TexProp,
945        s3d_CDrvVideoPlayer *VideoPlayer)
946{
947    int Width = 0;
948    int Height = 0;
949    int Depth = 1;
950
951    s3d_CDrvD3d9TexFmt TexFmt;
952    FindTexFmt(TexFmt, TexProp);
953   
954    s3d_CDrvD3d9TexObjBasePtr TexObjBase
955            = CreateTexDirectFmt(
956                Info, TexProp, TexFmt, Width, Height, Depth, VideoPlayer);
957
958    if(!TexObjBase)
959        return 0;
960
961    m_TexList.InsertBack(&TexObjBase->m_Node);
962
963    if(m_D3dCtx->m_D3dParam->m_ReportTex)
964    {
965        s3d_CUtilMsg m;
966        m.m_Code = "drv/imp/directx/d3d9/drv_d3d9_tex.report_tex_create";
967        m.m_StdTempl = "D3D: "
968            "Creating video texture Addr=[1] '[2]': ColFmt=[3].";
969        m.AddInfo("");
970        m.AddInfo(s3d_CUtilStrUtil::StrOfPtr(TexObjBase));
971        m.AddInfo(Info);
972        m.AddInfo(s3d_CDrvD3d9Util::StrOfFmt(TexFmt.m_FmtCol));
973        s3d_UtilMsgReportNote(m_D3dCtx->m_MsgHandler, m);
974    }
975
976    return TexObjBase.Get();
977}
978
979void s3d_CDrvD3d9TexMgr::Park()
980{
981    s3d_CDrvD3d9TexList::CNode *Node = m_TexList.GetFirst();
982    while(Node)
983    {
984        s3d_CDrvD3d9TexObjBase *Tex = Node->m_Data;
985        Node = Node->GetNext();
986        if(Tex)
987            Tex->Park();
988    }
989}
990
991void s3d_CDrvD3d9TexMgr::Unpark()
992{
993    s3d_CDrvD3d9TexList::CNode *Node = m_TexList.GetFirst();
994    while(Node)
995    {
996        s3d_CDrvD3d9TexObjBase *Tex = Node->m_Data;
997        Node = Node->GetNext();
998        if(Tex)
999            Tex->Unpark();
1000    }
1001}
1002
1003///////////////////////////////////////////////////////////////////////////////
1004
1005s3d_CDrvD3d9TexObjBasePtr s3d_CDrvD3d9TexMgr::CreateTexDirectFmt(
1006        s3d_CUtilStr_cr Info,
1007        int TexProp, const s3d_CDrvD3d9TexFmt &TexFmt,
1008        int Width, int Height, int Depth, s3d_CDrvVideoPlayer *VideoPlayer)
1009{
1010    const s3d_CDrvD3d9Param *D3dParam = m_D3dCtx->m_D3dParam;
1011    int MipLevels = 1;
1012    if((TexProp & s3d_CDrvGfxEng::TexProp_Mipmap) != 0)
1013        MipLevels = D3dParam->m_MaxMipLevels;
1014
1015    D3DPOOL Pool = D3DPOOL_MANAGED;
1016    if((TexProp & s3d_CDrvGfxEng::TexProp_RenderTarget) != 0
1017            || (TexProp & s3d_CDrvGfxEng::TexProp_Depth) != 0)
1018        Pool = D3DPOOL_DEFAULT;
1019
1020    s3d_CDrvD3d9TexObjBasePtr TexObjBase;
1021    if((TexProp & s3d_CDrvGfxEng::TexProp_Volume) != 0)
1022    {
1023    }
1024    else if((TexProp & s3d_CDrvGfxEng::TexProp_Cube) != 0)
1025    {
1026        if(Width <= 0 || Height <= 0)
1027            return 0;
1028        TexObjBase = S3D_SYS_NEW s3d_CDrvD3d9TexCubeObj(
1029                m_D3dCtx, TexProp, Width, Height, TexFmt, Pool);
1030    }
1031    else if(VideoPlayer)
1032    {
1033        bool CanRect = false;
1034        bool CanNPOT2 = false;
1035        if((m_DevCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) != 0)
1036            CanRect = true;
1037        if(!CanRect && (m_DevCaps.TextureCaps & D3DPTEXTURECAPS_POW2) == 0)
1038            CanNPOT2 = true;
1039        bool NeedSnap = true;
1040        if(CanRect || CanNPOT2)
1041            NeedSnap = false;
1042
1043        TexObjBase = S3D_SYS_NEW s3d_CDrvD3d9TexObjVideo(
1044                m_D3dCtx, VideoPlayer, TexProp, NeedSnap, TexFmt, Pool);
1045        return TexObjBase;
1046    }
1047    else
1048    {
1049        if(Width <= 0 || Height <= 0)
1050            return 0;
1051        TexObjBase = S3D_SYS_NEW s3d_CDrvD3d9TexObj(
1052                m_D3dCtx, TexProp, Width, Height, TexFmt, Pool);
1053    }
1054   
1055    if(!TexObjBase)
1056        return 0;
1057    if(!TexObjBase->m_BaseTex)
1058        return 0;
1059
1060    return TexObjBase;
1061}
1062
1063void s3d_CDrvD3d9TexMgr::FindTexFmt(
1064        s3d_CDrvD3d9TexFmt &TexFmt, int TexProp)
1065{
1066    if(!m_PropFmtMap.GetAtInto(TexProp, TexFmt))
1067    {
1068        FmtOfTexProp(TexProp, TexFmt);
1069        m_PropFmtMap.SetAt(TexProp, TexFmt);
1070    }
1071}
1072
1073static const D3DFORMAT s3d_DrvD3d9TexFmtArray1u[] =
1074{
1075    /* D3DFMT_L16,*/ D3DFMT_L8,
1076};
1077
1078static const D3DFORMAT s3d_DrvD3d9TexFmtArray1s[] =
1079{
1080    D3DFMT_V8U8,
1081};
1082
1083static const D3DFORMAT s3d_DrvD3d9TexFmtArray1f16[] =
1084{
1085    D3DFMT_R16F
1086};
1087
1088static const D3DFORMAT s3d_DrvD3d9TexFmtArray1f32[] =
1089{
1090    D3DFMT_R32F, D3DFMT_R16F
1091};
1092
1093static const D3DFORMAT s3d_DrvD3d9TexFmtArray2u[] =
1094{
1095    D3DFMT_G16R16,
1096};
1097
1098static const D3DFORMAT s3d_DrvD3d9TexFmtArray2s[] =
1099{
1100    /*D3DFMT_V16U16, */ D3DFMT_V8U8,
1101};
1102
1103static const D3DFORMAT s3d_DrvD3d9TexFmtArray2f16[] =
1104{
1105    D3DFMT_G16R16F
1106};
1107
1108static const D3DFORMAT s3d_DrvD3d9TexFmtArray2f32[] =
1109{
1110    D3DFMT_G32R32F, D3DFMT_G16R16F
1111};
1112
1113static const D3DFORMAT s3d_DrvD3d9TexFmtArray3u[] =
1114{
1115    D3DFMT_X8R8G8B8, D3DFMT_R5G6B5, D3DFMT_X1R5G5B5
1116};
1117
1118static const D3DFORMAT s3d_DrvD3d9TexFmtArray3s[] =
1119{
1120    D3DFMT_X8L8V8U8, D3DFMT_L6V5U5
1121};
1122
1123static const D3DFORMAT s3d_DrvD3d9TexFmtArray3f16[] =
1124{
1125     D3DFMT_A16B16G16R16F
1126};
1127
1128static const D3DFORMAT s3d_DrvD3d9TexFmtArray3f32[] =
1129{
1130     D3DFMT_A32B32G32R32F, D3DFMT_A16B16G16R16F
1131};
1132
1133static const D3DFORMAT s3d_DrvD3d9TexFmtArray4u[] =
1134{
1135    D3DFMT_A8R8G8B8, D3DFMT_A1R5G5B5, D3DFMT_A4R4G4B4
1136};
1137
1138static const D3DFORMAT s3d_DrvD3d9TexFmtArray4s[] =
1139{
1140    D3DFMT_Q8W8V8U8
1141};
1142
1143static const D3DFORMAT s3d_DrvD3d9TexFmtArray4f16[] =
1144{
1145    D3DFMT_A16B16G16R16F
1146};
1147
1148static const D3DFORMAT s3d_DrvD3d9TexFmtArray4f32[] =
1149{
1150    D3DFMT_A32B32G32R32F, D3DFMT_A16B16G16R16F
1151};
1152
1153static const D3DFORMAT s3d_DrvD3d9TexFmtDepth[] =
1154{
1155    D3DFMT_R32F, D3DFMT_R16F, //D3DFMT_D24FS8
1156};
1157
1158static const D3DFORMAT s3d_DrvD3d9TexFmtCompr123[] =
1159{
1160    D3DFMT_DXT1
1161};
1162
1163static const D3DFORMAT s3d_DrvD3d9TexFmtCompr4[] =
1164{
1165    D3DFMT_DXT5
1166};
1167
1168void s3d_CDrvD3d9TexMgr::FmtOfTexProp(
1169        int TexProp, s3d_CDrvD3d9TexFmt &TexFmt)
1170{
1171    TexFmt.m_FmtCol = D3DFMT_UNKNOWN;
1172    TexFmt.m_FmtDepth = D3DFMT_UNKNOWN;
1173    TexFmt.m_FilterMipGen = D3DTEXF_NONE;
1174    TexFmt.m_CanFilter = true;
1175    TexFmt.m_Usage = 0;
1176    TexFmt.m_SRGBRead = false;
1177    TexFmt.m_SRGBWrite = false;
1178
1179    D3DFORMAT FmtCol = D3DFMT_UNKNOWN;
1180    D3DFORMAT FmtDepth = D3DFMT_UNKNOWN;
1181    bool AutoMipmap = true;
1182    bool CanFilter = true;
1183    bool CanMultiSample = true;
1184    bool SRGBRead = false;
1185    bool SRGBWrite = false;
1186
1187    bool IsRT = (TexProp & s3d_CDrvGfxEng::TexProp_RenderTarget) != 0;
1188    bool IsDepth = (TexProp & s3d_CDrvGfxEng::TexProp_Depth) != 0;
1189    bool IsSigned = (TexProp & s3d_CDrvGfxEng::TexProp_Signed) != 0;
1190    bool IsFloat = (TexProp & s3d_CDrvGfxEng::TexProp_Float) != 0;
1191    bool IsCompr = (TexProp & s3d_CDrvGfxEng::TexProp_Compress) != 0;
1192    bool IsVolTex = (TexProp & s3d_CDrvGfxEng::TexProp_Volume) != 0;
1193    bool IsCubeTex = (TexProp & s3d_CDrvGfxEng::TexProp_Cube) != 0;
1194
1195    D3DRESOURCETYPE ResType = D3DRTYPE_TEXTURE;
1196    DWORD Usage = 0;
1197    if(TexProp & s3d_CDrvGfxEng::TexProp_Mipmap)
1198        Usage |= D3DUSAGE_AUTOGENMIPMAP;
1199/*
1200    D3d dynamic textures might cause performance problems. See dx doc.
1201    if(TexProp & s3d_CDrvGfxEng::TexProp_Dynamic)
1202        Usage |= D3DUSAGE_DYNAMIC;
1203*/
1204    if(IsDepth || IsRT)
1205        Usage |= D3DUSAGE_RENDERTARGET;
1206
1207    if(IsVolTex)
1208        ResType = D3DRTYPE_VOLUMETEXTURE;
1209    else if(IsCubeTex)
1210        ResType = D3DRTYPE_CUBETEXTURE;
1211
1212    const D3DFORMAT *TexFmtArray = 0;
1213    s3d_CSysIntps TexFmtCnt = 0;
1214    int CompCnt = CompCntOfTexProp(TexProp);
1215    int BitsPerCompCnt = BitsPerCompCntOfTexProp(TexProp);
1216
1217    if(CompCnt == 1)
1218    {
1219        TexFmtArray = s3d_DrvD3d9TexFmtArray1u;
1220        TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtArray1u);
1221        if(IsSigned)
1222        {
1223            TexFmtArray = s3d_DrvD3d9TexFmtArray1s;
1224            TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtArray1s);
1225        }
1226        else if(IsFloat)
1227        {
1228            if(BitsPerCompCnt > 0 && BitsPerCompCnt <= 16)
1229            {
1230                TexFmtArray = s3d_DrvD3d9TexFmtArray1f16;
1231                TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtArray1f16);
1232            }
1233            else
1234            {
1235                TexFmtArray = s3d_DrvD3d9TexFmtArray1f32;
1236                TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtArray1f32);
1237            }
1238        }
1239        if(IsDepth)
1240        {
1241            TexFmtArray = s3d_DrvD3d9TexFmtDepth;
1242            TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtDepth);
1243        }
1244    }
1245    else if(CompCnt == 2)
1246    {
1247        TexFmtArray = s3d_DrvD3d9TexFmtArray2u;
1248        TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtArray2u);
1249        if(IsSigned)
1250        {
1251            TexFmtArray = s3d_DrvD3d9TexFmtArray2s;
1252            TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtArray2s);
1253        }
1254        else if(IsFloat)
1255        {
1256            if(BitsPerCompCnt > 0 && BitsPerCompCnt <= 16)
1257            {
1258                TexFmtArray = s3d_DrvD3d9TexFmtArray2f16;
1259                TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtArray2f16);
1260            }
1261            else
1262            {
1263                TexFmtArray = s3d_DrvD3d9TexFmtArray2f32;
1264                TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtArray2f32);
1265            }
1266        }
1267    }
1268    else if(CompCnt == 3)
1269    {
1270        TexFmtArray = s3d_DrvD3d9TexFmtArray3u;
1271        TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtArray3u);
1272        if(IsSigned)
1273        {
1274            TexFmtArray = s3d_DrvD3d9TexFmtArray3s;
1275            TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtArray3s);
1276        }
1277        else if(IsFloat)
1278        {
1279            if(BitsPerCompCnt > 0 && BitsPerCompCnt <= 16)
1280            {
1281                TexFmtArray = s3d_DrvD3d9TexFmtArray3f16;
1282                TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtArray3f16);
1283            }
1284            else
1285            {
1286                TexFmtArray = s3d_DrvD3d9TexFmtArray3f32;
1287                TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtArray3f32);
1288            }
1289        }
1290    }
1291    else
1292    {
1293        TexFmtArray = s3d_DrvD3d9TexFmtArray4u;
1294        TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtArray4u);
1295        if(IsSigned)
1296        {
1297            TexFmtArray = s3d_DrvD3d9TexFmtArray4s;
1298            TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtArray4s);
1299        }
1300        else if(IsFloat)
1301        {
1302            if(BitsPerCompCnt > 0 && BitsPerCompCnt <= 16)
1303            {
1304                TexFmtArray = s3d_DrvD3d9TexFmtArray4f16;
1305                TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtArray4f16);
1306            }
1307            else
1308            {
1309                TexFmtArray = s3d_DrvD3d9TexFmtArray4f32;
1310                TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtArray4f32);
1311            }
1312        }
1313    }
1314    if(IsCompr)
1315    {
1316        if(!IsDepth && !IsRT)
1317        {
1318            if(CompCnt < 4)
1319            {
1320                TexFmtArray = s3d_DrvD3d9TexFmtCompr123;
1321                TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtCompr123);
1322            }
1323            else
1324            {
1325                TexFmtArray = s3d_DrvD3d9TexFmtCompr4;
1326                TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtCompr4);
1327            }
1328        }
1329    }
1330
1331    const s3d_CDrvD3d9Param* Param = m_D3dCtx->m_D3dParam;
1332    s3d_CDrvD3d9Env *Env = m_D3dCtx->m_Env;
1333    LPDIRECT3D9 D3d = m_D3dCtx->m_D3d;
1334    UINT Adapter = m_D3dCtx->m_Adapter;
1335    D3DDEVTYPE DevType = m_D3dCtx->m_DevType;
1336    if(IsDepth && Param->m_NVDepthTexEnabled)
1337    {
1338        HRESULT Result;
1339        S3D_DRV_D3D9_HRESCALL(
1340                Env, Result, D3d->CheckDeviceFormat(
1341                    Adapter, DevType, m_AdapterMode.Format,
1342                    D3DUSAGE_DEPTHSTENCIL, ResType, D3DFMT_D24S8));
1343        if(SUCCEEDED(Result))
1344        {
1345            FmtDepth = D3DFMT_D24S8;
1346            Usage = D3DUSAGE_DEPTHSTENCIL;
1347            AutoMipmap = false;
1348        }
1349    }
1350
1351    if(FmtDepth == D3DFMT_UNKNOWN)
1352    {
1353        s3d_CSysIntps i;
1354        for(i = 0; i < TexFmtCnt; i++)
1355        {
1356            FmtCol = TexFmtArray[i];
1357            HRESULT Result;
1358            S3D_DRV_D3D9_HRESCALL(
1359                    Env, Result, D3d->CheckDeviceFormat(
1360                        Adapter, DevType, m_AdapterMode.Format,
1361                        Usage, ResType, FmtCol));
1362            if(SUCCEEDED(Result))
1363            {
1364                if(Result == D3DOK_NOAUTOGEN)
1365                    AutoMipmap = false;
1366               
1367                S3D_DRV_D3D9_HRESCALL(
1368                        Env, Result, D3d->CheckDeviceFormat(
1369                            Adapter, DevType, m_AdapterMode.Format,
1370                            D3DUSAGE_QUERY_FILTER, ResType, FmtCol));
1371                if(FAILED(Result))
1372                    CanFilter = false;
1373               
1374                S3D_DRV_D3D9_HRESCALL(
1375                        Env, Result, D3d->CheckDeviceMultiSampleType(
1376                            Adapter, DevType, FmtCol, m_D3dCtx->m_Windowed,
1377                            m_D3dCtx->m_MultiSampleType, 0));
1378                if(FAILED(Result))
1379                    CanMultiSample = false;
1380               
1381                if(!Param->m_SRGBTexEnabled)
1382                    break;
1383                S3D_DRV_D3D9_HRESCALL(
1384                        Env, Result, D3d->CheckDeviceFormat(
1385                            Adapter, DevType, m_AdapterMode.Format,
1386                            D3DUSAGE_QUERY_SRGBREAD, ResType, FmtCol));
1387                if(SUCCEEDED(Result))
1388                    SRGBRead = true;
1389               
1390                S3D_DRV_D3D9_HRESCALL(
1391                        Env, Result, D3d->CheckDeviceFormat(
1392                            Adapter, DevType, m_AdapterMode.Format,
1393                            D3DUSAGE_QUERY_SRGBWRITE, ResType, FmtCol));
1394                if(SUCCEEDED(Result))
1395                    SRGBWrite = true;
1396                break;
1397            }
1398            FmtCol = D3DFMT_UNKNOWN;
1399        }
1400
1401        // Something went wrong, select a format that is known to work.
1402        if(FmtCol == D3DFMT_UNKNOWN)
1403            FmtCol = m_D3dCtx->m_BackBufFmt;
1404    }
1405    D3DTEXTUREFILTERTYPE FilterMipGen = D3DTEXF_NONE;
1406    if(AutoMipmap)
1407    {
1408        FilterMipGen = D3DTEXF_POINT;
1409        if(CanFilter)
1410        {
1411            FilterMipGen = D3DTEXF_LINEAR;
1412            if((TexProp & s3d_CDrvGfxEng::TexProp_Cube) != 0)
1413            {
1414                if(m_DevCaps.CubeTextureFilterCaps &
1415                        D3DPTFILTERCAPS_MINFANISOTROPIC)
1416                    FilterMipGen = D3DTEXF_ANISOTROPIC;
1417            }
1418            else if((TexProp & s3d_CDrvGfxEng::TexProp_Volume) != 0)
1419            {
1420                if(m_DevCaps.VolumeTextureFilterCaps &
1421                        D3DPTFILTERCAPS_MINFANISOTROPIC)
1422                    FilterMipGen = D3DTEXF_ANISOTROPIC;
1423            }
1424            else
1425            {
1426                if(m_DevCaps.TextureFilterCaps &
1427                        D3DPTFILTERCAPS_MINFANISOTROPIC)
1428                    FilterMipGen = D3DTEXF_ANISOTROPIC;
1429            }
1430        }
1431    }
1432
1433    TexFmt.m_FmtCol = FmtCol;
1434    TexFmt.m_FmtDepth = FmtDepth;
1435    TexFmt.m_FilterMipGen = FilterMipGen;
1436    TexFmt.m_CanFilter = CanFilter;
1437    TexFmt.m_CanMultiSample = CanMultiSample;
1438    TexFmt.m_Usage = Usage;
1439    TexFmt.m_SRGBRead = SRGBRead;
1440    TexFmt.m_SRGBWrite = SRGBWrite;
1441}
1442
1443///////////////////////////////////////////////////////////////////////////////
1444
1445//@
1446static const D3DCUBEMAP_FACES s3d_CDrvD3d9ubeMapFaceTable[] =
1447{
1448    D3DCUBEMAP_FACE_NEGATIVE_X, D3DCUBEMAP_FACE_POSITIVE_X,
1449    D3DCUBEMAP_FACE_NEGATIVE_Y, D3DCUBEMAP_FACE_POSITIVE_Y,
1450    D3DCUBEMAP_FACE_NEGATIVE_Z, D3DCUBEMAP_FACE_POSITIVE_Z,
1451};
1452
1453D3DCUBEMAP_FACES s3d_CDrvD3d9TexMgr::GetFaceOfPart(int Part)
1454{
1455    D3DCUBEMAP_FACES CubeFace = D3DCUBEMAP_FACE_NEGATIVE_X;
1456    if(Part >=0 && Part < 6)
1457        CubeFace = s3d_CDrvD3d9ubeMapFaceTable[Part];
1458    return CubeFace;
1459}
1460
1461int s3d_CDrvD3d9TexMgr::CompCntOfTexProp(
1462        int TexProp)
1463{
1464    if(TexProp & s3d_CDrvGfxEng::TexProp_Comp4)
1465        return 4;
1466    if(TexProp & s3d_CDrvGfxEng::TexProp_Comp3)
1467        return 3;
1468    if(TexProp & s3d_CDrvGfxEng::TexProp_Comp2)
1469        return 2;
1470    if(TexProp & s3d_CDrvGfxEng::TexProp_Comp1)
1471        return 1;
1472    return 0;
1473}
1474
1475int s3d_CDrvD3d9TexMgr::BitsPerCompCntOfTexProp(
1476        int TexProp)
1477{
1478    if(TexProp & s3d_CDrvGfxEng::TexProp_BitsPerComp32)
1479        return 32;
1480    if(TexProp & s3d_CDrvGfxEng::TexProp_BitsPerComp16)
1481        return 16;
1482    if(TexProp & s3d_CDrvGfxEng::TexProp_BitsPerComp8)
1483        return 8;
1484    return 0;
1485}
1486
1487void s3d_CDrvD3d9TexMgr::CopyTexData2D(
1488        s3d_CSysIntm *&DestData, s3d_CSysIntps Stride,
1489        int Width, int Height, const s3d_CDrvGfxPixel *SrcData)
1490{
1491    int LoopX, LoopY;
1492    for(LoopY = Height; LoopY > 0; LoopY--)
1493    {
1494        void *DestLine = DestData;
1495        (s3d_CSysIntm*&)DestData += Stride;
1496        for(LoopX = Width; LoopX > 0; LoopX--)
1497        {
1498            s3d_CDrvGfxPixel SrcPixel = *SrcData++;
1499            s3d_CSysInt32u DestPixel = (SrcPixel & 0xff00ff00)
1500                            | _rotl(SrcPixel & 0x00ff00ff, 16);
1501            *((s3d_CSysInt32u*&)DestLine)++ = DestPixel;
1502        }
1503    }
1504}
1505
1506
1507///////////////////////////////////////////////////////////////////////////////
1508
Note: See TracBrowser for help on using the repository browser.