//============================================================================= // 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 #include #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___