source-engine/materialsystem/shaderapidx9/colorformatdx8.cpp

728 lines
26 KiB
C++
Raw Normal View History

2020-04-22 16:56:21 +00:00
//========= 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