You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
727 lines
26 KiB
727 lines
26 KiB
//========= 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
|
|
|