diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /materialsystem/shaderapidx9/colorformatdx8.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'materialsystem/shaderapidx9/colorformatdx8.cpp')
| -rw-r--r-- | materialsystem/shaderapidx9/colorformatdx8.cpp | 727 |
1 files changed, 727 insertions, 0 deletions
diff --git a/materialsystem/shaderapidx9/colorformatdx8.cpp b/materialsystem/shaderapidx9/colorformatdx8.cpp new file mode 100644 index 0000000..daf3e50 --- /dev/null +++ b/materialsystem/shaderapidx9/colorformatdx8.cpp @@ -0,0 +1,727 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// + +#define DISABLE_PROTECTED_THINGS +#include "togl/rendermechanism.h" +#include "locald3dtypes.h" +#include "colorformatdx8.h" +#include "shaderapidx8_global.h" +#include "bitmap/imageformat.h" +#include "shaderapi/ishaderutil.h" +#include "tier0/dbg.h" +#include "tier1/strtools.h" +#include "shaderdevicedx8.h" + + +// Must be last +#include "tier0/memdbgon.h" + + +//----------------------------------------------------------------------------- +// Figures out what texture formats we support +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// globals +//----------------------------------------------------------------------------- + +// Texture formats supported by DX driver[vertextexture][render target][non filterable] +static D3DFORMAT g_D3DColorFormat[NUM_IMAGE_FORMATS][2][2][2]; +static UINT g_DisplayAdapter; +static D3DDEVTYPE g_DeviceType; +static ImageFormat g_DeviceFormat; +static bool g_bSupportsD24S8; +static bool g_bSupportsD24X8; +static bool g_bSupportsD16; +static bool g_bSupportsD24X4S4; +static bool g_bSupportsD15S1; + +//----------------------------------------------------------------------------- +// Determines what formats we actually *do* support +//----------------------------------------------------------------------------- +static bool TestTextureFormat( D3DFORMAT format, bool bIsRenderTarget, + bool bIsVertexTexture, bool bIsFilterableRequired ) +{ + int nUsage = bIsRenderTarget ? D3DUSAGE_RENDERTARGET : 0; + if ( bIsVertexTexture ) + { + // vertex textures never need filtering + nUsage |= D3DUSAGE_QUERY_VERTEXTEXTURE; + } + if ( bIsFilterableRequired ) + { + nUsage |= D3DUSAGE_QUERY_FILTER; + } + + HRESULT hr; + + // IHV depth texture formats require a slightly different check... + if ( !IsX360() && bIsRenderTarget && ( ( format == NVFMT_RAWZ ) || ( format == NVFMT_INTZ ) || + ( format == D3DFMT_D16 ) || ( format == D3DFMT_D24S8 ) || + ( format == ATIFMT_D16 ) || ( format == ATIFMT_D24S8 ) ) ) + { + hr = D3D()->CheckDeviceFormat( + g_DisplayAdapter, g_DeviceType, ImageLoader::ImageFormatToD3DFormat( g_DeviceFormat ), + D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format ); + } + else if ( !IsX360() || !bIsRenderTarget ) + { + // See if we can do it! + hr = D3D()->CheckDeviceFormat( + g_DisplayAdapter, g_DeviceType, ImageLoader::ImageFormatToD3DFormat( g_DeviceFormat ), + nUsage, D3DRTYPE_TEXTURE, format ); + } + else // 360 + { + // 360 can only validate render targets as surface display format + hr = D3D()->CheckDeviceFormat( g_DisplayAdapter, g_DeviceType, format, 0, D3DRTYPE_SURFACE, format ); + } + + return SUCCEEDED( hr ); +} + +D3DFORMAT GetNearestD3DColorFormat( ImageFormat fmt, + bool isRenderTarget, bool bIsVertexTexture, + bool bIsFilterableRequired) +{ + switch(fmt) + { + case IMAGE_FORMAT_RGBA8888: + case IMAGE_FORMAT_ABGR8888: + case IMAGE_FORMAT_ARGB8888: + case IMAGE_FORMAT_BGRA8888: + if (TestTextureFormat(D3DFMT_A8R8G8B8, isRenderTarget, bIsVertexTexture, bIsFilterableRequired)) + return D3DFMT_A8R8G8B8; + if (TestTextureFormat(D3DFMT_A4R4G4B4, isRenderTarget, bIsVertexTexture, bIsFilterableRequired)) + return D3DFMT_A4R4G4B4; + break; + +#if defined( _X360 ) + case IMAGE_FORMAT_LINEAR_RGBA8888: + case IMAGE_FORMAT_LINEAR_ABGR8888: + case IMAGE_FORMAT_LINEAR_ARGB8888: + case IMAGE_FORMAT_LINEAR_BGRA8888: + // same as above - all xxxx8888 RGBA ordering funnels to d3d a8r8g8b8 + if ( TestTextureFormat( D3DFMT_LIN_A8R8G8B8, isRenderTarget, bIsVertexTexture, bIsFilterableRequired ) ) + return D3DFMT_LIN_A8R8G8B8; + break; +#endif + +#if defined( _X360 ) + case IMAGE_FORMAT_LINEAR_BGRX8888: + if ( TestTextureFormat( D3DFMT_LIN_X8R8G8B8, isRenderTarget, bIsVertexTexture, bIsFilterableRequired ) ) + return D3DFMT_LIN_X8R8G8B8; + break; +#endif + + case IMAGE_FORMAT_BGRX8888: + // We want this format to return exactly it's equivalent so that + // when we create render targets to blit to from the framebuffer, + // the CopyRect won't fail due to format mismatches. + if (TestTextureFormat(D3DFMT_X8R8G8B8, isRenderTarget, bIsVertexTexture, bIsFilterableRequired)) + return D3DFMT_X8R8G8B8; + + // fall through. . . . + case IMAGE_FORMAT_RGB888: + case IMAGE_FORMAT_BGR888: +#if !defined( _X360 ) + if (TestTextureFormat(D3DFMT_R8G8B8, isRenderTarget, bIsVertexTexture, bIsFilterableRequired)) + return D3DFMT_R8G8B8; +#endif + if (TestTextureFormat(D3DFMT_X8R8G8B8, isRenderTarget, bIsVertexTexture, bIsFilterableRequired)) + return D3DFMT_X8R8G8B8; + if (TestTextureFormat(D3DFMT_A8R8G8B8, isRenderTarget, bIsVertexTexture, bIsFilterableRequired)) + return D3DFMT_A8R8G8B8; + if (TestTextureFormat(D3DFMT_R5G6B5, isRenderTarget, bIsVertexTexture, bIsFilterableRequired)) + return D3DFMT_R5G6B5; + if (TestTextureFormat(D3DFMT_X1R5G5B5, isRenderTarget, bIsVertexTexture, bIsFilterableRequired)) + return D3DFMT_X1R5G5B5; + if (TestTextureFormat(D3DFMT_A1R5G5B5, isRenderTarget, bIsVertexTexture, bIsFilterableRequired)) + return D3DFMT_A1R5G5B5; + break; + + case IMAGE_FORMAT_BGR565: + case IMAGE_FORMAT_RGB565: + if (TestTextureFormat(D3DFMT_R5G6B5, isRenderTarget, bIsVertexTexture, bIsFilterableRequired)) + return D3DFMT_R5G6B5; + if (TestTextureFormat(D3DFMT_X1R5G5B5, isRenderTarget, bIsVertexTexture, bIsFilterableRequired)) + return D3DFMT_X1R5G5B5; + if (TestTextureFormat(D3DFMT_A1R5G5B5, isRenderTarget, bIsVertexTexture, bIsFilterableRequired)) + return D3DFMT_A1R5G5B5; +#if !defined( _X360 ) + if (TestTextureFormat(D3DFMT_R8G8B8, isRenderTarget, bIsVertexTexture, bIsFilterableRequired)) + return D3DFMT_R8G8B8; +#endif + if (TestTextureFormat(D3DFMT_X8R8G8B8, isRenderTarget, bIsVertexTexture, bIsFilterableRequired)) + return D3DFMT_X8R8G8B8; + if (TestTextureFormat(D3DFMT_A8R8G8B8, isRenderTarget, bIsVertexTexture, bIsFilterableRequired)) + return D3DFMT_A8R8G8B8; + break; + + case IMAGE_FORMAT_BGRX5551: + if (TestTextureFormat(D3DFMT_X1R5G5B5, isRenderTarget, bIsVertexTexture, bIsFilterableRequired)) + return D3DFMT_X1R5G5B5; + if (TestTextureFormat(D3DFMT_A1R5G5B5, isRenderTarget, bIsVertexTexture, bIsFilterableRequired)) + return D3DFMT_A1R5G5B5; + if (TestTextureFormat(D3DFMT_R5G6B5, isRenderTarget, bIsVertexTexture, bIsFilterableRequired)) + return D3DFMT_R5G6B5; +#if !defined( _X360 ) + if (TestTextureFormat(D3DFMT_R8G8B8, isRenderTarget, bIsVertexTexture, bIsFilterableRequired)) + return D3DFMT_R8G8B8; +#endif + if (TestTextureFormat(D3DFMT_X8R8G8B8, isRenderTarget, bIsVertexTexture, bIsFilterableRequired)) + return D3DFMT_X8R8G8B8; + if (TestTextureFormat(D3DFMT_A8R8G8B8, isRenderTarget, bIsVertexTexture, bIsFilterableRequired)) + return D3DFMT_A8R8G8B8; + break; + +#if defined( _X360 ) + case IMAGE_FORMAT_LINEAR_BGRX5551: + if ( TestTextureFormat( D3DFMT_LIN_X1R5G5B5, isRenderTarget, bIsVertexTexture, bIsFilterableRequired ) ) + return D3DFMT_LIN_X1R5G5B5; + break; +#endif + + case IMAGE_FORMAT_BGRA5551: + if (TestTextureFormat(D3DFMT_A1R5G5B5, isRenderTarget, bIsVertexTexture, bIsFilterableRequired)) + return D3DFMT_A1R5G5B5; + if (TestTextureFormat(D3DFMT_A4R4G4B4, isRenderTarget, bIsVertexTexture, bIsFilterableRequired)) + return D3DFMT_A4R4G4B4; + if (TestTextureFormat(D3DFMT_A8R8G8B8, isRenderTarget, bIsVertexTexture, bIsFilterableRequired)) + return D3DFMT_A8R8G8B8; + break; + + case IMAGE_FORMAT_BGRA4444: + if (TestTextureFormat(D3DFMT_A4R4G4B4, isRenderTarget, bIsVertexTexture, bIsFilterableRequired)) + return D3DFMT_A4R4G4B4; + if (TestTextureFormat(D3DFMT_A8R8G8B8, isRenderTarget, bIsVertexTexture, bIsFilterableRequired)) + return D3DFMT_A8R8G8B8; + break; + + case IMAGE_FORMAT_I8: + if (TestTextureFormat(D3DFMT_L8, isRenderTarget, bIsVertexTexture, bIsFilterableRequired)) + return D3DFMT_L8; + if (TestTextureFormat(D3DFMT_A8R8G8B8, isRenderTarget, bIsVertexTexture, bIsFilterableRequired)) + return D3DFMT_A8R8G8B8; + break; + +#if defined( _X360 ) + case IMAGE_FORMAT_LINEAR_I8: + if ( TestTextureFormat( D3DFMT_LIN_L8, isRenderTarget, bIsVertexTexture, bIsFilterableRequired ) ) + return D3DFMT_LIN_L8; + break; +#endif + + case IMAGE_FORMAT_IA88: + if (TestTextureFormat(D3DFMT_A8L8, isRenderTarget, bIsVertexTexture, bIsFilterableRequired)) + return D3DFMT_A8L8; + if (TestTextureFormat(D3DFMT_A8R8G8B8, isRenderTarget, bIsVertexTexture, bIsFilterableRequired)) + return D3DFMT_A8R8G8B8; + break; + + case IMAGE_FORMAT_A8: + if (TestTextureFormat(D3DFMT_A8, isRenderTarget, bIsVertexTexture, bIsFilterableRequired)) + return D3DFMT_A8; + if (TestTextureFormat(D3DFMT_A8R8G8B8, isRenderTarget, bIsVertexTexture, bIsFilterableRequired)) + return D3DFMT_A8R8G8B8; + break; + + case IMAGE_FORMAT_DXT1: + case IMAGE_FORMAT_DXT1_ONEBITALPHA: + case IMAGE_FORMAT_DXT1_RUNTIME: + if (TestTextureFormat(D3DFMT_DXT1, isRenderTarget, bIsVertexTexture, bIsFilterableRequired)) + return D3DFMT_DXT1; + break; + + case IMAGE_FORMAT_DXT3: + if (TestTextureFormat(D3DFMT_DXT3, isRenderTarget, bIsVertexTexture, bIsFilterableRequired )) + return D3DFMT_DXT3; + break; + + case IMAGE_FORMAT_DXT5: + case IMAGE_FORMAT_DXT5_RUNTIME: + if (TestTextureFormat(D3DFMT_DXT5, isRenderTarget, bIsVertexTexture, bIsFilterableRequired )) + return D3DFMT_DXT5; + break; + + case IMAGE_FORMAT_UV88: + if (TestTextureFormat(D3DFMT_V8U8, isRenderTarget, bIsVertexTexture, bIsFilterableRequired )) + return D3DFMT_V8U8; + break; + + case IMAGE_FORMAT_UVWQ8888: + if (TestTextureFormat(D3DFMT_Q8W8V8U8, isRenderTarget, bIsVertexTexture, bIsFilterableRequired )) + return D3DFMT_Q8W8V8U8; + break; + + case IMAGE_FORMAT_UVLX8888: + if (TestTextureFormat(D3DFMT_X8L8V8U8, isRenderTarget, bIsVertexTexture, bIsFilterableRequired )) + return D3DFMT_X8L8V8U8; + break; + + case IMAGE_FORMAT_RGBA16161616F: + if ( TestTextureFormat( D3DFMT_A16B16G16R16F, isRenderTarget, bIsVertexTexture, bIsFilterableRequired ) ) + return D3DFMT_A16B16G16R16F; + if ( TestTextureFormat( D3DFMT_A16B16G16R16, isRenderTarget, bIsVertexTexture, bIsFilterableRequired ) ) + return D3DFMT_A16B16G16R16; + break; + + case IMAGE_FORMAT_RGBA16161616: + if ( TestTextureFormat( D3DFMT_A16B16G16R16, isRenderTarget, bIsVertexTexture, bIsFilterableRequired ) ) + return D3DFMT_A16B16G16R16; + if ( TestTextureFormat( D3DFMT_A16B16G16R16F, isRenderTarget, bIsVertexTexture, bIsFilterableRequired ) ) + return D3DFMT_A16B16G16R16F; + break; + +#if defined( _X360 ) + case IMAGE_FORMAT_LINEAR_RGBA16161616: + if ( TestTextureFormat( D3DFMT_LIN_A16B16G16R16, isRenderTarget, bIsVertexTexture, bIsFilterableRequired ) ) + return D3DFMT_LIN_A16B16G16R16; + break; +#endif + + case IMAGE_FORMAT_R32F: + if ( TestTextureFormat( D3DFMT_R32F, isRenderTarget, bIsVertexTexture, bIsFilterableRequired ) ) + return D3DFMT_R32F; + break; + + case IMAGE_FORMAT_RGBA32323232F: + if ( TestTextureFormat( D3DFMT_A32B32G32R32F, isRenderTarget, bIsVertexTexture, bIsFilterableRequired ) ) + return D3DFMT_A32B32G32R32F; + break; + +#if defined( _X360 ) + case IMAGE_FORMAT_X360_DST16: + return D3DFMT_D16; + + case IMAGE_FORMAT_X360_DST24: + return D3DFMT_D24S8; + + case IMAGE_FORMAT_X360_DST24F: + return D3DFMT_D24FS8; + + case IMAGE_FORMAT_LE_BGRX8888: + return D3DFMT_LE_X8R8G8B8; + + case IMAGE_FORMAT_LE_BGRA8888: + return D3DFMT_LE_A8R8G8B8; +#endif + + // nVidia overloads DST formats as texture formats + case IMAGE_FORMAT_NV_DST16: + if ( TestTextureFormat( D3DFMT_D16, isRenderTarget, bIsVertexTexture, bIsFilterableRequired ) ) + return D3DFMT_D16; + break; + + case IMAGE_FORMAT_NV_DST24: + if ( TestTextureFormat( D3DFMT_D24S8, isRenderTarget, bIsVertexTexture, bIsFilterableRequired ) ) + return D3DFMT_D24S8; + break; + case IMAGE_FORMAT_NV_INTZ: + if ( TestTextureFormat( NVFMT_INTZ, isRenderTarget, bIsVertexTexture, false ) ) + return NVFMT_INTZ; + break; + + case IMAGE_FORMAT_NV_RAWZ: + if ( TestTextureFormat( NVFMT_RAWZ, isRenderTarget, bIsVertexTexture, false ) ) + return NVFMT_RAWZ; + break; + + case IMAGE_FORMAT_NV_NULL: + if ( TestTextureFormat( NVFMT_NULL, isRenderTarget, bIsVertexTexture, false ) ) + return NVFMT_NULL; + break; + + case IMAGE_FORMAT_ATI_DST16: + if ( TestTextureFormat( ATIFMT_D16, isRenderTarget, bIsVertexTexture, false ) ) + return ATIFMT_D16; + break; + + case IMAGE_FORMAT_ATI_DST24: + if ( TestTextureFormat( ATIFMT_D24S8, isRenderTarget, bIsVertexTexture, false ) ) + return ATIFMT_D24S8; + break; + + case IMAGE_FORMAT_ATI2N: + if ( TestTextureFormat( ATIFMT_ATI2N, isRenderTarget, bIsVertexTexture, bIsFilterableRequired ) ) + return ATIFMT_ATI2N; + break; + + case IMAGE_FORMAT_ATI1N: + if ( TestTextureFormat( ATIFMT_ATI1N, isRenderTarget, bIsVertexTexture, bIsFilterableRequired ) ) + return ATIFMT_ATI1N; + break; + } + + return D3DFMT_UNKNOWN; +} + +void InitializeColorInformation( UINT displayAdapter, D3DDEVTYPE deviceType, + ImageFormat displayFormat ) +{ + g_DisplayAdapter = displayAdapter; + g_DeviceType = deviceType; + g_DeviceFormat = displayFormat; + + int fmt = 0; + while ( fmt < NUM_IMAGE_FORMATS ) + { + for ( int nVertexTexture = 0; nVertexTexture <= 1; ++nVertexTexture ) + { + for ( int nRenderTarget = 0; nRenderTarget <= 1; ++nRenderTarget ) + { + for ( int nFilterable = 0; nFilterable <= 1; ++nFilterable ) + { + g_D3DColorFormat[fmt][nVertexTexture][nRenderTarget][nFilterable] = + GetNearestD3DColorFormat( (ImageFormat)fmt, nRenderTarget != 0, nVertexTexture != 0, nFilterable != 0 ); + } + } + } + ++fmt; + } + + // Check the depth formats + HRESULT hr = D3D()->CheckDeviceFormat( + g_DisplayAdapter, g_DeviceType, ImageLoader::ImageFormatToD3DFormat( g_DeviceFormat ), + D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24S8 ); + g_bSupportsD24S8 = !FAILED(hr); + + hr = D3D()->CheckDeviceFormat( + g_DisplayAdapter, g_DeviceType, ImageLoader::ImageFormatToD3DFormat( g_DeviceFormat ), + D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24X8 ); + g_bSupportsD24X8 = !FAILED(hr); + + hr = D3D()->CheckDeviceFormat( + g_DisplayAdapter, g_DeviceType, ImageLoader::ImageFormatToD3DFormat( g_DeviceFormat ), + D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D16 ); + g_bSupportsD16 = !FAILED(hr); + +#if !defined( _X360 ) + hr = D3D()->CheckDeviceFormat( + g_DisplayAdapter, g_DeviceType, ImageLoader::ImageFormatToD3DFormat( g_DeviceFormat ), + D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24X4S4 ); + g_bSupportsD24X4S4 = !FAILED(hr); +#else + g_bSupportsD24X4S4 = false; +#endif + +#if !defined( _X360 ) + hr = D3D()->CheckDeviceFormat( + g_DisplayAdapter, g_DeviceType, ImageLoader::ImageFormatToD3DFormat( g_DeviceFormat ), + D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D15S1 ); + g_bSupportsD15S1 = !FAILED(hr); +#else + g_bSupportsD15S1 = false; +#endif +} + + +//----------------------------------------------------------------------------- +// Returns true if compressed textures are supported +//----------------------------------------------------------------------------- +bool D3DSupportsCompressedTextures() +{ + return (g_D3DColorFormat[IMAGE_FORMAT_DXT1][0][0][0] != D3DFMT_UNKNOWN) && + (g_D3DColorFormat[IMAGE_FORMAT_DXT3][0][0][0] != D3DFMT_UNKNOWN) && + (g_D3DColorFormat[IMAGE_FORMAT_DXT5][0][0][0] != D3DFMT_UNKNOWN); +} + + +//----------------------------------------------------------------------------- +// Returns closest supported format +//----------------------------------------------------------------------------- +ImageFormat FindNearestSupportedFormat( ImageFormat format, bool bIsVertexTexture, bool bIsRenderTarget, bool bFilterableRequired ) +{ + return ImageLoader::D3DFormatToImageFormat( g_D3DColorFormat[format][bIsVertexTexture][bIsRenderTarget][bFilterableRequired] ); +} + + +//----------------------------------------------------------------------------- +// Returns true if compressed textures are supported +//----------------------------------------------------------------------------- +bool D3DSupportsDepthTexture(D3DFORMAT format) +{ + // See if we can do it! + HRESULT hr = D3D()->CheckDeviceFormat( + g_DisplayAdapter, g_DeviceType, ImageLoader::ImageFormatToD3DFormat(g_DeviceFormat), + D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format); + + return !FAILED(hr); +} + + +//----------------------------------------------------------------------------- +// Returns true if the depth format is compatible with the display +//----------------------------------------------------------------------------- +static inline bool IsDepthFormatCompatible( int nAdapter, ImageFormat displayFormat, ImageFormat renderTargetFormat, D3DFORMAT depthFormat ) +{ + D3DFORMAT d3dDisplayFormat = ImageLoader::ImageFormatToD3DFormat( displayFormat ); + D3DFORMAT d3dRenderTargetFormat = ImageLoader::ImageFormatToD3DFormat( renderTargetFormat ); + + // Verify that the depth format is compatible. + HRESULT hr = D3D()->CheckDepthStencilMatch( nAdapter, DX8_DEVTYPE, + d3dDisplayFormat, d3dRenderTargetFormat, depthFormat); + return !FAILED(hr); +} + +//----------------------------------------------------------------------------- +// Finds the nearest supported depth buffer format +//----------------------------------------------------------------------------- +D3DFORMAT FindNearestSupportedDepthFormat( int nAdapter, ImageFormat displayFormat, ImageFormat renderTargetFormat, D3DFORMAT depthFormat ) +{ + // This is the default case, used for rendering to the main render target + Assert( displayFormat != IMAGE_FORMAT_UNKNOWN && renderTargetFormat != IMAGE_FORMAT_UNKNOWN ); + + switch (depthFormat) + { +#if defined( _X360 ) + case D3DFMT_D24FS8: + return D3DFMT_D24FS8; + + case D3DFMT_LIN_D24S8: + if ( g_bSupportsD24S8 && IsDepthFormatCompatible( nAdapter, displayFormat, renderTargetFormat, D3DFMT_LIN_D24S8 ) ) + return D3DFMT_LIN_D24S8; +#endif + case D3DFMT_D24S8: + if ( g_bSupportsD24S8 && IsDepthFormatCompatible( nAdapter, displayFormat, renderTargetFormat, D3DFMT_D24S8 ) ) + return D3DFMT_D24S8; +#if !defined( _X360 ) + if ( g_bSupportsD24X4S4 && IsDepthFormatCompatible( nAdapter, displayFormat, renderTargetFormat, D3DFMT_D24X4S4 ) ) + return D3DFMT_D24X4S4; + if ( g_bSupportsD15S1 && IsDepthFormatCompatible( nAdapter, displayFormat, renderTargetFormat, D3DFMT_D15S1 ) ) + return D3DFMT_D15S1; +#endif + if ( g_bSupportsD24X8 && IsDepthFormatCompatible( nAdapter, displayFormat, renderTargetFormat, D3DFMT_D24X8 ) ) + return D3DFMT_D24X8; + if ( g_bSupportsD16 && IsDepthFormatCompatible( nAdapter, displayFormat, renderTargetFormat, D3DFMT_D16 ) ) + return D3DFMT_D16; + break; + + case D3DFMT_D24X8: + if ( g_bSupportsD24X8 && IsDepthFormatCompatible( nAdapter, displayFormat, renderTargetFormat, D3DFMT_D24X8 ) ) + return D3DFMT_D24X8; + if ( g_bSupportsD24S8 && IsDepthFormatCompatible( nAdapter, displayFormat, renderTargetFormat, D3DFMT_D24S8 ) ) + return D3DFMT_D24S8; +#if !defined( _X360 ) + if ( g_bSupportsD24X4S4 && IsDepthFormatCompatible( nAdapter, displayFormat, renderTargetFormat, D3DFMT_D24X4S4 ) ) + return D3DFMT_D24X4S4; +#endif + if ( g_bSupportsD16 && IsDepthFormatCompatible( nAdapter, displayFormat, renderTargetFormat, D3DFMT_D16 ) ) + return D3DFMT_D16; +#if !defined( _X360 ) + if ( g_bSupportsD15S1 && IsDepthFormatCompatible( nAdapter, displayFormat, renderTargetFormat, D3DFMT_D15S1 ) ) + return D3DFMT_D15S1; +#endif + break; + + case D3DFMT_D16: + if ( g_bSupportsD16 && IsDepthFormatCompatible( nAdapter, displayFormat, renderTargetFormat, D3DFMT_D16 ) ) + return D3DFMT_D16; +#if !defined( _X360 ) + if ( g_bSupportsD15S1 && IsDepthFormatCompatible( nAdapter, displayFormat, renderTargetFormat, D3DFMT_D15S1 ) ) + return D3DFMT_D15S1; +#endif + if ( g_bSupportsD24X8 && IsDepthFormatCompatible( nAdapter, displayFormat, renderTargetFormat, D3DFMT_D24X8 ) ) + return D3DFMT_D24X8; + if ( g_bSupportsD24S8 && IsDepthFormatCompatible( nAdapter, displayFormat, renderTargetFormat, D3DFMT_D24S8 ) ) + return D3DFMT_D24S8; +#if !defined( _X360 ) + if ( g_bSupportsD24X4S4 && IsDepthFormatCompatible( nAdapter, displayFormat, renderTargetFormat, D3DFMT_D24X4S4 ) ) + return D3DFMT_D24X4S4; +#endif + break; + } + + Assert( 0 ); + return D3DFMT_D16; +} + + +//----------------------------------------------------------------------------- +// Is a display buffer valid? +//----------------------------------------------------------------------------- +static inline bool IsFrameBufferFormatValid( UINT displayAdapter, D3DDEVTYPE deviceType, + D3DFORMAT displayFormat, D3DFORMAT backBufferFormat, bool bIsWindowed ) +{ + HRESULT hr = D3D()->CheckDeviceType( displayAdapter, deviceType, displayFormat, + backBufferFormat, bIsWindowed ); + return !FAILED(hr); +} + + +//----------------------------------------------------------------------------- +// Finds the nearest supported frame buffer format +//----------------------------------------------------------------------------- +ImageFormat FindNearestSupportedBackBufferFormat( UINT displayAdapter, + D3DDEVTYPE deviceType, ImageFormat displayFormat, ImageFormat backBufferFormat, bool bIsWindowed ) +{ + D3DFORMAT d3dDisplayFormat = ImageLoader::ImageFormatToD3DFormat( displayFormat ); + switch (backBufferFormat) + { + case IMAGE_FORMAT_RGBA8888: + case IMAGE_FORMAT_ABGR8888: + case IMAGE_FORMAT_ARGB8888: + case IMAGE_FORMAT_BGRA8888: + case IMAGE_FORMAT_BGRA4444: // This is not supported ever; bump up to 32 bit + if (IsFrameBufferFormatValid( displayAdapter, deviceType, d3dDisplayFormat, D3DFMT_A8R8G8B8, bIsWindowed )) + return IMAGE_FORMAT_BGRA8888; + + // Bye, bye dest alpha + if (IsFrameBufferFormatValid( displayAdapter, deviceType, d3dDisplayFormat, D3DFMT_X8R8G8B8, bIsWindowed )) + return IMAGE_FORMAT_BGRX8888; + + if (IsFrameBufferFormatValid( displayAdapter, deviceType, d3dDisplayFormat, D3DFMT_R5G6B5, bIsWindowed )) + return IMAGE_FORMAT_BGR565; + + if (IsFrameBufferFormatValid( displayAdapter, deviceType, d3dDisplayFormat, D3DFMT_A1R5G5B5, bIsWindowed )) + return IMAGE_FORMAT_BGRA5551; + + if (IsFrameBufferFormatValid( displayAdapter, deviceType, d3dDisplayFormat, D3DFMT_X1R5G5B5, bIsWindowed )) + return IMAGE_FORMAT_BGRX5551; + + return IMAGE_FORMAT_UNKNOWN; + + case IMAGE_FORMAT_RGB888: + case IMAGE_FORMAT_BGR888: + case IMAGE_FORMAT_RGB888_BLUESCREEN: + case IMAGE_FORMAT_BGRX8888: + if (IsFrameBufferFormatValid( displayAdapter, deviceType, d3dDisplayFormat, D3DFMT_X8R8G8B8, bIsWindowed )) + return IMAGE_FORMAT_BGRX8888; + + if (IsFrameBufferFormatValid( displayAdapter, deviceType, d3dDisplayFormat, D3DFMT_A8R8G8B8, bIsWindowed )) + return IMAGE_FORMAT_BGRA8888; + + if (IsFrameBufferFormatValid( displayAdapter, deviceType, d3dDisplayFormat, D3DFMT_R5G6B5, bIsWindowed )) + return IMAGE_FORMAT_BGR565; + + if (IsFrameBufferFormatValid( displayAdapter, deviceType, d3dDisplayFormat, D3DFMT_A1R5G5B5, bIsWindowed )) + return IMAGE_FORMAT_BGRA5551; + + if (IsFrameBufferFormatValid( displayAdapter, deviceType, d3dDisplayFormat, D3DFMT_X1R5G5B5, bIsWindowed )) + return IMAGE_FORMAT_BGRX5551; + + return IMAGE_FORMAT_UNKNOWN; + + case IMAGE_FORMAT_RGB565: + case IMAGE_FORMAT_BGR565: + if (IsFrameBufferFormatValid( displayAdapter, deviceType, d3dDisplayFormat, D3DFMT_R5G6B5, bIsWindowed )) + return IMAGE_FORMAT_BGR565; + + if (IsFrameBufferFormatValid( displayAdapter, deviceType, d3dDisplayFormat, D3DFMT_A1R5G5B5, bIsWindowed )) + return IMAGE_FORMAT_BGRA5551; + + if (IsFrameBufferFormatValid( displayAdapter, deviceType, d3dDisplayFormat, D3DFMT_X1R5G5B5, bIsWindowed )) + return IMAGE_FORMAT_BGRX5551; + + if (IsFrameBufferFormatValid( displayAdapter, deviceType, d3dDisplayFormat, D3DFMT_X8R8G8B8, bIsWindowed )) + return IMAGE_FORMAT_BGRX8888; + + if (IsFrameBufferFormatValid( displayAdapter, deviceType, d3dDisplayFormat, D3DFMT_A8R8G8B8, bIsWindowed )) + return IMAGE_FORMAT_BGRA8888; + + return IMAGE_FORMAT_UNKNOWN; + + case IMAGE_FORMAT_BGRX5551: + if (IsFrameBufferFormatValid( displayAdapter, deviceType, d3dDisplayFormat, D3DFMT_X1R5G5B5, bIsWindowed )) + return IMAGE_FORMAT_BGRX5551; + + if (IsFrameBufferFormatValid( displayAdapter, deviceType, d3dDisplayFormat, D3DFMT_A1R5G5B5, bIsWindowed )) + return IMAGE_FORMAT_BGRA5551; + + if (IsFrameBufferFormatValid( displayAdapter, deviceType, d3dDisplayFormat, D3DFMT_R5G6B5, bIsWindowed )) + return IMAGE_FORMAT_BGR565; + + if (IsFrameBufferFormatValid( displayAdapter, deviceType, d3dDisplayFormat, D3DFMT_X8R8G8B8, bIsWindowed )) + return IMAGE_FORMAT_BGRX8888; + + if (IsFrameBufferFormatValid( displayAdapter, deviceType, d3dDisplayFormat, D3DFMT_A8R8G8B8, bIsWindowed )) + return IMAGE_FORMAT_BGRA8888; + + return IMAGE_FORMAT_UNKNOWN; + + case IMAGE_FORMAT_BGRA5551: + if (IsFrameBufferFormatValid( displayAdapter, deviceType, d3dDisplayFormat, D3DFMT_A1R5G5B5, bIsWindowed )) + return IMAGE_FORMAT_BGRA5551; + + if (IsFrameBufferFormatValid( displayAdapter, deviceType, d3dDisplayFormat, D3DFMT_X1R5G5B5, bIsWindowed )) + return IMAGE_FORMAT_BGRX5551; + + if (IsFrameBufferFormatValid( displayAdapter, deviceType, d3dDisplayFormat, D3DFMT_R5G6B5, bIsWindowed )) + return IMAGE_FORMAT_BGR565; + + if (IsFrameBufferFormatValid( displayAdapter, deviceType, d3dDisplayFormat, D3DFMT_A8R8G8B8, bIsWindowed )) + return IMAGE_FORMAT_BGRA8888; + + if (IsFrameBufferFormatValid( displayAdapter, deviceType, d3dDisplayFormat, D3DFMT_X8R8G8B8, bIsWindowed )) + return IMAGE_FORMAT_BGRX8888; + + return IMAGE_FORMAT_UNKNOWN; + } + + return IMAGE_FORMAT_UNKNOWN; +} + +#if defined( _X360 ) +const char *D3DFormatName( D3DFORMAT d3dFormat ) +{ + if ( IS_D3DFORMAT_SRGB( d3dFormat ) ) + { + // sanitize the format from possible sRGB state for comparison purposes + d3dFormat = MAKE_NON_SRGB_FMT( d3dFormat ); + } + + switch ( d3dFormat ) + { + case D3DFMT_A8R8G8B8: + return "D3DFMT_A8R8G8B8"; + case D3DFMT_LIN_A8R8G8B8: + return "D3DFMT_LIN_A8R8G8B8"; + case D3DFMT_X8R8G8B8: + return "D3DFMT_X8R8G8B8"; + case D3DFMT_LIN_X8R8G8B8: + return "D3DFMT_LIN_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_L8: + return "D3DFMT_L8"; + case D3DFMT_A8L8: + return "D3DFMT_A8L8"; + case D3DFMT_A8: + return "D3DFMT_A8"; + case D3DFMT_DXT1: + return "D3DFMT_DXT1"; + case D3DFMT_DXT3: + return "D3DFMT_DXT3"; + case D3DFMT_DXT5: + return "D3DFMT_DXT5"; + case D3DFMT_V8U8: + return "D3DFMT_V8U8"; + case D3DFMT_Q8W8V8U8: + return "D3DFMT_Q8W8V8U8"; + case D3DFMT_D16: + return "D3DFMT_D16"; + case D3DFMT_D24S8: + return "D3DFMT_D24S8"; + case D3DFMT_D24FS8: + return "D3DFMT_D24FS8"; + case D3DFMT_LIN_D24S8: + return "D3DFMT_LIN_D24S8"; + case D3DFMT_A16B16G16R16: + return "D3DFMT_A16B16G16R16"; + case D3DFMT_LIN_A16B16G16R16: + return "D3DFMT_LIN_A16B16G16R16"; + } + return "???"; +} +#endif |