/////////////////////////////////////////////////////////////////////////////// // // ## ###### // ###### ### // ## ############### Shark 3D Engine (www.shark3d.com) // ########## # # # // ######## Copyright (c) 1996-2006 Spinor GmbH. // ######### # # # All rights reserved. // ## ########## // ## // /////////////////////////////////////////////////////////////////////////////// #include "drv_d3d9_util.h" #include "util/base/util_strutil.h" #include "util/stream/util_textstreampos.h" #include /////////////////////////////////////////////////////////////////////////////// void s3d_DrvD3d9DbgPrintF(const s3d_CSysChar *FmtStr, ...) { static s3d_CSysChar Buf[512]; va_list VaList; va_start(VaList, FmtStr); _vsnprintf(Buf, S3D_SYS_SIZEOFS(Buf), FmtStr, VaList); va_end(VaList); OutputDebugString("s3d_drvd3d: "); OutputDebugString(Buf); } /////////////////////////////////////////////////////////////////////////////// int s3d_CDrvD3d9Util::ColBitsOfFmt(D3DFORMAT Fmt) { switch(Fmt) { case D3DFMT_R8G8B8: return 24; case D3DFMT_A8R8G8B8: return 32; case D3DFMT_X8R8G8B8: return 24; case D3DFMT_R5G6B5: return 16; case D3DFMT_X1R5G5B5: return 15; case D3DFMT_A1R5G5B5: return 16; case D3DFMT_A4R4G4B4: return 16; case D3DFMT_R3G3B2: return 8; case D3DFMT_A8: return 8; case D3DFMT_A8R3G3B2: return 16; case D3DFMT_X4R4G4B4: return 12; case D3DFMT_A2B10G10R10: return 32; case D3DFMT_A8B8G8R8: return 32; case D3DFMT_X8B8G8R8: return 24; case D3DFMT_G16R16: return 32; case D3DFMT_A2R10G10B10: return 32; case D3DFMT_A16B16G16R16: return 64; case D3DFMT_A8P8: return 16; case D3DFMT_P8: return 8; case D3DFMT_L8: return 8; case D3DFMT_A8L8: return 16; case D3DFMT_A4L4: return 8; case D3DFMT_V8U8: return 16; case D3DFMT_L6V5U5: return 16; case D3DFMT_X8L8V8U8: return 24; case D3DFMT_Q8W8V8U8: return 32; case D3DFMT_V16U16: return 32; case D3DFMT_A2W10V10U10: return 32; case D3DFMT_UYVY: return 16; case D3DFMT_R8G8_B8G8: return 16; case D3DFMT_YUY2: return 16; case D3DFMT_G8R8_G8B8: return 16; case D3DFMT_DXT1: return 24; case D3DFMT_DXT2: return 32; case D3DFMT_DXT3: return 32; case D3DFMT_DXT4: return 32; case D3DFMT_DXT5: return 32; case D3DFMT_D16_LOCKABLE: return 0; case D3DFMT_D32: return 0; case D3DFMT_D15S1: return 0; case D3DFMT_D24S8: return 0; case D3DFMT_D24X8: return 0; case D3DFMT_D24X4S4: return 0; case D3DFMT_D16: return 0; case D3DFMT_D32F_LOCKABLE: return 0; case D3DFMT_D24FS8: return 0; case D3DFMT_L16: return 16; case D3DFMT_VERTEXDATA: return 0; case D3DFMT_INDEX16: return 0; case D3DFMT_INDEX32: return 0; case D3DFMT_Q16W16V16U16: return 64; case D3DFMT_MULTI2_ARGB8: return 64; case D3DFMT_R16F: return 16; case D3DFMT_G16R16F: return 32; case D3DFMT_A16B16G16R16F: return 64; case D3DFMT_R32F: return 32; case D3DFMT_G32R32F: return 64; case D3DFMT_A32B32G32R32F: return 128; case D3DFMT_CxV8U8: return 16; default: S3D_SYS_ASSERT(0); return 0; } } int s3d_CDrvD3d9Util::DepthBitsOfFmt(D3DFORMAT Fmt) { switch(Fmt) { case D3DFMT_D16_LOCKABLE: return 16; case D3DFMT_D32: return 32; case D3DFMT_D15S1: return 15; case D3DFMT_D24S8: return 24; case D3DFMT_D24X8: return 24; case D3DFMT_D24X4S4: return 24; case D3DFMT_D32F_LOCKABLE: return 32; case D3DFMT_D24FS8: return 24; default: S3D_SYS_ASSERT(0); return 0; } } bool s3d_CDrvD3d9Util::IsDepthStencilFmt( D3DFORMAT Fmt) { switch(Fmt) { case D3DFMT_D16_LOCKABLE: case D3DFMT_D32: case D3DFMT_D15S1: case D3DFMT_D24S8: case D3DFMT_D24X8: case D3DFMT_D24X4S4: case D3DFMT_D32F_LOCKABLE: case D3DFMT_D24FS8: return true; default: return false; } } int s3d_CDrvD3d9Util::StencilBitsOfFmt(D3DFORMAT Fmt) { switch(Fmt) { case D3DFMT_D16_LOCKABLE: return 0; case D3DFMT_D32: return 0; case D3DFMT_D15S1: return 1; case D3DFMT_D24S8: return 8; case D3DFMT_D24X8: return 0; case D3DFMT_D24X4S4: return 4; case D3DFMT_D32F_LOCKABLE: return 0; case D3DFMT_D24FS8: return 8; default: S3D_SYS_ASSERT(0); return 0; } } D3DFORMAT s3d_CDrvD3d9Util::LinearFmtOfSwizzledFmt(D3DFORMAT Fmt) { return Fmt; } s3d_CUtilStr s3d_CDrvD3d9Util::StrOfFmt(D3DFORMAT Fmt) { switch(Fmt) { case D3DFMT_UNKNOWN: return "D3DFMT_UNKNOWN"; case D3DFMT_R8G8B8: return "D3DFMT_R8G8B8"; case D3DFMT_A8R8G8B8: return "D3DFMT_A8R8G8B8"; case D3DFMT_X8R8G8B8: return "D3DFMT_X8R8G8B8"; case D3DFMT_R5G6B5: return "D3DFMT_R5G6B5"; case D3DFMT_X1R5G5B5: return "D3DFMT_X1R5G5B5"; case D3DFMT_A1R5G5B5: return "D3DFMT_A1R5G5B5"; case D3DFMT_A4R4G4B4: return "D3DFMT_A4R4G4B4"; case D3DFMT_R3G3B2: return "D3DFMT_R3G3B2"; case D3DFMT_A8: return "D3DFMT_A8"; case D3DFMT_A8R3G3B2: return "D3DFMT_A8R3G3B2"; case D3DFMT_X4R4G4B4: return "D3DFMT_X4R4G4B4"; case D3DFMT_A2B10G10R10: return "D3DFMT_A2B10G10R10"; case D3DFMT_A8B8G8R8: return "D3DFMT_A8B8G8R8"; case D3DFMT_X8B8G8R8: return "D3DFMT_X8B8G8R8"; case D3DFMT_G16R16: return "D3DFMT_G16R16"; case D3DFMT_A2R10G10B10: return "D3DFMT_A2R10G10B10"; case D3DFMT_A16B16G16R16: return "D3DFMT_A16B16G16R16"; case D3DFMT_A8P8: return "D3DFMT_A8P8"; case D3DFMT_P8: return "D3DFMT_P8"; case D3DFMT_L8: return "D3DFMT_L8"; case D3DFMT_A8L8: return "D3DFMT_A8L8"; case D3DFMT_A4L4: return "D3DFMT_A4L4"; case D3DFMT_V8U8: return "D3DFMT_V8U8"; case D3DFMT_L6V5U5: return "D3DFMT_L6V5U5"; case D3DFMT_X8L8V8U8: return "D3DFMT_X8L8V8U8"; case D3DFMT_Q8W8V8U8: return "D3DFMT_Q8W8V8U8"; case D3DFMT_V16U16: return "D3DFMT_V16U16"; case D3DFMT_A2W10V10U10: return "D3DFMT_A2W10V10U10"; case D3DFMT_UYVY: return "D3DFMT_UYVY"; case D3DFMT_YUY2: return "D3DFMT_YUY2"; case D3DFMT_DXT1: return "D3DFMT_DXT1"; case D3DFMT_DXT2: return "D3DFMT_DXT2"; case D3DFMT_DXT3: return "D3DFMT_DXT3"; case D3DFMT_DXT4: return "D3DFMT_DXT4"; case D3DFMT_DXT5: return "D3DFMT_DXT5"; case D3DFMT_D16_LOCKABLE: return "D3DFMT_D16_LOCKABLE"; case D3DFMT_D32: return "D3DFMT_D32"; case D3DFMT_D15S1: return "D3DFMT_D15S1"; case D3DFMT_D24S8: return "D3DFMT_D24S8"; case D3DFMT_D24X8: return "D3DFMT_D24X8"; case D3DFMT_D24X4S4: return "D3DFMT_D24X4S4"; case D3DFMT_D16: return "D3DFMT_D16"; case D3DFMT_L16: return "D3DFMT_L16"; case D3DFMT_VERTEXDATA: return "D3DFMT_VERTEXDATA"; case D3DFMT_INDEX16: return "D3DFMT_INDEX16"; case D3DFMT_INDEX32: return "D3DFMT_INDEX32"; case D3DFMT_Q16W16V16U16: return "D3DFMT_Q16W16V16U16"; case D3DFMT_MULTI2_ARGB8: return "D3DFMT_MULTI2_ARGB8"; case D3DFMT_R16F: return "D3DFMT_R16F"; case D3DFMT_G16R16F: return "D3DFMT_G16R16F"; case D3DFMT_A16B16G16R16F: return "D3DFMT_A16B16G16R16F"; case D3DFMT_R32F: return "D3DFMT_R32F"; case D3DFMT_G32R32F: return "D3DFMT_G32R32F"; case D3DFMT_A32B32G32R32F: return "D3DFMT_A32B32G32R32F"; case D3DFMT_CxV8U8: return "D3DFMT_CxV8U8"; default: return "Unknown format"; } } s3d_CUtilStr s3d_CDrvD3d9Util::StrOfMutliSampleType( D3DMULTISAMPLE_TYPE MultiSampleType) { switch(MultiSampleType) { case D3DMULTISAMPLE_NONE: return ""; case D3DMULTISAMPLE_NONMASKABLE: return "Maskable MSAA"; case D3DMULTISAMPLE_2_SAMPLES: return "2xMSAA"; case D3DMULTISAMPLE_3_SAMPLES: return "3xMSAA"; case D3DMULTISAMPLE_4_SAMPLES: return "4xMSAA"; case D3DMULTISAMPLE_5_SAMPLES: return "5xMSAA"; case D3DMULTISAMPLE_6_SAMPLES: return "6xMSAA"; case D3DMULTISAMPLE_7_SAMPLES: return "7xMSAA"; case D3DMULTISAMPLE_8_SAMPLES: return "8xMSAA"; default: return "Unknown MSAA"; } } /////////////////////////////////////////////////////////////////////////////// void s3d_CDrvD3d9Util::ErrorD3d( s3d_CUtilMsgHandler *MsgHandler, HRESULT DxResult, const char *File, int Line) { s3d_CUtilTextStreamPos FilePos(File, Line, 0); s3d_CUtilStr DxResultStr = s3d_CUtilStrUtil::StrOfInt(DxResult); s3d_CDrvDxError e; e.m_Code = s3d_CUtilStr("drv/imp/directx/d3d9/s3d_DrvD3d9util.dxerror.") + s3d_CUtilStrUtil::StrOfInt(DxResult); e.m_StdTempl = "Direct3D: Call \"[1]\" returned error [2] \"[3]\"."; e.AddInfo(""); e.AddInfo(FilePos.FormatStd()); e.AddInfo(s3d_CUtilStrUtil::StrOfInt( DxResult, 8, s3d_CUtilStrNum::Format_HexPadding)); e.AddInfo(DXGetErrorDescription9(DxResult)); s3d_UtilMsgReportError(MsgHandler, e); } /////////////////////////////////////////////////////////////////////////////// s3d_CUtilStr s3d_CDrvD3d9Util::StrOfSemantic( const D3DXSEMANTIC &Semantic) { s3d_CUtilStrBuf StrBuf; DWORD Usage = Semantic.Usage; DWORD UsageIdx = Semantic.UsageIndex; switch(Usage) { case D3DDECLUSAGE_POSITION: { StrBuf.Append("POSITION"); break; } case D3DDECLUSAGE_BLENDWEIGHT: { StrBuf.Append("BLENDWGH"); break; } case D3DDECLUSAGE_NORMAL: { StrBuf.Append("NORMAL"); break; } case D3DDECLUSAGE_COLOR: { StrBuf.Append("COLOR"); break; } case D3DDECLUSAGE_TEXCOORD: { StrBuf.Append("TEXCOORD"); break; } case D3DDECLUSAGE_PSIZE: { StrBuf.Append("PSIZE"); break; } case D3DDECLUSAGE_BLENDINDICES: { StrBuf.Append("BLENDINDICES"); break; } case D3DDECLUSAGE_TANGENT: { StrBuf.Append("TANGENT"); break; } case D3DDECLUSAGE_BINORMAL: { StrBuf.Append("BINORMAL"); break; } case D3DDECLUSAGE_TESSFACTOR: { StrBuf.Append("TESSFACTOR"); break; } case D3DDECLUSAGE_POSITIONT: { StrBuf.Append("POSITIONT"); break; } case D3DDECLUSAGE_FOG: { StrBuf.Append("FOG"); break; } case D3DDECLUSAGE_DEPTH: { StrBuf.Append("DEPTH"); break; } case D3DDECLUSAGE_SAMPLE: { StrBuf.Append("SAMPLE"); break; } } StrBuf.AppendInt(UsageIdx); return StrBuf; } s3d_CUtilStr s3d_CDrvD3d9Util::StrOfProgDecl( const s3d_CDrvD3d9ProgDecl &ProgDecl) { s3d_CUtilStrBuf StrBuf; const D3DXSEMANTIC *SemanticArray = ProgDecl.m_SemanticArray; s3d_CSysIntps nSemantic = ProgDecl.m_SemanticsCnt; s3d_CSysIntps iSemantic; for(iSemantic = 0; iSemantic < nSemantic; iSemantic++) { if(iSemantic > 0) StrBuf.Append(", "); StrBuf.Append(s3d_CDrvD3d9Util::StrOfSemantic(*SemanticArray++)); } return StrBuf; } s3d_CUtilStr s3d_CDrvD3d9Util::StrOfVertDecl( s3d_CDrvD3d9Env *Env, const s3d_CDrvD3d9VertDecl &VertDecl) { UINT ElemCnt = 0; S3D_DRV_D3D9_CHECK( Env, VertDecl->GetDeclaration(0, &ElemCnt)); s3d_CSysIntps AllocSize = ElemCnt * S3D_SYS_SIZEOFS(D3DVERTEXELEMENT9); D3DVERTEXELEMENT9 *ElemArray = reinterpret_cast(alloca(AllocSize)); S3D_DRV_D3D9_CHECK( Env, VertDecl->GetDeclaration(ElemArray, &ElemCnt)); return s3d_CDrvD3d9Util::StrOfVertElemArray(ElemCnt, ElemArray); } s3d_CUtilStr s3d_CDrvD3d9Util::StrOfVertElemArray( s3d_CSysIntps ElemCnt, const D3DVERTEXELEMENT9 *ElemArray) { ElemCnt--; // DECL_END if(ElemCnt <= 0) return 0; if(!ElemArray) return 0; s3d_CUtilStrBuf StrBuf; s3d_CSysIntps iElem; for(iElem = 0; iElem < ElemCnt; iElem++) //-1 DECL_END { if(iElem > 0) StrBuf.Append(", "); D3DXSEMANTIC Semantic; Semantic.Usage = ElemArray->Usage; Semantic.UsageIndex = ElemArray->UsageIndex; StrBuf.Append(s3d_CDrvD3d9Util::StrOfSemantic(Semantic)); ElemArray++; } return StrBuf; } s3d_CSysIntps s3d_CDrvD3d9Util::SizeOfDeclType(int Type) { switch(Type) { case D3DDECLTYPE_FLOAT1: return S3D_SYS_SIZEOFS(float); case D3DDECLTYPE_FLOAT2: return S3D_SYS_SIZEOFS(float) * 2; case D3DDECLTYPE_FLOAT3: return S3D_SYS_SIZEOFS(float) * 3; case D3DDECLTYPE_FLOAT4: return S3D_SYS_SIZEOFS(float) * 4; case D3DDECLTYPE_D3DCOLOR: case D3DDECLTYPE_UBYTE4N: case D3DDECLTYPE_UBYTE4: return S3D_SYS_SIZEOFS(DWORD); case D3DDECLTYPE_SHORT2: case D3DDECLTYPE_SHORT2N: case D3DDECLTYPE_USHORT2N: return S3D_SYS_SIZEOFS(DWORD); case D3DDECLTYPE_SHORT4: case D3DDECLTYPE_SHORT4N: case D3DDECLTYPE_USHORT4N: return S3D_SYS_SIZEOFS(DWORD) * 2; case D3DDECLTYPE_UDEC3: case D3DDECLTYPE_DEC3N: return S3D_SYS_SIZEOFS(DWORD); case D3DDECLTYPE_FLOAT16_2: return S3D_SYS_SIZEOFS(DWORD); case D3DDECLTYPE_FLOAT16_4: return S3D_SYS_SIZEOFS(DWORD) * 2; } return 0; } static const D3DRENDERSTATETYPE s3d_DrvD3d9WrapTable[16] = { D3DRS_WRAP0, D3DRS_WRAP1, D3DRS_WRAP2, D3DRS_WRAP3, D3DRS_WRAP4, D3DRS_WRAP5, D3DRS_WRAP6, D3DRS_WRAP7, D3DRS_WRAP8, D3DRS_WRAP9, D3DRS_WRAP10, D3DRS_WRAP11, D3DRS_WRAP12, D3DRS_WRAP13, D3DRS_WRAP14, D3DRS_WRAP15 }; D3DRENDERSTATETYPE s3d_CDrvD3d9Util::D3dWrapOfSamp(int Samp) { if(s3d_SysIsValidArrayIdx( Samp, S3D_SYS_ARRAYCNTS(s3d_DrvD3d9WrapTable))) return s3d_DrvD3d9WrapTable[Samp]; else return D3DRS_WRAP0; } ///////////////////////////////////////////////////////////////////////////////