/////////////////////////////////////////////////////////////////////////////// // // ## ###### // ###### ### // ## ############### Shark 3D Engine (www.shark3d.com) // ########## # # # // ######## Copyright (c) 1996-2006 Spinor GmbH. // ######### # # # All rights reserved. // ## ########## // ## // /////////////////////////////////////////////////////////////////////////////// //@cpp #include "drv_d3d9_tex.h" #include "drv_d3d9_util.h" #include "drv/util/drv_util_gfxutil.h" #include "util/stream/util_streambin.h" #include "sys/core/sys_util.h" /////////////////////////////////////////////////////////////////////////////// S3D_UTIL_RECOG_DEFINEINFO(s3d_CDrvD3d9TexObjBase); s3d_CDrvD3d9TexObjBase::s3d_CDrvD3d9TexObjBase() { S3D_UTIL_RECOG_INITOBJ(s3d_CDrvD3d9TexObjBase); m_Node.m_Data = this; } s3d_CDrvD3d9TexObjBase::~s3d_CDrvD3d9TexObjBase() { s3d_CDrvD3d9Param *D3dParam = 0; if(m_D3dCtx) D3dParam = m_D3dCtx->m_D3dParam; if(D3dParam && D3dParam->m_ReportTex) { s3d_CUtilMsg m; m.m_Code = "drv/imp/directx/d3d9/drv_d3d9_tex.report_tex_destroy"; m.m_StdTempl = "D3D: " "Destroying texture Addr=[1]. "; m.AddInfo(""); m.AddInfo(s3d_CUtilStrUtil::StrOfPtr(this)); s3d_UtilMsgReportNote(m_D3dCtx->m_MsgHandler, m); } m_Node.Extract(); } void s3d_CDrvD3d9TexObjBase::LoadData( int Part, int Mipmap, int Width, int Height, int Depth, const s3d_CDrvGfxPixel *Data) { if(!Data) return; if(!m_BaseTex) return; D3DFORMAT FmtCol = s3d_CDrvD3d9Util::LinearFmtOfSwizzledFmt( m_TexFmt.m_FmtCol); if(FmtCol != D3DFMT_X8R8G8B8 && FmtCol != D3DFMT_A8R8G8B8) { s3d_CDrvD3d9Device D3dDev; S3D_DRV_D3D9_CHECK( m_D3dCtx->m_Env, m_BaseTex->GetDevice(&D3dDev.EmptyRef())); if(!D3dDev) return; s3d_CDrvD3d9Surf TmpSurf; S3D_DRV_D3D9_CHECK( m_D3dCtx->m_Env, D3dDev->CreateOffscreenPlainSurface( Width, Height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &TmpSurf.EmptyRef(), 0)); if(!TmpSurf) return; DWORD Flags = 0; D3DLOCKED_RECT LockRect; S3D_DRV_D3D9_CHECK( m_D3dCtx->m_Env, TmpSurf->LockRect(&LockRect, 0, Flags)); s3d_CSysIntm *DestData = reinterpret_cast(LockRect.pBits); if(!DestData) return; s3d_CSysIntps Stride = LockRect.Pitch; s3d_CDrvD3d9TexMgr::CopyTexData2D( DestData, Stride, Width, Height, Data); S3D_DRV_D3D9_CHECK( m_D3dCtx->m_Env, TmpSurf->UnlockRect()); S3D_DRV_D3D9_CHECK( m_D3dCtx->m_Env, D3dLoadData( Part, Mipmap, Width, Height, Depth, TmpSurf)); } else { S3D_DRV_D3D9_CHECK( m_D3dCtx->m_Env, D3dLoadData( Part, Mipmap, Width, Height, Depth, Data)); } if((m_Prop & s3d_CDrvGfxEng::TexProp_Mipmap) != 0 && (m_Prop & s3d_CDrvGfxEng::TexProp_RestrUsage) == 0) { if(m_TexFmt.m_FilterMipGen != D3DTEXF_NONE) { S3D_DRV_D3D9_CHECK( m_D3dCtx->m_Env, m_BaseTex->SetAutoGenFilterType( m_TexFmt.m_FilterMipGen)); m_BaseTex->GenerateMipSubLevels(); } else if(m_Pool != D3DPOOL_DEFAULT || (m_TexFmt.m_Usage & D3DUSAGE_DYNAMIC) != 0) { // Textures created in the default pool ( // D3DPOOL_DEFAULT) cannot be // used with D3DXFilterTexture ( // unless created with D3DUSAGE_DYNAMIC) int MipLevel = Mipmap - 1; if(MipLevel < 0) MipLevel = 0; PALETTEENTRY *Palette = 0; S3D_DRV_D3D9_CHECK( m_D3dCtx->m_Env, D3DXFilterTexture( m_BaseTex, Palette, MipLevel, D3DX_FILTER_LINEAR)); } } if(m_D3dCtx->m_D3dParam->m_PreloadResources && m_Pool == D3DPOOL_MANAGED) { S3D_DRV_D3D9_CALL(m_D3dCtx->m_Env, m_BaseTex->PreLoad()); } } void s3d_CDrvD3d9TexObjBase::UpdateToFrm( s3d_CSysInt32u FrmIdx) { } bool s3d_CDrvD3d9TexObjBase::IsVideoTex() { return false; } /////////////////////////////////////////////////////////////////////////////// s3d_CDrvD3d9TexObj::s3d_CDrvD3d9TexObj( s3d_CDrvD3d9Ctx *D3dCtx, int TexProp, int Width, int Height, const s3d_CDrvD3d9TexFmt &TexFmt, D3DPOOL Pool) { m_D3dCtx = D3dCtx; m_Prop = TexProp; m_Width = Width; m_Height = Height; m_Depth = 1; m_TexFmt = TexFmt; m_Pool = Pool; AllocTex(); } s3d_CDrvD3d9TexObj::s3d_CDrvD3d9TexObj( s3d_CDrvD3d9Ctx *D3dCtx, int TexProp, int Width, int Height, const s3d_CDrvD3d9TexFmt &TexFmt, D3DPOOL Pool, LPDIRECT3DTEXTURE9 D3dTex) { m_D3dCtx = D3dCtx; m_Prop = TexProp; m_Width = Width; m_Height = Height; m_Depth = 1; m_TexFmt = TexFmt; m_Pool = Pool; m_BaseTex = D3dTex; m_D3dTex = D3dTex; } void s3d_CDrvD3d9TexObj::AllocTex() { m_BaseTex.Reset(); m_D3dTex.Reset(); int MipLevels = 1; if((m_Prop & s3d_CDrvGfxEng::TexProp_Mipmap) != 0) MipLevels = m_D3dCtx->m_D3dParam->m_MaxMipLevels; if((m_Prop & s3d_CDrvGfxEng::TexProp_RestrUsage) != 0) { //S3D_SYS_ASSERT((m_Prop & s3d_CDrvGfxEng::TexProp_Filter) == 0); S3D_SYS_ASSERT((m_Prop & s3d_CDrvGfxEng::TexProp_Mipmap) == 0); } // If color format is unknown, its a NVIDIA depthtex. D3DFORMAT D3dTexFmt = m_TexFmt.m_FmtCol; if(D3dTexFmt == D3DFMT_UNKNOWN) D3dTexFmt = m_TexFmt.m_FmtDepth; S3D_DRV_D3D9_CHECK( m_D3dCtx->m_Env, m_D3dCtx->m_D3dDev->CreateTexture( m_Width, m_Height, MipLevels, m_TexFmt.m_Usage, D3dTexFmt, m_Pool, &m_D3dTex.EmptyRef(), 0)); m_BaseTex = m_D3dTex; } HRESULT s3d_CDrvD3d9TexObj::D3dLoadData( int Part, int Mipmap, int Width, int Height, int Depth, const s3d_CDrvGfxPixel *Data) { if(!m_D3dTex) return D3DERR_INVALIDCALL; int MipLevel = Mipmap - 1; if(MipLevel < 0) MipLevel = 0; DWORD Flags = 0; D3DLOCKED_RECT LockRect; HRESULT Result = m_D3dTex->LockRect(MipLevel, &LockRect, 0, Flags); s3d_CSysIntm *DestData = reinterpret_cast(LockRect.pBits); if(DestData) { s3d_CSysIntps Stride = LockRect.Pitch; s3d_CDrvD3d9TexMgr::CopyTexData2D( DestData, Stride, Width, Height, Data); Result = m_D3dTex->UnlockRect(MipLevel); } return Result; } HRESULT s3d_CDrvD3d9TexObj::D3dLoadData( int Part, int Mipmap, int Width, int Height, int Depth, LPDIRECT3DSURFACE9 SrcSurf) { if(!m_D3dTex) return D3DERR_INVALIDCALL; int MipLevel = Mipmap - 1; if(MipLevel < 0) MipLevel = 0; s3d_CDrvD3d9Surf DestSurf; HRESULT Result = m_D3dTex->GetSurfaceLevel(MipLevel, &DestSurf.EmptyRef()); if(DestSurf) { Result = D3DXLoadSurfaceFromSurface( DestSurf, 0, 0, SrcSurf, 0, 0, D3DX_FILTER_NONE, 0); } return Result; } HRESULT s3d_CDrvD3d9TexObj::GetRenderTarget( s3d_CDrvD3d9Surf &DestSurf, const s3d_CDrvGfxDest *GfxDest) { DestSurf.Reset(); if(!m_D3dTex) return D3DERR_INVALIDCALL; HRESULT Result = m_D3dTex->GetSurfaceLevel(0, &DestSurf.EmptyRef()); return Result; } void s3d_CDrvD3d9TexObj::Park() { if(m_Pool == D3DPOOL_DEFAULT) { m_BaseTex.Reset(); m_D3dTex.Reset(); } } void s3d_CDrvD3d9TexObj::Unpark() { if(m_Pool == D3DPOOL_DEFAULT) AllocTex(); } /////////////////////////////////////////////////////////////////////////////// s3d_CDrvD3d9TexCubeObj::s3d_CDrvD3d9TexCubeObj( s3d_CDrvD3d9Ctx *D3dCtx, int TexProp, int Width, int Height, const s3d_CDrvD3d9TexFmt &TexFmt, D3DPOOL Pool) { m_D3dCtx = D3dCtx; m_Prop = TexProp; m_Width = Width; m_Height = Height; m_Depth = 1; m_TexFmt = TexFmt; m_Pool = Pool; AllocTex(); } s3d_CDrvD3d9TexCubeObj::s3d_CDrvD3d9TexCubeObj( s3d_CDrvD3d9Ctx *D3dCtx, int TexProp, int Width, int Height, const s3d_CDrvD3d9TexFmt &TexFmt, D3DPOOL Pool, LPDIRECT3DCUBETEXTURE9 D3dCubeTex) { m_D3dCtx = D3dCtx; m_Prop = TexProp; m_Width = Width; m_Height = Height; m_Depth = 1; m_TexFmt = TexFmt; m_Pool = Pool; m_BaseTex = D3dCubeTex; m_D3dCubeTex = D3dCubeTex; } void s3d_CDrvD3d9TexCubeObj::AllocTex() { m_BaseTex.Reset(); m_D3dCubeTex.Reset(); int MipLevels = 1; if((m_Prop & s3d_CDrvGfxEng::TexProp_Mipmap) != 0) MipLevels = m_D3dCtx->m_D3dParam->m_MaxMipLevels; UINT EdgeLength = s3d_SysMax(m_Width, m_Height); S3D_DRV_D3D9_CHECK( m_D3dCtx->m_Env, m_D3dCtx->m_D3dDev->CreateCubeTexture( EdgeLength, MipLevels, m_TexFmt.m_Usage, m_TexFmt.m_FmtCol, m_Pool, &m_D3dCubeTex.EmptyRef(), 0)); m_BaseTex = m_D3dCubeTex; } HRESULT s3d_CDrvD3d9TexCubeObj::D3dLoadData( int Part, int Mipmap, int Width, int Height, int Depth, const s3d_CDrvGfxPixel *Data) { if(!m_D3dCubeTex) return D3DERR_INVALIDCALL; int MipLevel = Mipmap - 1; if(MipLevel < 0) MipLevel = 0; D3DCUBEMAP_FACES CubeFace = s3d_CDrvD3d9TexMgr::GetFaceOfPart(Part); DWORD Flags = 0; D3DLOCKED_RECT LockRect; HRESULT Result = m_D3dCubeTex->LockRect( CubeFace, MipLevel, &LockRect, 0, Flags); s3d_CSysIntm *DestData = reinterpret_cast(LockRect.pBits); if(DestData) { s3d_CSysIntps Stride = LockRect.Pitch; s3d_CDrvD3d9TexMgr::CopyTexData2D( DestData, Stride, Width, Height, Data); Result = m_D3dCubeTex->UnlockRect(CubeFace, MipLevel); } return Result; } HRESULT s3d_CDrvD3d9TexCubeObj::D3dLoadData( int Part, int Mipmap, int Width, int Height, int Depth, LPDIRECT3DSURFACE9 SrcSurf) { if(!m_D3dCubeTex) return D3DERR_INVALIDCALL; int MipLevel = Mipmap - 1; if(MipLevel < 0) MipLevel = 0; D3DCUBEMAP_FACES CubeFace = s3d_CDrvD3d9TexMgr::GetFaceOfPart(Part); s3d_CDrvD3d9Surf DestSurf; HRESULT Result = m_D3dCubeTex->GetCubeMapSurface( CubeFace, MipLevel, &DestSurf.EmptyRef()); if(DestSurf) { Result = D3DXLoadSurfaceFromSurface( DestSurf, 0, 0, SrcSurf, 0, 0, D3DX_FILTER_NONE, 0); } return Result; } HRESULT s3d_CDrvD3d9TexCubeObj::GetRenderTarget( s3d_CDrvD3d9Surf &DestSurf, const s3d_CDrvGfxDest *Dest) { DestSurf.Reset(); if(!m_D3dCubeTex) return D3DERR_INVALIDCALL; D3DCUBEMAP_FACES CubeFace = s3d_CDrvD3d9TexMgr::GetFaceOfPart( Dest->m_Part); HRESULT Result = m_D3dCubeTex->GetCubeMapSurface( CubeFace, 0, &DestSurf.EmptyRef()); return Result; } void s3d_CDrvD3d9TexCubeObj::Park() { if(m_Pool == D3DPOOL_DEFAULT) { m_BaseTex.Reset(); m_D3dCubeTex.Reset(); } } void s3d_CDrvD3d9TexCubeObj::Unpark() { if(m_Pool == D3DPOOL_DEFAULT) AllocTex(); } /////////////////////////////////////////////////////////////////////////////// s3d_CDrvD3d9TexVolObj::s3d_CDrvD3d9TexVolObj( s3d_CDrvD3d9Ctx *D3dCtx, int TexProp, int Width, int Height, int Depth, const s3d_CDrvD3d9TexFmt &TexFmt, D3DPOOL Pool, LPDIRECT3DVOLUMETEXTURE9 D3dVolTex) { m_D3dCtx = D3dCtx; m_Prop = TexProp; m_Width = Width; m_Height = Height; m_Depth = Depth; m_TexFmt = TexFmt; m_Pool = Pool; m_BaseTex = D3dVolTex; m_D3dVolTex = D3dVolTex; } void s3d_CDrvD3d9TexVolObj::AllocTex() { } HRESULT s3d_CDrvD3d9TexVolObj::D3dLoadData( int Part, int Mipmap, int Width, int Height, int Depth, const s3d_CDrvGfxPixel *SrcData) { return 0; } HRESULT s3d_CDrvD3d9TexVolObj::D3dLoadData( int Part, int Mipmap, int Width, int Height, int Depth, LPDIRECT3DSURFACE9 SrcSurf) { return 0; } HRESULT s3d_CDrvD3d9TexVolObj::GetRenderTarget( s3d_CDrvD3d9Surf &DestSurf, const s3d_CDrvGfxDest *GfxDest) { return 0; } bool s3d_CDrvD3d9TexVolObj::IsVideoTex() { return false; } void s3d_CDrvD3d9TexVolObj::UpdateToFrm( s3d_CSysInt32u FrmIdx) { } void s3d_CDrvD3d9TexVolObj::Park() { } void s3d_CDrvD3d9TexVolObj::Unpark() { } /////////////////////////////////////////////////////////////////////////////// s3d_CDrvD3d9TexObjVideo::s3d_CDrvD3d9TexObjVideo( s3d_CDrvD3d9Ctx *D3dCtx, s3d_CDrvVideoPlayer *VideoPlayer, int TexProp, bool NeedSnap, const s3d_CDrvD3d9TexFmt &TexFmt, D3DPOOL Pool) { m_D3dCtx = D3dCtx; m_VideoPlayer = VideoPlayer; m_Prop = TexProp; m_NeedSnap = NeedSnap; m_Width = 0; m_Height = 0; m_Depth = 1; m_TexFmt = TexFmt; m_Pool = Pool; m_VideoWidth = 0; m_VideoHeight = 0; m_LastFrmIdx = -1; int Format = CalcVideoFormat(VideoPlayer); if(VideoPlayer) VideoPlayer->Appoint(Format, false); UpdateToFrm(0); } void s3d_CDrvD3d9TexObjVideo::AllocTex() { m_BaseTex.Reset(); m_D3dTex.Reset(); int MipLevels = 1; D3DFORMAT D3dTexFmt = m_TexFmt.m_FmtCol; if(D3dTexFmt == D3DFMT_UNKNOWN) return; S3D_DRV_D3D9_CHECK( m_D3dCtx->m_Env, m_D3dCtx->m_D3dDev->CreateTexture( m_Width, m_Height, MipLevels, m_TexFmt.m_Usage, D3dTexFmt, m_Pool, &m_D3dTex.EmptyRef(), 0)); m_BaseTex = m_D3dTex; } HRESULT s3d_CDrvD3d9TexObjVideo::D3dLoadData( int Part, int Mipmap, int Width, int Height, int Depth, const s3d_CDrvGfxPixel *Data) { return D3DERR_INVALIDCALL; } HRESULT s3d_CDrvD3d9TexObjVideo::D3dLoadData( int Part, int Mipmap, int Width, int Height, int Depth, LPDIRECT3DSURFACE9 SrcSurf) { return D3DERR_INVALIDCALL; } HRESULT s3d_CDrvD3d9TexObjVideo::GetRenderTarget( s3d_CDrvD3d9Surf &DestSurf, const s3d_CDrvGfxDest *GfxDest) { DestSurf.Reset(); return D3DERR_INVALIDCALL; } bool s3d_CDrvD3d9TexObjVideo::IsVideoTex() { return true; } void s3d_CDrvD3d9TexObjVideo::UpdateToFrm( s3d_CSysInt32u FrmIdx) { if(!m_VideoPlayer) return; if(!m_VideoPlayer->IsAvail()) return; int VideoWidth = 0; int VideoHeight = 0; m_VideoPlayer->GetSize(VideoWidth, VideoHeight); if(!m_D3dTex || VideoWidth != m_VideoWidth || VideoHeight != m_VideoHeight) SetVideoSize(VideoWidth, VideoHeight); // SetVideoSize internally call AllocTex and when it fails // m_D3dTex might be invalid, hence check again. if(!m_D3dTex) return; s3d_CSysInt32u DeltaFrmIdx = FrmIdx - m_LastFrmIdx; if(DeltaFrmIdx == 0) return; m_LastFrmIdx = FrmIdx; bool HadPause = (DeltaFrmIdx > 1); int PosX = (m_Width - m_VideoWidth) >> 1; int PosY = (m_Height - m_VideoHeight) >> 1; RECT Rect; Rect.left = PosX; Rect.top = PosY; Rect.right = PosX + m_VideoWidth; Rect.bottom = PosY + m_VideoHeight; UINT Level = 0; D3DLOCKED_RECT LockRect; S3D_DRV_D3D9_CHECK( m_D3dCtx->m_Env, m_D3dTex->LockRect( Level, &LockRect, &Rect, 0)); s3d_CDrvVideoSurf VideoSurf; VideoSurf.m_Width = m_VideoWidth; VideoSurf.m_Height = m_VideoHeight; VideoSurf.m_Stride = LockRect.Pitch; VideoSurf.m_Format = s3d_CDrvVideoPlayer::Format_B8G8R8A8; VideoSurf.m_Data = reinterpret_cast(LockRect.pBits); m_VideoPlayer->TransferPerform(VideoSurf, HadPause); S3D_DRV_D3D9_CHECK( m_D3dCtx->m_Env, m_D3dTex->UnlockRect(Level)); } void s3d_CDrvD3d9TexObjVideo::Park() { if(m_Pool == D3DPOOL_DEFAULT) { m_BaseTex.Reset(); m_D3dTex.Reset(); } } void s3d_CDrvD3d9TexObjVideo::Unpark() { if(m_Pool == D3DPOOL_DEFAULT) AllocTex(); } void s3d_CDrvD3d9TexObjVideo::SetVideoSize( int VideoWidth, int VideoHeight) { int TexWidth = VideoWidth; int TexHeight = VideoHeight; SnapVideoSize(TexWidth, TexHeight); if(m_Width != TexWidth || m_Height != TexHeight) { m_Width = TexWidth; m_Height = TexHeight; AllocTex(); } m_VideoWidth = VideoWidth; m_VideoHeight = VideoHeight; } void s3d_CDrvD3d9TexObjVideo::SnapVideoSize( int &Width, int &Height) { if(m_NeedSnap) { Width = (1 << s3d_CDrvUtilGfxUtil::BinLogDownInt(Width)); Height = (1 << s3d_CDrvUtilGfxUtil::BinLogDownInt(Height)); } s3d_SysSetToMax(Width, 1); s3d_SysSetToMax(Height, 1); } int s3d_CDrvD3d9TexObjVideo::CalcVideoFormat( s3d_CDrvVideoPlayer *VideoPlayer) { if(!VideoPlayer) return 0; if(VideoPlayer->TransferLikesFormat(s3d_CDrvVideoPlayer::Format_B8G8R8A8)) return s3d_CDrvVideoPlayer::Format_B8G8R8A8; if(VideoPlayer->TransferLikesFormat(s3d_CDrvVideoPlayer::Format_B8G8R8)) return s3d_CDrvVideoPlayer::Format_B8G8R8; if(VideoPlayer->TransferSupportsFormat( s3d_CDrvVideoPlayer::Format_B8G8R8A8)) return s3d_CDrvVideoPlayer::Format_B8G8R8A8; if(VideoPlayer->TransferSupportsFormat(s3d_CDrvVideoPlayer::Format_B8G8R8)) return s3d_CDrvVideoPlayer::Format_B8G8R8; return 0; } /////////////////////////////////////////////////////////////////////////////// s3d_CDrvD3d9TexMgr::s3d_CDrvD3d9TexMgr( s3d_CDrvD3d9Ctx *D3dCtx) { m_D3dCtx = D3dCtx; s3d_SysMemset(&m_AdapterMode, 0, S3D_SYS_SIZEOFS(m_AdapterMode)); S3D_DRV_D3D9_CHECK( m_D3dCtx->m_Env, m_D3dCtx->m_D3d->GetAdapterDisplayMode( m_D3dCtx->m_Adapter, &m_AdapterMode)); s3d_SysMemset(&m_DevCaps, 0, S3D_SYS_SIZEOFS(m_DevCaps)); S3D_DRV_D3D9_CHECK( m_D3dCtx->m_Env, m_D3dCtx->m_D3dDev->GetDeviceCaps(&m_DevCaps)); } s3d_CDrvD3d9TexMgr::~s3d_CDrvD3d9TexMgr() { } s3d_CDrvGfxTexPtr s3d_CDrvD3d9TexMgr::CreateTexDirect( s3d_CUtilStr_cr Info, int TexProp, int Width, int Height, int Depth) { int EffTexProp = TexProp; const s3d_CDrvD3d9Param *D3dParam = m_D3dCtx->m_D3dParam; if(D3dParam->m_MinTexComprWidth > 0 && D3dParam->m_MinTexComprHeight > 0 && Width > D3dParam->m_MinTexComprWidth && Height > D3dParam->m_MinTexComprHeight) { EffTexProp |= s3d_CDrvGfxEng::TexProp_Compress; } s3d_CDrvD3d9TexFmt TexFmt; FindTexFmt(TexFmt, EffTexProp); s3d_CDrvD3d9TexObjBasePtr TexObjBase = CreateTexDirectFmt( Info, EffTexProp, TexFmt, Width, Height, Depth, 0); if(!TexObjBase) return 0; m_TexList.InsertBack(&TexObjBase->m_Node); if(D3dParam->m_ReportTex) { s3d_CUtilMsg m; m.m_Code = "drv/imp/directx/d3d9/drv_d3d9_tex.report_tex_create"; m.m_StdTempl = "D3D: " "Creating texture Addr=[1] '[2]': " "[3]x[4]x[5] Prop='[6]' ColFmt=[7] DepthFmt=[8]."; m.AddInfo(""); m.AddInfo(s3d_CUtilStrUtil::StrOfPtr(TexObjBase)); m.AddInfo(Info); m.AddInfo(s3d_CUtilStrUtil::StrOfInt(Width)); m.AddInfo(s3d_CUtilStrUtil::StrOfInt(Height)); m.AddInfo(s3d_CUtilStrUtil::StrOfInt(Depth)); m.AddInfo(s3d_CDrvUtilGfxUtil::CalcStrOfTexProp(TexProp)); m.AddInfo(s3d_CDrvD3d9Util::StrOfFmt(TexFmt.m_FmtCol)); m.AddInfo(s3d_CDrvD3d9Util::StrOfFmt(TexFmt.m_FmtDepth)); s3d_UtilMsgReportNote(m_D3dCtx->m_MsgHandler, m); } return TexObjBase.Get(); } s3d_CDrvGfxTexPtr s3d_CDrvD3d9TexMgr::CreateTexStream( s3d_CUtilStr_cr Info, int TexProp, s3d_CUtilStream *Stream) { // Quick check format: if(!Stream) return 0; s3d_CUtilStreamPos StreamSize = Stream->GetSize(); /* if(StreamSize < 4) return 0; Stream->SetPos(0); DWORD DDSMagic = s3d_CUtilStreamBin::ReadInt32uLitEndian(Stream); if(DDSMagic != 0x20534444) //"DDS " return 0; */ // Load data: s3d_CUtilMemPoolFrm MemPoolFrm(m_D3dCtx->m_MemPool); UINT DataLen = UINT(StreamSize); s3d_CSysInt8u *Data = new(m_D3dCtx->m_MemPool) s3d_CSysInt8u[DataLen]; Stream->SetPos(0); Stream->Read(DataLen, Data); D3DXIMAGE_INFO ImageInfo; memset(&ImageInfo, 0, sizeof(ImageInfo)); HRESULT DxResult = D3D_OK; S3D_DRV_D3D9_HRESCALL(m_D3dCtx->m_Env, DxResult, D3DXGetImageInfoFromFileInMemory(Data, DataLen, &ImageInfo)); if(DxResult != D3D_OK) return 0; int Width = 0; int Height = 0; int Depth = 0; s3d_CDrvD3d9TexFmt TexFmt; int MipLevels = ImageInfo.MipLevels; if(TexProp & s3d_CDrvGfxEng::TexProp_Mipmap) MipLevels = 0; D3DRESOURCETYPE ResType = ImageInfo.ResourceType; s3d_CDrvD3d9TexObjBasePtr TexObjBase; switch(ResType) { case D3DRTYPE_TEXTURE: { s3d_CDrvD3d9Tex D3dTex; S3D_DRV_D3D9_CHECK(m_D3dCtx->m_Env, D3DXCreateTextureFromFileInMemoryEx( m_D3dCtx->m_D3dDev, Data, DataLen, 0, 0, MipLevels, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, 0, 0, &D3dTex.EmptyRef())); if(!D3dTex) return 0; HRESULT Result; D3DSURFACE_DESC SurfDesc; S3D_DRV_D3D9_CALLCHECK( m_D3dCtx->m_Env, Result, D3dTex->GetLevelDesc(0, &SurfDesc)); if(FAILED(Result)) return 0; Width = SurfDesc.Width; Height = SurfDesc.Height; Depth = 1; D3DPOOL Pool = SurfDesc.Pool; TexFmt.m_FmtCol = SurfDesc.Format; TexFmt.m_FmtDepth = D3DFMT_UNKNOWN; TexFmt.m_FilterMipGen = D3DTEXF_NONE; TexFmt.m_CanFilter = true; TexFmt.m_Usage = 0; TexFmt.m_SRGBRead = false; TexFmt.m_SRGBWrite = false; TexObjBase = S3D_SYS_NEW s3d_CDrvD3d9TexObj( m_D3dCtx, TexProp, Width, Height, TexFmt, Pool, D3dTex); } break; case D3DRTYPE_CUBETEXTURE: { s3d_CDrvD3d9CubeTex D3dCubeTex; S3D_DRV_D3D9_CHECK(m_D3dCtx->m_Env, D3DXCreateCubeTextureFromFileInMemoryEx( m_D3dCtx->m_D3dDev, Data, DataLen, 0, MipLevels, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, 0, 0, &D3dCubeTex.EmptyRef())); if(!D3dCubeTex) return 0; HRESULT Result; D3DSURFACE_DESC SurfDesc; S3D_DRV_D3D9_CALLCHECK( m_D3dCtx->m_Env, Result, D3dCubeTex->GetLevelDesc( 0, &SurfDesc)); if(FAILED(Result)) return 0; Width = SurfDesc.Width; Height = SurfDesc.Height; Depth = 1; D3DPOOL Pool = SurfDesc.Pool; TexFmt.m_FmtCol = SurfDesc.Format; TexFmt.m_FmtDepth = D3DFMT_UNKNOWN; TexFmt.m_FilterMipGen = D3DTEXF_NONE; TexFmt.m_CanFilter = true; TexFmt.m_Usage = 0; TexFmt.m_SRGBRead = false; TexFmt.m_SRGBWrite = false; TexObjBase = S3D_SYS_NEW s3d_CDrvD3d9TexCubeObj( m_D3dCtx, TexProp, Width, Height, TexFmt, Pool, D3dCubeTex); } break; case D3DRTYPE_VOLUMETEXTURE: { s3d_CDrvD3d9VolTex D3dVolTex; S3D_DRV_D3D9_CHECK(m_D3dCtx->m_Env, D3DXCreateVolumeTextureFromFileInMemoryEx( m_D3dCtx->m_D3dDev, Data, DataLen, 0, 0, 0, MipLevels, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, 0, 0, &D3dVolTex.EmptyRef())); if(!D3dVolTex) return 0; HRESULT Result; D3DVOLUME_DESC VolDesc; S3D_DRV_D3D9_CALLCHECK( m_D3dCtx->m_Env, Result, D3dVolTex->GetLevelDesc( 0, &VolDesc)); if(FAILED(Result)) return 0; Width = VolDesc.Width; Height = VolDesc.Height; Depth = VolDesc.Depth; D3DPOOL Pool = VolDesc.Pool; TexFmt.m_FmtCol = VolDesc.Format; TexFmt.m_FmtDepth = D3DFMT_UNKNOWN; TexFmt.m_FilterMipGen = D3DTEXF_NONE; TexFmt.m_CanFilter = true; TexFmt.m_Usage = 0; TexFmt.m_SRGBRead = false; TexFmt.m_SRGBWrite = false; TexObjBase = S3D_SYS_NEW s3d_CDrvD3d9TexVolObj( m_D3dCtx, TexProp, Width, Height, Depth, TexFmt, Pool, D3dVolTex); } break; default: return 0; } if(!TexObjBase) return 0; m_TexList.InsertBack(&TexObjBase->m_Node); if(m_D3dCtx->m_D3dParam->m_ReportTex) { s3d_CUtilMsg m; m.m_Code = "drv/imp/directx/d3d9/drv_d3d9_tex.report_tex_create"; m.m_StdTempl = "D3D: " "Creating texture Addr=[1] '[2]': " "[3]x[4]x[5] Prop='[6]' ColFmt=[7] DepthFmt=[8]."; m.AddInfo(""); m.AddInfo(s3d_CUtilStrUtil::StrOfPtr(TexObjBase)); m.AddInfo(Info); m.AddInfo(s3d_CUtilStrUtil::StrOfInt(Width)); m.AddInfo(s3d_CUtilStrUtil::StrOfInt(Height)); m.AddInfo(s3d_CUtilStrUtil::StrOfInt(Depth)); m.AddInfo(s3d_CDrvUtilGfxUtil::CalcStrOfTexProp(TexProp)); m.AddInfo(s3d_CDrvD3d9Util::StrOfFmt(TexFmt.m_FmtCol)); m.AddInfo(s3d_CDrvD3d9Util::StrOfFmt(TexFmt.m_FmtDepth)); s3d_UtilMsgReportNote(m_D3dCtx->m_MsgHandler, m); } return TexObjBase.Get(); } s3d_CDrvGfxTexPtr s3d_CDrvD3d9TexMgr::CreateTexVideo( s3d_CUtilStr_cr Info, int TexProp, s3d_CDrvVideoPlayer *VideoPlayer) { int Width = 0; int Height = 0; int Depth = 1; s3d_CDrvD3d9TexFmt TexFmt; FindTexFmt(TexFmt, TexProp); s3d_CDrvD3d9TexObjBasePtr TexObjBase = CreateTexDirectFmt( Info, TexProp, TexFmt, Width, Height, Depth, VideoPlayer); if(!TexObjBase) return 0; m_TexList.InsertBack(&TexObjBase->m_Node); if(m_D3dCtx->m_D3dParam->m_ReportTex) { s3d_CUtilMsg m; m.m_Code = "drv/imp/directx/d3d9/drv_d3d9_tex.report_tex_create"; m.m_StdTempl = "D3D: " "Creating video texture Addr=[1] '[2]': ColFmt=[3]."; m.AddInfo(""); m.AddInfo(s3d_CUtilStrUtil::StrOfPtr(TexObjBase)); m.AddInfo(Info); m.AddInfo(s3d_CDrvD3d9Util::StrOfFmt(TexFmt.m_FmtCol)); s3d_UtilMsgReportNote(m_D3dCtx->m_MsgHandler, m); } return TexObjBase.Get(); } void s3d_CDrvD3d9TexMgr::Park() { s3d_CDrvD3d9TexList::CNode *Node = m_TexList.GetFirst(); while(Node) { s3d_CDrvD3d9TexObjBase *Tex = Node->m_Data; Node = Node->GetNext(); if(Tex) Tex->Park(); } } void s3d_CDrvD3d9TexMgr::Unpark() { s3d_CDrvD3d9TexList::CNode *Node = m_TexList.GetFirst(); while(Node) { s3d_CDrvD3d9TexObjBase *Tex = Node->m_Data; Node = Node->GetNext(); if(Tex) Tex->Unpark(); } } /////////////////////////////////////////////////////////////////////////////// s3d_CDrvD3d9TexObjBasePtr s3d_CDrvD3d9TexMgr::CreateTexDirectFmt( s3d_CUtilStr_cr Info, int TexProp, const s3d_CDrvD3d9TexFmt &TexFmt, int Width, int Height, int Depth, s3d_CDrvVideoPlayer *VideoPlayer) { const s3d_CDrvD3d9Param *D3dParam = m_D3dCtx->m_D3dParam; int MipLevels = 1; if((TexProp & s3d_CDrvGfxEng::TexProp_Mipmap) != 0) MipLevels = D3dParam->m_MaxMipLevels; D3DPOOL Pool = D3DPOOL_MANAGED; if((TexProp & s3d_CDrvGfxEng::TexProp_RenderTarget) != 0 || (TexProp & s3d_CDrvGfxEng::TexProp_Depth) != 0) Pool = D3DPOOL_DEFAULT; s3d_CDrvD3d9TexObjBasePtr TexObjBase; if((TexProp & s3d_CDrvGfxEng::TexProp_Volume) != 0) { } else if((TexProp & s3d_CDrvGfxEng::TexProp_Cube) != 0) { if(Width <= 0 || Height <= 0) return 0; TexObjBase = S3D_SYS_NEW s3d_CDrvD3d9TexCubeObj( m_D3dCtx, TexProp, Width, Height, TexFmt, Pool); } else if(VideoPlayer) { bool CanRect = false; bool CanNPOT2 = false; if((m_DevCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) != 0) CanRect = true; if(!CanRect && (m_DevCaps.TextureCaps & D3DPTEXTURECAPS_POW2) == 0) CanNPOT2 = true; bool NeedSnap = true; if(CanRect || CanNPOT2) NeedSnap = false; TexObjBase = S3D_SYS_NEW s3d_CDrvD3d9TexObjVideo( m_D3dCtx, VideoPlayer, TexProp, NeedSnap, TexFmt, Pool); return TexObjBase; } else { if(Width <= 0 || Height <= 0) return 0; TexObjBase = S3D_SYS_NEW s3d_CDrvD3d9TexObj( m_D3dCtx, TexProp, Width, Height, TexFmt, Pool); } if(!TexObjBase) return 0; if(!TexObjBase->m_BaseTex) return 0; return TexObjBase; } void s3d_CDrvD3d9TexMgr::FindTexFmt( s3d_CDrvD3d9TexFmt &TexFmt, int TexProp) { if(!m_PropFmtMap.GetAtInto(TexProp, TexFmt)) { FmtOfTexProp(TexProp, TexFmt); m_PropFmtMap.SetAt(TexProp, TexFmt); } } static const D3DFORMAT s3d_DrvD3d9TexFmtArray1u[] = { /* D3DFMT_L16,*/ D3DFMT_L8, }; static const D3DFORMAT s3d_DrvD3d9TexFmtArray1s[] = { D3DFMT_V8U8, }; static const D3DFORMAT s3d_DrvD3d9TexFmtArray1f16[] = { D3DFMT_R16F }; static const D3DFORMAT s3d_DrvD3d9TexFmtArray1f32[] = { D3DFMT_R32F, D3DFMT_R16F }; static const D3DFORMAT s3d_DrvD3d9TexFmtArray2u[] = { D3DFMT_G16R16, }; static const D3DFORMAT s3d_DrvD3d9TexFmtArray2s[] = { /*D3DFMT_V16U16, */ D3DFMT_V8U8, }; static const D3DFORMAT s3d_DrvD3d9TexFmtArray2f16[] = { D3DFMT_G16R16F }; static const D3DFORMAT s3d_DrvD3d9TexFmtArray2f32[] = { D3DFMT_G32R32F, D3DFMT_G16R16F }; static const D3DFORMAT s3d_DrvD3d9TexFmtArray3u[] = { D3DFMT_X8R8G8B8, D3DFMT_R5G6B5, D3DFMT_X1R5G5B5 }; static const D3DFORMAT s3d_DrvD3d9TexFmtArray3s[] = { D3DFMT_X8L8V8U8, D3DFMT_L6V5U5 }; static const D3DFORMAT s3d_DrvD3d9TexFmtArray3f16[] = { D3DFMT_A16B16G16R16F }; static const D3DFORMAT s3d_DrvD3d9TexFmtArray3f32[] = { D3DFMT_A32B32G32R32F, D3DFMT_A16B16G16R16F }; static const D3DFORMAT s3d_DrvD3d9TexFmtArray4u[] = { D3DFMT_A8R8G8B8, D3DFMT_A1R5G5B5, D3DFMT_A4R4G4B4 }; static const D3DFORMAT s3d_DrvD3d9TexFmtArray4s[] = { D3DFMT_Q8W8V8U8 }; static const D3DFORMAT s3d_DrvD3d9TexFmtArray4f16[] = { D3DFMT_A16B16G16R16F }; static const D3DFORMAT s3d_DrvD3d9TexFmtArray4f32[] = { D3DFMT_A32B32G32R32F, D3DFMT_A16B16G16R16F }; static const D3DFORMAT s3d_DrvD3d9TexFmtDepth[] = { D3DFMT_R32F, D3DFMT_R16F, //D3DFMT_D24FS8 }; static const D3DFORMAT s3d_DrvD3d9TexFmtCompr123[] = { D3DFMT_DXT1 }; static const D3DFORMAT s3d_DrvD3d9TexFmtCompr4[] = { D3DFMT_DXT5 }; void s3d_CDrvD3d9TexMgr::FmtOfTexProp( int TexProp, s3d_CDrvD3d9TexFmt &TexFmt) { TexFmt.m_FmtCol = D3DFMT_UNKNOWN; TexFmt.m_FmtDepth = D3DFMT_UNKNOWN; TexFmt.m_FilterMipGen = D3DTEXF_NONE; TexFmt.m_CanFilter = true; TexFmt.m_Usage = 0; TexFmt.m_SRGBRead = false; TexFmt.m_SRGBWrite = false; D3DFORMAT FmtCol = D3DFMT_UNKNOWN; D3DFORMAT FmtDepth = D3DFMT_UNKNOWN; bool AutoMipmap = true; bool CanFilter = true; bool CanMultiSample = true; bool SRGBRead = false; bool SRGBWrite = false; bool IsRT = (TexProp & s3d_CDrvGfxEng::TexProp_RenderTarget) != 0; bool IsDepth = (TexProp & s3d_CDrvGfxEng::TexProp_Depth) != 0; bool IsSigned = (TexProp & s3d_CDrvGfxEng::TexProp_Signed) != 0; bool IsFloat = (TexProp & s3d_CDrvGfxEng::TexProp_Float) != 0; bool IsCompr = (TexProp & s3d_CDrvGfxEng::TexProp_Compress) != 0; bool IsVolTex = (TexProp & s3d_CDrvGfxEng::TexProp_Volume) != 0; bool IsCubeTex = (TexProp & s3d_CDrvGfxEng::TexProp_Cube) != 0; D3DRESOURCETYPE ResType = D3DRTYPE_TEXTURE; DWORD Usage = 0; if(TexProp & s3d_CDrvGfxEng::TexProp_Mipmap) Usage |= D3DUSAGE_AUTOGENMIPMAP; /* D3d dynamic textures might cause performance problems. See dx doc. if(TexProp & s3d_CDrvGfxEng::TexProp_Dynamic) Usage |= D3DUSAGE_DYNAMIC; */ if(IsDepth || IsRT) Usage |= D3DUSAGE_RENDERTARGET; if(IsVolTex) ResType = D3DRTYPE_VOLUMETEXTURE; else if(IsCubeTex) ResType = D3DRTYPE_CUBETEXTURE; const D3DFORMAT *TexFmtArray = 0; s3d_CSysIntps TexFmtCnt = 0; int CompCnt = CompCntOfTexProp(TexProp); int BitsPerCompCnt = BitsPerCompCntOfTexProp(TexProp); if(CompCnt == 1) { TexFmtArray = s3d_DrvD3d9TexFmtArray1u; TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtArray1u); if(IsSigned) { TexFmtArray = s3d_DrvD3d9TexFmtArray1s; TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtArray1s); } else if(IsFloat) { if(BitsPerCompCnt > 0 && BitsPerCompCnt <= 16) { TexFmtArray = s3d_DrvD3d9TexFmtArray1f16; TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtArray1f16); } else { TexFmtArray = s3d_DrvD3d9TexFmtArray1f32; TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtArray1f32); } } if(IsDepth) { TexFmtArray = s3d_DrvD3d9TexFmtDepth; TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtDepth); } } else if(CompCnt == 2) { TexFmtArray = s3d_DrvD3d9TexFmtArray2u; TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtArray2u); if(IsSigned) { TexFmtArray = s3d_DrvD3d9TexFmtArray2s; TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtArray2s); } else if(IsFloat) { if(BitsPerCompCnt > 0 && BitsPerCompCnt <= 16) { TexFmtArray = s3d_DrvD3d9TexFmtArray2f16; TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtArray2f16); } else { TexFmtArray = s3d_DrvD3d9TexFmtArray2f32; TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtArray2f32); } } } else if(CompCnt == 3) { TexFmtArray = s3d_DrvD3d9TexFmtArray3u; TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtArray3u); if(IsSigned) { TexFmtArray = s3d_DrvD3d9TexFmtArray3s; TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtArray3s); } else if(IsFloat) { if(BitsPerCompCnt > 0 && BitsPerCompCnt <= 16) { TexFmtArray = s3d_DrvD3d9TexFmtArray3f16; TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtArray3f16); } else { TexFmtArray = s3d_DrvD3d9TexFmtArray3f32; TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtArray3f32); } } } else { TexFmtArray = s3d_DrvD3d9TexFmtArray4u; TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtArray4u); if(IsSigned) { TexFmtArray = s3d_DrvD3d9TexFmtArray4s; TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtArray4s); } else if(IsFloat) { if(BitsPerCompCnt > 0 && BitsPerCompCnt <= 16) { TexFmtArray = s3d_DrvD3d9TexFmtArray4f16; TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtArray4f16); } else { TexFmtArray = s3d_DrvD3d9TexFmtArray4f32; TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtArray4f32); } } } if(IsCompr) { if(!IsDepth && !IsRT) { if(CompCnt < 4) { TexFmtArray = s3d_DrvD3d9TexFmtCompr123; TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtCompr123); } else { TexFmtArray = s3d_DrvD3d9TexFmtCompr4; TexFmtCnt = S3D_SYS_ARRAYCNTS(s3d_DrvD3d9TexFmtCompr4); } } } const s3d_CDrvD3d9Param* Param = m_D3dCtx->m_D3dParam; s3d_CDrvD3d9Env *Env = m_D3dCtx->m_Env; LPDIRECT3D9 D3d = m_D3dCtx->m_D3d; UINT Adapter = m_D3dCtx->m_Adapter; D3DDEVTYPE DevType = m_D3dCtx->m_DevType; if(IsDepth && Param->m_NVDepthTexEnabled) { HRESULT Result; S3D_DRV_D3D9_HRESCALL( Env, Result, D3d->CheckDeviceFormat( Adapter, DevType, m_AdapterMode.Format, D3DUSAGE_DEPTHSTENCIL, ResType, D3DFMT_D24S8)); if(SUCCEEDED(Result)) { FmtDepth = D3DFMT_D24S8; Usage = D3DUSAGE_DEPTHSTENCIL; AutoMipmap = false; } } if(FmtDepth == D3DFMT_UNKNOWN) { s3d_CSysIntps i; for(i = 0; i < TexFmtCnt; i++) { FmtCol = TexFmtArray[i]; HRESULT Result; S3D_DRV_D3D9_HRESCALL( Env, Result, D3d->CheckDeviceFormat( Adapter, DevType, m_AdapterMode.Format, Usage, ResType, FmtCol)); if(SUCCEEDED(Result)) { if(Result == D3DOK_NOAUTOGEN) AutoMipmap = false; S3D_DRV_D3D9_HRESCALL( Env, Result, D3d->CheckDeviceFormat( Adapter, DevType, m_AdapterMode.Format, D3DUSAGE_QUERY_FILTER, ResType, FmtCol)); if(FAILED(Result)) CanFilter = false; S3D_DRV_D3D9_HRESCALL( Env, Result, D3d->CheckDeviceMultiSampleType( Adapter, DevType, FmtCol, m_D3dCtx->m_Windowed, m_D3dCtx->m_MultiSampleType, 0)); if(FAILED(Result)) CanMultiSample = false; if(!Param->m_SRGBTexEnabled) break; S3D_DRV_D3D9_HRESCALL( Env, Result, D3d->CheckDeviceFormat( Adapter, DevType, m_AdapterMode.Format, D3DUSAGE_QUERY_SRGBREAD, ResType, FmtCol)); if(SUCCEEDED(Result)) SRGBRead = true; S3D_DRV_D3D9_HRESCALL( Env, Result, D3d->CheckDeviceFormat( Adapter, DevType, m_AdapterMode.Format, D3DUSAGE_QUERY_SRGBWRITE, ResType, FmtCol)); if(SUCCEEDED(Result)) SRGBWrite = true; break; } FmtCol = D3DFMT_UNKNOWN; } // Something went wrong, select a format that is known to work. if(FmtCol == D3DFMT_UNKNOWN) FmtCol = m_D3dCtx->m_BackBufFmt; } D3DTEXTUREFILTERTYPE FilterMipGen = D3DTEXF_NONE; if(AutoMipmap) { FilterMipGen = D3DTEXF_POINT; if(CanFilter) { FilterMipGen = D3DTEXF_LINEAR; if((TexProp & s3d_CDrvGfxEng::TexProp_Cube) != 0) { if(m_DevCaps.CubeTextureFilterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC) FilterMipGen = D3DTEXF_ANISOTROPIC; } else if((TexProp & s3d_CDrvGfxEng::TexProp_Volume) != 0) { if(m_DevCaps.VolumeTextureFilterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC) FilterMipGen = D3DTEXF_ANISOTROPIC; } else { if(m_DevCaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC) FilterMipGen = D3DTEXF_ANISOTROPIC; } } } TexFmt.m_FmtCol = FmtCol; TexFmt.m_FmtDepth = FmtDepth; TexFmt.m_FilterMipGen = FilterMipGen; TexFmt.m_CanFilter = CanFilter; TexFmt.m_CanMultiSample = CanMultiSample; TexFmt.m_Usage = Usage; TexFmt.m_SRGBRead = SRGBRead; TexFmt.m_SRGBWrite = SRGBWrite; } /////////////////////////////////////////////////////////////////////////////// //@ static const D3DCUBEMAP_FACES s3d_CDrvD3d9ubeMapFaceTable[] = { D3DCUBEMAP_FACE_NEGATIVE_X, D3DCUBEMAP_FACE_POSITIVE_X, D3DCUBEMAP_FACE_NEGATIVE_Y, D3DCUBEMAP_FACE_POSITIVE_Y, D3DCUBEMAP_FACE_NEGATIVE_Z, D3DCUBEMAP_FACE_POSITIVE_Z, }; D3DCUBEMAP_FACES s3d_CDrvD3d9TexMgr::GetFaceOfPart(int Part) { D3DCUBEMAP_FACES CubeFace = D3DCUBEMAP_FACE_NEGATIVE_X; if(Part >=0 && Part < 6) CubeFace = s3d_CDrvD3d9ubeMapFaceTable[Part]; return CubeFace; } int s3d_CDrvD3d9TexMgr::CompCntOfTexProp( int TexProp) { if(TexProp & s3d_CDrvGfxEng::TexProp_Comp4) return 4; if(TexProp & s3d_CDrvGfxEng::TexProp_Comp3) return 3; if(TexProp & s3d_CDrvGfxEng::TexProp_Comp2) return 2; if(TexProp & s3d_CDrvGfxEng::TexProp_Comp1) return 1; return 0; } int s3d_CDrvD3d9TexMgr::BitsPerCompCntOfTexProp( int TexProp) { if(TexProp & s3d_CDrvGfxEng::TexProp_BitsPerComp32) return 32; if(TexProp & s3d_CDrvGfxEng::TexProp_BitsPerComp16) return 16; if(TexProp & s3d_CDrvGfxEng::TexProp_BitsPerComp8) return 8; return 0; } void s3d_CDrvD3d9TexMgr::CopyTexData2D( s3d_CSysIntm *&DestData, s3d_CSysIntps Stride, int Width, int Height, const s3d_CDrvGfxPixel *SrcData) { int LoopX, LoopY; for(LoopY = Height; LoopY > 0; LoopY--) { void *DestLine = DestData; (s3d_CSysIntm*&)DestData += Stride; for(LoopX = Width; LoopX > 0; LoopX--) { s3d_CDrvGfxPixel SrcPixel = *SrcData++; s3d_CSysInt32u DestPixel = (SrcPixel & 0xff00ff00) | _rotl(SrcPixel & 0x00ff00ff, 16); *((s3d_CSysInt32u*&)DestLine)++ = DestPixel; } } } ///////////////////////////////////////////////////////////////////////////////