summaryrefslogtreecommitdiff
path: root/materialsystem/shaderapidx9/colorformatdx8.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /materialsystem/shaderapidx9/colorformatdx8.cpp
downloadarchived-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.cpp727
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