mirror of
https://github.com/nillerusr/source-engine.git
synced 2024-12-22 06:06:50 +00:00
728 lines
26 KiB
C++
728 lines
26 KiB
C++
//========= 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
|