iw4x-client/deps/dxsdk/Include/D3DX_DXGIFormatConvert.inl
2024-03-07 05:13:50 -05:00

801 lines
33 KiB
C++

//=============================================================================
// D3D11 HLSL Routines for Manual Pack/Unpack of 32-bit DXGI_FORMAT_*
//=============================================================================
//
// This file contains format conversion routines for use in the
// Compute Shader or Pixel Shader on D3D11 Hardware.
//
// Skip to the end of this comment to see a summary of the routines
// provided. The rest of the text below explains why they are needed
// and how to use them.
//
// The scenario where these can be useful is if your application
// needs to simultaneously both read and write texture - i.e. in-place
// image editing.
//
// D3D11's Unordered Access View (UAV) of a Texture1D/2D/3D resource
// allows random access reads and writes to memory from a Compute Shader
// or Pixel Shader. However, the only texture format that supports this
// is DXGI_FORMAT_R32_UINT. e.g. Other more interesting formats like
// DXGI_FORMAT_R8G8B8A8_UNORM do not support simultaneous read and
// write. You can use such formats for random access writing only
// using a UAV, or reading only using a Shader Resource View (SRV).
// But for simultaneous read+write, the format conversion hardware is
// not available.
//
// There is a workaround to this limitation, involving casting the texture
// to R32_UINT when creating a UAV, as long as the original format of the
// resource supports it (most 32 bit per element formats). This allows
// simultaneous read+write as long as the shader does manual format
// unpacking on read and packing on write.
//
// The benefit is that later on, other views such as RenderTarget Views
// or ShaderResource Views on the same texture can be used with the
// proper format (e.g. DXGI_FORMAT_R16G16_FLOAT) so the hardware can
// do the usual automatic format unpack/pack and do texture filtering etc.
// where there are no hardware limitations.
//
// The sequence of actions for an application is the following:
//
// Suppose you want to make a texture than you can use a Pixel Shader
// or Compute Shader to perform in-place editing, and that the format
// you want the data to be stored in happens to be a descendent
// of of one of these formats:
//
// DXGI_FORMAT_R10G10B10A2_TYPELESS
// DXGI_FORMAT_R8G8B8A8_TYPELESS
// DXGI_FORMAT_B8G8R8A8_TYPELESS
// DXGI_FORMAT_B8G8R8X8_TYPELESS
// DXGI_FORMAT_R16G16_TYPELESS
//
// e.g. DXGI_FORMAT_R10G10B10A2_UNORM is a descendent of
// DXGI_FORMAT_R10G10B10A2_TYPELESS, so it supports the
// usage pattern described here.
//
// (Formats descending from DXGI_FORMAT_R32_TYPELESS, such as
// DXGI_FORMAT_R32_FLOAT, are trivially supported without
// needing any of the format conversion help provided here.)
//
// Steps:
//
// (1) Create a texture with the appropriate _TYPELESS format above
// along with the needed bind flags, such as
// D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE.
//
// (2) For in-place image editing, create a UAV with the format
// DXGI_FORMAT_R32_UINT. D3D normally doesn't allow casting
// between different format "families", but the API makes
// an exception here.
//
// (3) In the Compute Shader or Pixel Shader, use the appropriate
// format pack/unpack routines provided in this file.
// For example if the DXGI_FORMAT_R32_UINT UAV really holds
// DXGI_FORMAT_R10G10B10A2_UNORM data, then, after reading a
// uint from the UAV into the shader, unpack by calling:
//
// XMFLOAT4 D3DX_R10G10B10A2_UNORM_to_FLOAT4(UINT packedInput)
//
// Then to write to the UAV in the same shader, call the following
// to pack shader data into a uint that can be written out:
//
// UINT D3DX_FLOAT4_to_R10G10B10A2_UNORM(hlsl_precise XMFLOAT4 unpackedInput)
//
// (4) Other views, such as SRVs, can be created with the desired format;
// e.g. DXGI_FORMAT_R10G10B10A2_UNORM if the resource was created as
// DXGI_FORMAT_R10G10B10A2_TYPELESS. When that view is accessed by a
// shader, the hardware can do automatic type conversion as usual.
//
// Note, again, that if the shader only needs to write to a UAV, or read
// as an SRV, then none of this is needed - fully typed UAV or SRVs can
// be used. Only if simultaneous reading and writing to a UAV of a texture
// is needed are the format conversion routines provided here potentially
// useful.
//
// The following is the list of format conversion routines included in this
// file, categorized by the DXGI_FORMAT they unpack/pack. Each of the
// formats supported descends from one of the TYPELESS formats listed
// above, and supports casting to DXGI_FORMAT_R32_UINT as a UAV.
//
// DXGI_FORMAT_R10G10B10A2_UNORM:
//
// XMFLOAT4 D3DX_R10G10B10A2_UNORM_to_FLOAT4(UINT packedInput)
// UINT D3DX_FLOAT4_to_R10G10B10A2_UNORM(hlsl_precise XMFLOAT4 unpackedInput)
//
// DXGI_FORMAT_R10G10B10A2_UINT:
//
// XMUINT4 D3DX_R10G10B10A2_UINT_to_UINT4(UINT packedInput)
// UINT D3DX_UINT4_to_R10G10B10A2_UINT(XMUINT4 unpackedInput)
//
// DXGI_FORMAT_R8G8B8A8_UNORM:
//
// XMFLOAT4 D3DX_R8G8B8A8_UNORM_to_FLOAT4(UINT packedInput)
// UINT D3DX_FLOAT4_to_R8G8B8A8_UNORM(hlsl_precise XMFLOAT4 unpackedInput)
//
// DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
//
// XMFLOAT4 D3DX_R8G8B8A8_UNORM_SRGB_to_FLOAT4_inexact(UINT packedInput) *
// XMFLOAT4 D3DX_R8G8B8A8_UNORM_SRGB_to_FLOAT4(UINT packedInput)
// UINT D3DX_FLOAT4_to_R8G8B8A8_UNORM_SRGB(hlsl_precise XMFLOAT4 unpackedInput)
//
// * The "_inexact" function above uses shader instructions that don't
// have high enough precision to give the exact answer, albeit close.
// The alternative function uses a lookup table stored in the shader
// to give an exact SRGB->float conversion.
//
// DXGI_FORMAT_R8G8B8A8_UINT:
//
// XMUINT4 D3DX_R8G8B8A8_UINT_to_UINT4(UINT packedInput)
// XMUINT D3DX_UINT4_to_R8G8B8A8_UINT(XMUINT4 unpackedInput)
//
// DXGI_FORMAT_R8G8B8A8_SNORM:
//
// XMFLOAT4 D3DX_R8G8B8A8_SNORM_to_FLOAT4(UINT packedInput)
// UINT D3DX_FLOAT4_to_R8G8B8A8_SNORM(hlsl_precise XMFLOAT4 unpackedInput)
//
// DXGI_FORMAT_R8G8B8A8_SINT:
//
// XMINT4 D3DX_R8G8B8A8_SINT_to_INT4(UINT packedInput)
// UINT D3DX_INT4_to_R8G8B8A8_SINT(XMINT4 unpackedInput)
//
// DXGI_FORMAT_B8G8R8A8_UNORM:
//
// XMFLOAT4 D3DX_B8G8R8A8_UNORM_to_FLOAT4(UINT packedInput)
// UINT D3DX_FLOAT4_to_B8G8R8A8_UNORM(hlsl_precise XMFLOAT4 unpackedInput)
//
// DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
//
// XMFLOAT4 D3DX_B8G8R8A8_UNORM_SRGB_to_FLOAT4_inexact(UINT packedInput) *
// XMFLOAT4 D3DX_B8G8R8A8_UNORM_SRGB_to_FLOAT4(UINT packedInput)
// UINT D3DX_FLOAT4_to_R8G8B8A8_UNORM_SRGB(hlsl_precise XMFLOAT4 unpackedInput)
//
// * The "_inexact" function above uses shader instructions that don't
// have high enough precision to give the exact answer, albeit close.
// The alternative function uses a lookup table stored in the shader
// to give an exact SRGB->float conversion.
//
// DXGI_FORMAT_B8G8R8X8_UNORM:
//
// XMFLOAT3 D3DX_B8G8R8X8_UNORM_to_FLOAT3(UINT packedInput)
// UINT D3DX_FLOAT3_to_B8G8R8X8_UNORM(hlsl_precise XMFLOAT3 unpackedInput)
//
// DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
//
// XMFLOAT3 D3DX_B8G8R8X8_UNORM_SRGB_to_FLOAT3_inexact(UINT packedInput) *
// XMFLOAT3 D3DX_B8G8R8X8_UNORM_SRGB_to_FLOAT3(UINT packedInput)
// UINT D3DX_FLOAT3_to_B8G8R8X8_UNORM_SRGB(hlsl_precise XMFLOAT3 unpackedInput)
//
// * The "_inexact" function above uses shader instructions that don't
// have high enough precision to give the exact answer, albeit close.
// The alternative function uses a lookup table stored in the shader
// to give an exact SRGB->float conversion.
//
// DXGI_FORMAT_R16G16_FLOAT:
//
// XMFLOAT2 D3DX_R16G16_FLOAT_to_FLOAT2(UINT packedInput)
// UINT D3DX_FLOAT2_to_R16G16_FLOAT(hlsl_precise XMFLOAT2 unpackedInput)
//
// DXGI_FORMAT_R16G16_UNORM:
//
// XMFLOAT2 D3DX_R16G16_UNORM_to_FLOAT2(UINT packedInput)
// UINT D3DX_FLOAT2_to_R16G16_UNORM(hlsl_precise FLOAT2 unpackedInput)
//
// DXGI_FORMAT_R16G16_UINT:
//
// XMUINT2 D3DX_R16G16_UINT_to_UINT2(UINT packedInput)
// UINT D3DX_UINT2_to_R16G16_UINT(XMUINT2 unpackedInput)
//
// DXGI_FORMAT_R16G16_SNORM:
//
// XMFLOAT2 D3DX_R16G16_SNORM_to_FLOAT2(UINT packedInput)
// UINT D3DX_FLOAT2_to_R16G16_SNORM(hlsl_precise XMFLOAT2 unpackedInput)
//
// DXGI_FORMAT_R16G16_SINT:
//
// XMINT2 D3DX_R16G16_SINT_to_INT2(UINT packedInput)
// UINT D3DX_INT2_to_R16G16_SINT(XMINT2 unpackedInput)
//
//=============================================================================
#ifndef __D3DX_DXGI_FORMAT_CONVERT_INL___
#define __D3DX_DXGI_FORMAT_CONVERT_INL___
#if HLSL_VERSION > 0
#define D3DX11INLINE
typedef int INT;
typedef uint UINT;
typedef float2 XMFLOAT2;
typedef float3 XMFLOAT3;
typedef float4 XMFLOAT4;
typedef int2 XMINT2;
typedef int4 XMINT4;
typedef uint2 XMUINT2;
typedef uint4 XMUINT4;
#define hlsl_precise precise
#define D3DX_Saturate_FLOAT(_V) saturate(_V)
#define D3DX_IsNan(_V) isnan(_V)
#define D3DX_Truncate_FLOAT(_V) trunc(_V)
#else // HLSL_VERSION > 0
#ifndef __cplusplus
#error C++ compilation required
#endif
#include <float.h>
#include <xnamath.h>
#define hlsl_precise
D3DX11INLINE FLOAT D3DX_Saturate_FLOAT(FLOAT _V)
{
return min(max(_V, 0), 1);
}
D3DX11INLINE bool D3DX_IsNan(FLOAT _V)
{
return _V != _V;
}
D3DX11INLINE FLOAT D3DX_Truncate_FLOAT(FLOAT _V)
{
return _V >= 0 ? floor(_V) : ceil(_V);
}
// 2D Vector; 32 bit signed integer components
typedef struct _XMINT2
{
INT x;
INT y;
} XMINT2;
// 2D Vector; 32 bit unsigned integer components
typedef struct _XMUINT2
{
UINT x;
UINT y;
} XMUINT2;
// 4D Vector; 32 bit signed integer components
typedef struct _XMINT4
{
INT x;
INT y;
INT z;
INT w;
} XMINT4;
// 4D Vector; 32 bit unsigned integer components
typedef struct _XMUINT4
{
UINT x;
UINT y;
UINT z;
UINT w;
} XMUINT4;
#endif // HLSL_VERSION > 0
//=============================================================================
// SRGB Helper Functions Called By Conversions Further Below.
//=============================================================================
// SRGB_to_FLOAT_inexact is imprecise due to precision of pow implementations.
// If exact SRGB->float conversion is needed, a table lookup is provided
// further below.
D3DX11INLINE FLOAT D3DX_SRGB_to_FLOAT_inexact(hlsl_precise FLOAT val)
{
if( val < 0.04045f )
val /= 12.92f;
else
val = pow((val + 0.055f)/1.055f,2.4f);
return val;
}
static const UINT D3DX_SRGBTable[] =
{
0x00000000,0x399f22b4,0x3a1f22b4,0x3a6eb40e,0x3a9f22b4,0x3ac6eb61,0x3aeeb40e,0x3b0b3e5d,
0x3b1f22b4,0x3b33070b,0x3b46eb61,0x3b5b518d,0x3b70f18d,0x3b83e1c6,0x3b8fe616,0x3b9c87fd,
0x3ba9c9b7,0x3bb7ad6f,0x3bc63549,0x3bd56361,0x3be539c1,0x3bf5ba70,0x3c0373b5,0x3c0c6152,
0x3c15a703,0x3c1f45be,0x3c293e6b,0x3c3391f7,0x3c3e4149,0x3c494d43,0x3c54b6c7,0x3c607eb1,
0x3c6ca5df,0x3c792d22,0x3c830aa8,0x3c89af9f,0x3c9085db,0x3c978dc5,0x3c9ec7c2,0x3ca63433,
0x3cadd37d,0x3cb5a601,0x3cbdac20,0x3cc5e639,0x3cce54ab,0x3cd6f7d5,0x3cdfd010,0x3ce8ddb9,
0x3cf2212c,0x3cfb9ac1,0x3d02a569,0x3d0798dc,0x3d0ca7e6,0x3d11d2af,0x3d171963,0x3d1c7c2e,
0x3d21fb3c,0x3d2796b2,0x3d2d4ebb,0x3d332380,0x3d39152b,0x3d3f23e3,0x3d454fd1,0x3d4b991c,
0x3d51ffef,0x3d58846a,0x3d5f26b7,0x3d65e6fe,0x3d6cc564,0x3d73c20f,0x3d7add29,0x3d810b67,
0x3d84b795,0x3d887330,0x3d8c3e4a,0x3d9018f6,0x3d940345,0x3d97fd4a,0x3d9c0716,0x3da020bb,
0x3da44a4b,0x3da883d7,0x3daccd70,0x3db12728,0x3db59112,0x3dba0b3b,0x3dbe95b5,0x3dc33092,
0x3dc7dbe2,0x3dcc97b6,0x3dd1641f,0x3dd6412c,0x3ddb2eef,0x3de02d77,0x3de53cd5,0x3dea5d19,
0x3def8e52,0x3df4d091,0x3dfa23e8,0x3dff8861,0x3e027f07,0x3e054280,0x3e080ea3,0x3e0ae378,
0x3e0dc105,0x3e10a754,0x3e13966b,0x3e168e52,0x3e198f10,0x3e1c98ad,0x3e1fab30,0x3e22c6a3,
0x3e25eb09,0x3e29186c,0x3e2c4ed0,0x3e2f8e41,0x3e32d6c4,0x3e362861,0x3e39831e,0x3e3ce703,
0x3e405416,0x3e43ca5f,0x3e4749e4,0x3e4ad2ae,0x3e4e64c2,0x3e520027,0x3e55a4e6,0x3e595303,
0x3e5d0a8b,0x3e60cb7c,0x3e6495e0,0x3e6869bf,0x3e6c4720,0x3e702e0c,0x3e741e84,0x3e781890,
0x3e7c1c38,0x3e8014c2,0x3e82203c,0x3e84308d,0x3e8645ba,0x3e885fc5,0x3e8a7eb2,0x3e8ca283,
0x3e8ecb3d,0x3e90f8e1,0x3e932b74,0x3e9562f8,0x3e979f71,0x3e99e0e2,0x3e9c274e,0x3e9e72b7,
0x3ea0c322,0x3ea31892,0x3ea57308,0x3ea7d289,0x3eaa3718,0x3eaca0b7,0x3eaf0f69,0x3eb18333,
0x3eb3fc18,0x3eb67a18,0x3eb8fd37,0x3ebb8579,0x3ebe12e1,0x3ec0a571,0x3ec33d2d,0x3ec5da17,
0x3ec87c33,0x3ecb2383,0x3ecdd00b,0x3ed081cd,0x3ed338cc,0x3ed5f50b,0x3ed8b68d,0x3edb7d54,
0x3ede4965,0x3ee11ac1,0x3ee3f16b,0x3ee6cd67,0x3ee9aeb6,0x3eec955d,0x3eef815d,0x3ef272ba,
0x3ef56976,0x3ef86594,0x3efb6717,0x3efe6e02,0x3f00bd2d,0x3f02460e,0x3f03d1a7,0x3f055ff9,
0x3f06f106,0x3f0884cf,0x3f0a1b56,0x3f0bb49b,0x3f0d50a0,0x3f0eef67,0x3f1090f1,0x3f12353e,
0x3f13dc51,0x3f15862b,0x3f1732cd,0x3f18e239,0x3f1a946f,0x3f1c4971,0x3f1e0141,0x3f1fbbdf,
0x3f21794e,0x3f23398e,0x3f24fca0,0x3f26c286,0x3f288b41,0x3f2a56d3,0x3f2c253d,0x3f2df680,
0x3f2fca9e,0x3f31a197,0x3f337b6c,0x3f355820,0x3f3737b3,0x3f391a26,0x3f3aff7c,0x3f3ce7b5,
0x3f3ed2d2,0x3f40c0d4,0x3f42b1be,0x3f44a590,0x3f469c4b,0x3f4895f1,0x3f4a9282,0x3f4c9201,
0x3f4e946e,0x3f5099cb,0x3f52a218,0x3f54ad57,0x3f56bb8a,0x3f58ccb0,0x3f5ae0cd,0x3f5cf7e0,
0x3f5f11ec,0x3f612eee,0x3f634eef,0x3f6571e9,0x3f6797e3,0x3f69c0d6,0x3f6beccd,0x3f6e1bbf,
0x3f704db8,0x3f7282af,0x3f74baae,0x3f76f5ae,0x3f7933b9,0x3f7b74c6,0x3f7db8e0,0x3f800000
};
D3DX11INLINE FLOAT D3DX_SRGB_to_FLOAT(UINT val)
{
#if HLSL_VERSION > 0
return asfloat(D3DX_SRGBTable[val]);
#else
return *(FLOAT*)&D3DX_SRGBTable[val];
#endif
}
D3DX11INLINE FLOAT D3DX_FLOAT_to_SRGB(hlsl_precise FLOAT val)
{
if( val < 0.0031308f )
val *= 12.92f;
else
val = 1.055f * pow(val,1.0f/2.4f) - 0.055f;
return val;
}
D3DX11INLINE FLOAT D3DX_SaturateSigned_FLOAT(FLOAT _V)
{
if (D3DX_IsNan(_V))
{
return 0;
}
return min(max(_V, -1), 1);
}
D3DX11INLINE UINT D3DX_FLOAT_to_UINT(FLOAT _V,
FLOAT _Scale)
{
return (UINT)floor(_V * _Scale + 0.5f);
}
D3DX11INLINE FLOAT D3DX_INT_to_FLOAT(INT _V,
FLOAT _Scale)
{
FLOAT Scaled = (FLOAT)_V / _Scale;
// The integer is a two's-complement signed
// number so the negative range is slightly
// larger than the positive range, meaning
// the scaled value can be slight less than -1.
// Clamp to keep the float range [-1, 1].
return max(Scaled, -1.0f);
}
D3DX11INLINE INT D3DX_FLOAT_to_INT(FLOAT _V,
FLOAT _Scale)
{
return (INT)D3DX_Truncate_FLOAT(_V * _Scale + (_V >= 0 ? 0.5f : -0.5f));
}
//=============================================================================
// Conversion routines
//=============================================================================
//-----------------------------------------------------------------------------
// R10B10G10A2_UNORM <-> FLOAT4
//-----------------------------------------------------------------------------
D3DX11INLINE XMFLOAT4 D3DX_R10G10B10A2_UNORM_to_FLOAT4(UINT packedInput)
{
hlsl_precise XMFLOAT4 unpackedOutput;
unpackedOutput.x = (FLOAT) (packedInput & 0x000003ff) / 1023;
unpackedOutput.y = (FLOAT)(((packedInput>>10) & 0x000003ff)) / 1023;
unpackedOutput.z = (FLOAT)(((packedInput>>20) & 0x000003ff)) / 1023;
unpackedOutput.w = (FLOAT)(((packedInput>>30) & 0x00000003)) / 3;
return unpackedOutput;
}
D3DX11INLINE UINT D3DX_FLOAT4_to_R10G10B10A2_UNORM(hlsl_precise XMFLOAT4 unpackedInput)
{
UINT packedOutput;
packedOutput = ( (D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.x), 1023)) |
(D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.y), 1023)<<10) |
(D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.z), 1023)<<20) |
(D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.w), 3)<<30) );
return packedOutput;
}
//-----------------------------------------------------------------------------
// R10B10G10A2_UINT <-> UINT4
//-----------------------------------------------------------------------------
D3DX11INLINE XMUINT4 D3DX_R10G10B10A2_UINT_to_UINT4(UINT packedInput)
{
XMUINT4 unpackedOutput;
unpackedOutput.x = packedInput & 0x000003ff;
unpackedOutput.y = (packedInput>>10) & 0x000003ff;
unpackedOutput.z = (packedInput>>20) & 0x000003ff;
unpackedOutput.w = (packedInput>>30) & 0x00000003;
return unpackedOutput;
}
D3DX11INLINE UINT D3DX_UINT4_to_R10G10B10A2_UINT(XMUINT4 unpackedInput)
{
UINT packedOutput;
unpackedInput.x = min(unpackedInput.x, 0x000003ff);
unpackedInput.y = min(unpackedInput.y, 0x000003ff);
unpackedInput.z = min(unpackedInput.z, 0x000003ff);
unpackedInput.w = min(unpackedInput.w, 0x00000003);
packedOutput = ( (unpackedInput.x) |
((unpackedInput.y)<<10) |
((unpackedInput.z)<<20) |
((unpackedInput.w)<<30) );
return packedOutput;
}
//-----------------------------------------------------------------------------
// R8G8B8A8_UNORM <-> FLOAT4
//-----------------------------------------------------------------------------
D3DX11INLINE XMFLOAT4 D3DX_R8G8B8A8_UNORM_to_FLOAT4(UINT packedInput)
{
hlsl_precise XMFLOAT4 unpackedOutput;
unpackedOutput.x = (FLOAT) (packedInput & 0x000000ff) / 255;
unpackedOutput.y = (FLOAT)(((packedInput>> 8) & 0x000000ff)) / 255;
unpackedOutput.z = (FLOAT)(((packedInput>>16) & 0x000000ff)) / 255;
unpackedOutput.w = (FLOAT) (packedInput>>24) / 255;
return unpackedOutput;
}
D3DX11INLINE UINT D3DX_FLOAT4_to_R8G8B8A8_UNORM(hlsl_precise XMFLOAT4 unpackedInput)
{
UINT packedOutput;
packedOutput = ( (D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.x), 255)) |
(D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.y), 255)<< 8) |
(D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.z), 255)<<16) |
(D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.w), 255)<<24) );
return packedOutput;
}
//-----------------------------------------------------------------------------
// R8G8B8A8_UNORM_SRGB <-> FLOAT4
//-----------------------------------------------------------------------------
D3DX11INLINE XMFLOAT4 D3DX_R8G8B8A8_UNORM_SRGB_to_FLOAT4_inexact(UINT packedInput)
{
hlsl_precise XMFLOAT4 unpackedOutput;
unpackedOutput.x = D3DX_SRGB_to_FLOAT_inexact(((FLOAT) (packedInput & 0x000000ff) )/255);
unpackedOutput.y = D3DX_SRGB_to_FLOAT_inexact(((FLOAT)(((packedInput>> 8) & 0x000000ff)))/255);
unpackedOutput.z = D3DX_SRGB_to_FLOAT_inexact(((FLOAT)(((packedInput>>16) & 0x000000ff)))/255);
unpackedOutput.w = (FLOAT)(packedInput>>24) / 255;
return unpackedOutput;
}
D3DX11INLINE XMFLOAT4 D3DX_R8G8B8A8_UNORM_SRGB_to_FLOAT4(UINT packedInput)
{
hlsl_precise XMFLOAT4 unpackedOutput;
unpackedOutput.x = D3DX_SRGB_to_FLOAT( (packedInput & 0x000000ff) );
unpackedOutput.y = D3DX_SRGB_to_FLOAT((((packedInput>> 8) & 0x000000ff)));
unpackedOutput.z = D3DX_SRGB_to_FLOAT((((packedInput>>16) & 0x000000ff)));
unpackedOutput.w = (FLOAT)(packedInput>>24) / 255;
return unpackedOutput;
}
D3DX11INLINE UINT D3DX_FLOAT4_to_R8G8B8A8_UNORM_SRGB(hlsl_precise XMFLOAT4 unpackedInput)
{
UINT packedOutput;
unpackedInput.x = D3DX_FLOAT_to_SRGB(D3DX_Saturate_FLOAT(unpackedInput.x));
unpackedInput.y = D3DX_FLOAT_to_SRGB(D3DX_Saturate_FLOAT(unpackedInput.y));
unpackedInput.z = D3DX_FLOAT_to_SRGB(D3DX_Saturate_FLOAT(unpackedInput.z));
unpackedInput.w = D3DX_Saturate_FLOAT(unpackedInput.w);
packedOutput = ( (D3DX_FLOAT_to_UINT(unpackedInput.x, 255)) |
(D3DX_FLOAT_to_UINT(unpackedInput.y, 255)<< 8) |
(D3DX_FLOAT_to_UINT(unpackedInput.z, 255)<<16) |
(D3DX_FLOAT_to_UINT(unpackedInput.w, 255)<<24) );
return packedOutput;
}
//-----------------------------------------------------------------------------
// R8G8B8A8_UINT <-> UINT4
//-----------------------------------------------------------------------------
D3DX11INLINE XMUINT4 D3DX_R8G8B8A8_UINT_to_UINT4(UINT packedInput)
{
XMUINT4 unpackedOutput;
unpackedOutput.x = packedInput & 0x000000ff;
unpackedOutput.y = (packedInput>> 8) & 0x000000ff;
unpackedOutput.z = (packedInput>>16) & 0x000000ff;
unpackedOutput.w = packedInput>>24;
return unpackedOutput;
}
D3DX11INLINE UINT D3DX_UINT4_to_R8G8B8A8_UINT(XMUINT4 unpackedInput)
{
UINT packedOutput;
unpackedInput.x = min(unpackedInput.x, 0x000000ff);
unpackedInput.y = min(unpackedInput.y, 0x000000ff);
unpackedInput.z = min(unpackedInput.z, 0x000000ff);
unpackedInput.w = min(unpackedInput.w, 0x000000ff);
packedOutput = ( unpackedInput.x |
(unpackedInput.y<< 8) |
(unpackedInput.z<<16) |
(unpackedInput.w<<24) );
return packedOutput;
}
//-----------------------------------------------------------------------------
// R8G8B8A8_SNORM <-> FLOAT4
//-----------------------------------------------------------------------------
D3DX11INLINE XMFLOAT4 D3DX_R8G8B8A8_SNORM_to_FLOAT4(UINT packedInput)
{
hlsl_precise XMFLOAT4 unpackedOutput;
XMINT4 signExtendedBits;
signExtendedBits.x = (INT)(packedInput << 24) >> 24;
signExtendedBits.y = (INT)((packedInput << 16) & 0xff000000) >> 24;
signExtendedBits.z = (INT)((packedInput << 8) & 0xff000000) >> 24;
signExtendedBits.w = (INT)(packedInput & 0xff000000) >> 24;
unpackedOutput.x = D3DX_INT_to_FLOAT(signExtendedBits.x, 127);
unpackedOutput.y = D3DX_INT_to_FLOAT(signExtendedBits.y, 127);
unpackedOutput.z = D3DX_INT_to_FLOAT(signExtendedBits.z, 127);
unpackedOutput.w = D3DX_INT_to_FLOAT(signExtendedBits.w, 127);
return unpackedOutput;
}
D3DX11INLINE UINT D3DX_FLOAT4_to_R8G8B8A8_SNORM(hlsl_precise XMFLOAT4 unpackedInput)
{
UINT packedOutput;
packedOutput = ( (D3DX_FLOAT_to_INT(D3DX_SaturateSigned_FLOAT(unpackedInput.x), 127) & 0x000000ff) |
((D3DX_FLOAT_to_INT(D3DX_SaturateSigned_FLOAT(unpackedInput.y), 127) & 0x000000ff)<< 8) |
((D3DX_FLOAT_to_INT(D3DX_SaturateSigned_FLOAT(unpackedInput.z), 127) & 0x000000ff)<<16) |
((D3DX_FLOAT_to_INT(D3DX_SaturateSigned_FLOAT(unpackedInput.w), 127)) <<24) );
return packedOutput;
}
//-----------------------------------------------------------------------------
// R8G8B8A8_SINT <-> INT4
//-----------------------------------------------------------------------------
D3DX11INLINE XMINT4 D3DX_R8G8B8A8_SINT_to_INT4(UINT packedInput)
{
XMINT4 unpackedOutput;
unpackedOutput.x = (INT)(packedInput << 24) >> 24;
unpackedOutput.y = (INT)((packedInput << 16) & 0xff000000) >> 24;
unpackedOutput.z = (INT)((packedInput << 8) & 0xff000000) >> 24;
unpackedOutput.w = (INT)(packedInput & 0xff000000) >> 24;
return unpackedOutput;
}
D3DX11INLINE UINT D3DX_INT4_to_R8G8B8A8_SINT(XMINT4 unpackedInput)
{
UINT packedOutput;
unpackedInput.x = max(min(unpackedInput.x,127),-128);
unpackedInput.y = max(min(unpackedInput.y,127),-128);
unpackedInput.z = max(min(unpackedInput.z,127),-128);
unpackedInput.w = max(min(unpackedInput.w,127),-128);
packedOutput = ( (unpackedInput.x & 0x000000ff) |
((unpackedInput.y & 0x000000ff)<< 8) |
((unpackedInput.z & 0x000000ff)<<16) |
(unpackedInput.w <<24) );
return packedOutput;
}
//-----------------------------------------------------------------------------
// B8G8R8A8_UNORM <-> FLOAT4
//-----------------------------------------------------------------------------
D3DX11INLINE XMFLOAT4 D3DX_B8G8R8A8_UNORM_to_FLOAT4(UINT packedInput)
{
hlsl_precise XMFLOAT4 unpackedOutput;
unpackedOutput.z = (FLOAT) (packedInput & 0x000000ff) / 255;
unpackedOutput.y = (FLOAT)(((packedInput>> 8) & 0x000000ff)) / 255;
unpackedOutput.x = (FLOAT)(((packedInput>>16) & 0x000000ff)) / 255;
unpackedOutput.w = (FLOAT) (packedInput>>24) / 255;
return unpackedOutput;
}
D3DX11INLINE UINT D3DX_FLOAT4_to_B8G8R8A8_UNORM(hlsl_precise XMFLOAT4 unpackedInput)
{
UINT packedOutput;
packedOutput = ( (D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.z), 255)) |
(D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.y), 255)<< 8) |
(D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.x), 255)<<16) |
(D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.w), 255)<<24) );
return packedOutput;
}
//-----------------------------------------------------------------------------
// B8G8R8A8_UNORM_SRGB <-> FLOAT4
//-----------------------------------------------------------------------------
D3DX11INLINE XMFLOAT4 D3DX_B8G8R8A8_UNORM_SRGB_to_FLOAT4_inexact(UINT packedInput)
{
hlsl_precise XMFLOAT4 unpackedOutput;
unpackedOutput.z = D3DX_SRGB_to_FLOAT_inexact(((FLOAT) (packedInput & 0x000000ff) )/255);
unpackedOutput.y = D3DX_SRGB_to_FLOAT_inexact(((FLOAT)(((packedInput>> 8) & 0x000000ff)))/255);
unpackedOutput.x = D3DX_SRGB_to_FLOAT_inexact(((FLOAT)(((packedInput>>16) & 0x000000ff)))/255);
unpackedOutput.w = (FLOAT)(packedInput>>24) / 255;
return unpackedOutput;
}
D3DX11INLINE XMFLOAT4 D3DX_B8G8R8A8_UNORM_SRGB_to_FLOAT4(UINT packedInput)
{
hlsl_precise XMFLOAT4 unpackedOutput;
unpackedOutput.z = D3DX_SRGB_to_FLOAT( (packedInput & 0x000000ff) );
unpackedOutput.y = D3DX_SRGB_to_FLOAT((((packedInput>> 8) & 0x000000ff)));
unpackedOutput.x = D3DX_SRGB_to_FLOAT((((packedInput>>16) & 0x000000ff)));
unpackedOutput.w = (FLOAT)(packedInput>>24) / 255;
return unpackedOutput;
}
D3DX11INLINE UINT D3DX_FLOAT4_to_B8G8R8A8_UNORM_SRGB(hlsl_precise XMFLOAT4 unpackedInput)
{
UINT packedOutput;
unpackedInput.z = D3DX_FLOAT_to_SRGB(D3DX_Saturate_FLOAT(unpackedInput.z));
unpackedInput.y = D3DX_FLOAT_to_SRGB(D3DX_Saturate_FLOAT(unpackedInput.y));
unpackedInput.x = D3DX_FLOAT_to_SRGB(D3DX_Saturate_FLOAT(unpackedInput.x));
unpackedInput.w = D3DX_Saturate_FLOAT(unpackedInput.w);
packedOutput = ( (D3DX_FLOAT_to_UINT(unpackedInput.z, 255)) |
(D3DX_FLOAT_to_UINT(unpackedInput.y, 255)<< 8) |
(D3DX_FLOAT_to_UINT(unpackedInput.x, 255)<<16) |
(D3DX_FLOAT_to_UINT(unpackedInput.w, 255)<<24) );
return packedOutput;
}
//-----------------------------------------------------------------------------
// B8G8R8X8_UNORM <-> FLOAT3
//-----------------------------------------------------------------------------
D3DX11INLINE XMFLOAT3 D3DX_B8G8R8X8_UNORM_to_FLOAT3(UINT packedInput)
{
hlsl_precise XMFLOAT3 unpackedOutput;
unpackedOutput.z = (FLOAT) (packedInput & 0x000000ff) / 255;
unpackedOutput.y = (FLOAT)(((packedInput>> 8) & 0x000000ff)) / 255;
unpackedOutput.x = (FLOAT)(((packedInput>>16) & 0x000000ff)) / 255;
return unpackedOutput;
}
D3DX11INLINE UINT D3DX_FLOAT3_to_B8G8R8X8_UNORM(hlsl_precise XMFLOAT3 unpackedInput)
{
UINT packedOutput;
packedOutput = ( (D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.z), 255)) |
(D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.y), 255)<< 8) |
(D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.x), 255)<<16) );
return packedOutput;
}
//-----------------------------------------------------------------------------
// B8G8R8X8_UNORM_SRGB <-> FLOAT3
//-----------------------------------------------------------------------------
D3DX11INLINE XMFLOAT3 D3DX_B8G8R8X8_UNORM_SRGB_to_FLOAT3_inexact(UINT packedInput)
{
hlsl_precise XMFLOAT3 unpackedOutput;
unpackedOutput.z = D3DX_SRGB_to_FLOAT_inexact(((FLOAT) (packedInput & 0x000000ff) )/255);
unpackedOutput.y = D3DX_SRGB_to_FLOAT_inexact(((FLOAT)(((packedInput>> 8) & 0x000000ff)))/255);
unpackedOutput.x = D3DX_SRGB_to_FLOAT_inexact(((FLOAT)(((packedInput>>16) & 0x000000ff)))/255);
return unpackedOutput;
}
D3DX11INLINE XMFLOAT3 D3DX_B8G8R8X8_UNORM_SRGB_to_FLOAT3(UINT packedInput)
{
hlsl_precise XMFLOAT3 unpackedOutput;
unpackedOutput.z = D3DX_SRGB_to_FLOAT( (packedInput & 0x000000ff) );
unpackedOutput.y = D3DX_SRGB_to_FLOAT((((packedInput>> 8) & 0x000000ff)));
unpackedOutput.x = D3DX_SRGB_to_FLOAT((((packedInput>>16) & 0x000000ff)));
return unpackedOutput;
}
D3DX11INLINE UINT D3DX_FLOAT3_to_B8G8R8X8_UNORM_SRGB(hlsl_precise XMFLOAT3 unpackedInput)
{
UINT packedOutput;
unpackedInput.z = D3DX_FLOAT_to_SRGB(D3DX_Saturate_FLOAT(unpackedInput.z));
unpackedInput.y = D3DX_FLOAT_to_SRGB(D3DX_Saturate_FLOAT(unpackedInput.y));
unpackedInput.x = D3DX_FLOAT_to_SRGB(D3DX_Saturate_FLOAT(unpackedInput.x));
packedOutput = ( (D3DX_FLOAT_to_UINT(unpackedInput.z, 255)) |
(D3DX_FLOAT_to_UINT(unpackedInput.y, 255)<< 8) |
(D3DX_FLOAT_to_UINT(unpackedInput.x, 255)<<16) );
return packedOutput;
}
//-----------------------------------------------------------------------------
// R16G16_FLOAT <-> FLOAT2
//-----------------------------------------------------------------------------
#if HLSL_VERSION > 0
D3DX11INLINE XMFLOAT2 D3DX_R16G16_FLOAT_to_FLOAT2(UINT packedInput)
{
hlsl_precise XMFLOAT2 unpackedOutput;
unpackedOutput.x = f16tof32(packedInput&0x0000ffff);
unpackedOutput.y = f16tof32(packedInput>>16);
return unpackedOutput;
}
D3DX11INLINE UINT D3DX_FLOAT2_to_R16G16_FLOAT(hlsl_precise XMFLOAT2 unpackedInput)
{
UINT packedOutput;
packedOutput = asuint(f32tof16(unpackedInput.x)) |
(asuint(f32tof16(unpackedInput.y)) << 16);
return packedOutput;
}
#endif // HLSL_VERSION > 0
//-----------------------------------------------------------------------------
// R16G16_UNORM <-> FLOAT2
//-----------------------------------------------------------------------------
D3DX11INLINE XMFLOAT2 D3DX_R16G16_UNORM_to_FLOAT2(UINT packedInput)
{
hlsl_precise XMFLOAT2 unpackedOutput;
unpackedOutput.x = (FLOAT) (packedInput & 0x0000ffff) / 65535;
unpackedOutput.y = (FLOAT) (packedInput>>16) / 65535;
return unpackedOutput;
}
D3DX11INLINE UINT D3DX_FLOAT2_to_R16G16_UNORM(hlsl_precise XMFLOAT2 unpackedInput)
{
UINT packedOutput;
packedOutput = ( (D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.x), 65535)) |
(D3DX_FLOAT_to_UINT(D3DX_Saturate_FLOAT(unpackedInput.y), 65535)<< 16) );
return packedOutput;
}
//-----------------------------------------------------------------------------
// R16G16_UINT <-> UINT2
//-----------------------------------------------------------------------------
D3DX11INLINE XMUINT2 D3DX_R16G16_UINT_to_UINT2(UINT packedInput)
{
XMUINT2 unpackedOutput;
unpackedOutput.x = packedInput & 0x0000ffff;
unpackedOutput.y = packedInput>>16;
return unpackedOutput;
}
D3DX11INLINE UINT D3DX_UINT2_to_R16G16_UINT(XMUINT2 unpackedInput)
{
UINT packedOutput;
unpackedInput.x = min(unpackedInput.x,0x0000ffff);
unpackedInput.y = min(unpackedInput.y,0x0000ffff);
packedOutput = ( unpackedInput.x |
(unpackedInput.y<<16) );
return packedOutput;
}
//-----------------------------------------------------------------------------
// R16G16_SNORM <-> FLOAT2
//-----------------------------------------------------------------------------
D3DX11INLINE XMFLOAT2 D3DX_R16G16_SNORM_to_FLOAT2(UINT packedInput)
{
hlsl_precise XMFLOAT2 unpackedOutput;
XMINT2 signExtendedBits;
signExtendedBits.x = (INT)(packedInput << 16) >> 16;
signExtendedBits.y = (INT)(packedInput & 0xffff0000) >> 16;
unpackedOutput.x = D3DX_INT_to_FLOAT(signExtendedBits.x, 32767);
unpackedOutput.y = D3DX_INT_to_FLOAT(signExtendedBits.y, 32767);
return unpackedOutput;
}
D3DX11INLINE UINT D3DX_FLOAT2_to_R16G16_SNORM(hlsl_precise XMFLOAT2 unpackedInput)
{
UINT packedOutput;
packedOutput = ( (D3DX_FLOAT_to_INT(D3DX_SaturateSigned_FLOAT(unpackedInput.x), 32767) & 0x0000ffff) |
(D3DX_FLOAT_to_INT(D3DX_SaturateSigned_FLOAT(unpackedInput.y), 32767) <<16) );
return packedOutput;
}
//-----------------------------------------------------------------------------
// R16G16_SINT <-> INT2
//-----------------------------------------------------------------------------
D3DX11INLINE XMINT2 D3DX_R16G16_SINT_to_INT2(UINT packedInput)
{
XMINT2 unpackedOutput;
unpackedOutput.x = (INT)(packedInput << 16) >> 16;
unpackedOutput.y = (INT)(packedInput & 0xffff0000) >> 16;
return unpackedOutput;
}
D3DX11INLINE UINT D3DX_INT2_to_R16G16_SINT(XMINT2 unpackedInput)
{
UINT packedOutput;
unpackedInput.x = max(min(unpackedInput.x,32767),-32768);
unpackedInput.y = max(min(unpackedInput.y,32767),-32768);
packedOutput = ( (unpackedInput.x & 0x0000ffff) |
(unpackedInput.y <<16) );
return packedOutput;
}
#endif // __D3DX_DXGI_FORMAT_CONVERT_INL___