added -x2bias switch for texconv

This commit is contained in:
Chuck Walbourn 2016-09-30 00:16:56 -07:00
parent 9ea3ed1b4a
commit a7b3393d4d
4 changed files with 142 additions and 53 deletions

View File

@ -411,6 +411,9 @@ namespace DirectX
TEX_FILTER_SEPARATE_ALPHA = 0x100, TEX_FILTER_SEPARATE_ALPHA = 0x100,
// Resize color and alpha channel independently // Resize color and alpha channel independently
TEX_FILTER_FLOAT_X2BIAS = 0x200,
// Enable *2 - 1 conversion cases for unorm<->float and positive-only float formats
TEX_FILTER_RGB_COPY_RED = 0x1000, TEX_FILTER_RGB_COPY_RED = 0x1000,
TEX_FILTER_RGB_COPY_GREEN = 0x2000, TEX_FILTER_RGB_COPY_GREEN = 0x2000,
TEX_FILTER_RGB_COPY_BLUE = 0x4000, TEX_FILTER_RGB_COPY_BLUE = 0x4000,

View File

@ -2815,7 +2815,7 @@ namespace
{ DXGI_FORMAT_D32_FLOAT_S8X24_UINT, 32, CONVF_FLOAT | CONVF_DEPTH | CONVF_STENCIL }, { DXGI_FORMAT_D32_FLOAT_S8X24_UINT, 32, CONVF_FLOAT | CONVF_DEPTH | CONVF_STENCIL },
{ DXGI_FORMAT_R10G10B10A2_UNORM, 10, CONVF_UNORM | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_R10G10B10A2_UNORM, 10, CONVF_UNORM | CONVF_R | CONVF_G | CONVF_B | CONVF_A },
{ DXGI_FORMAT_R10G10B10A2_UINT, 10, CONVF_UINT | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_R10G10B10A2_UINT, 10, CONVF_UINT | CONVF_R | CONVF_G | CONVF_B | CONVF_A },
{ DXGI_FORMAT_R11G11B10_FLOAT, 10, CONVF_FLOAT | CONVF_R | CONVF_G | CONVF_B }, { DXGI_FORMAT_R11G11B10_FLOAT, 10, CONVF_FLOAT | CONVF_POS_ONLY | CONVF_R | CONVF_G | CONVF_B },
{ DXGI_FORMAT_R8G8B8A8_UNORM, 8, CONVF_UNORM | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_R8G8B8A8_UNORM, 8, CONVF_UNORM | CONVF_R | CONVF_G | CONVF_B | CONVF_A },
{ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, 8, CONVF_UNORM | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, 8, CONVF_UNORM | CONVF_R | CONVF_G | CONVF_B | CONVF_A },
{ DXGI_FORMAT_R8G8B8A8_UINT, 8, CONVF_UINT | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_R8G8B8A8_UINT, 8, CONVF_UINT | CONVF_R | CONVF_G | CONVF_B | CONVF_A },
@ -2847,7 +2847,7 @@ namespace
{ DXGI_FORMAT_R8_SINT, 8, CONVF_SINT | CONVF_R }, { DXGI_FORMAT_R8_SINT, 8, CONVF_SINT | CONVF_R },
{ DXGI_FORMAT_A8_UNORM, 8, CONVF_UNORM | CONVF_A }, { DXGI_FORMAT_A8_UNORM, 8, CONVF_UNORM | CONVF_A },
{ DXGI_FORMAT_R1_UNORM, 1, CONVF_UNORM | CONVF_R }, { DXGI_FORMAT_R1_UNORM, 1, CONVF_UNORM | CONVF_R },
{ DXGI_FORMAT_R9G9B9E5_SHAREDEXP, 9, CONVF_SHAREDEXP | CONVF_R | CONVF_G | CONVF_B }, { DXGI_FORMAT_R9G9B9E5_SHAREDEXP, 9, CONVF_FLOAT | CONVF_SHAREDEXP | CONVF_POS_ONLY | CONVF_R | CONVF_G | CONVF_B },
{ DXGI_FORMAT_R8G8_B8G8_UNORM, 8, CONVF_UNORM | CONVF_PACKED | CONVF_R | CONVF_G | CONVF_B }, { DXGI_FORMAT_R8G8_B8G8_UNORM, 8, CONVF_UNORM | CONVF_PACKED | CONVF_R | CONVF_G | CONVF_B },
{ DXGI_FORMAT_G8R8_G8B8_UNORM, 8, CONVF_UNORM | CONVF_PACKED | CONVF_R | CONVF_G | CONVF_B }, { DXGI_FORMAT_G8R8_G8B8_UNORM, 8, CONVF_UNORM | CONVF_PACKED | CONVF_R | CONVF_G | CONVF_B },
{ DXGI_FORMAT_BC1_UNORM, 8, CONVF_UNORM | CONVF_BC | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_BC1_UNORM, 8, CONVF_UNORM | CONVF_BC | CONVF_R | CONVF_G | CONVF_B | CONVF_A },
@ -2878,8 +2878,8 @@ namespace
{ DXGI_FORMAT_Y210, 10, CONVF_UNORM | CONVF_YUV | CONVF_PACKED | CONVF_R | CONVF_G | CONVF_B }, { DXGI_FORMAT_Y210, 10, CONVF_UNORM | CONVF_YUV | CONVF_PACKED | CONVF_R | CONVF_G | CONVF_B },
{ DXGI_FORMAT_Y216, 16, CONVF_UNORM | CONVF_YUV | CONVF_PACKED | CONVF_R | CONVF_G | CONVF_B }, { DXGI_FORMAT_Y216, 16, CONVF_UNORM | CONVF_YUV | CONVF_PACKED | CONVF_R | CONVF_G | CONVF_B },
{ DXGI_FORMAT_B4G4R4A4_UNORM, 4, CONVF_UNORM | CONVF_BGR | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { DXGI_FORMAT_B4G4R4A4_UNORM, 4, CONVF_UNORM | CONVF_BGR | CONVF_R | CONVF_G | CONVF_B | CONVF_A },
{ XBOX_DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT, 10, CONVF_FLOAT | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { XBOX_DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT, 10, CONVF_FLOAT | CONVF_POS_ONLY | CONVF_R | CONVF_G | CONVF_B | CONVF_A },
{ XBOX_DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT, 10, CONVF_FLOAT | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { XBOX_DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT, 10, CONVF_FLOAT | CONVF_POS_ONLY | CONVF_R | CONVF_G | CONVF_B | CONVF_A },
{ XBOX_DXGI_FORMAT_R10G10B10_SNORM_A2_UNORM,10, CONVF_SNORM | CONVF_R | CONVF_G | CONVF_B | CONVF_A }, { XBOX_DXGI_FORMAT_R10G10B10_SNORM_A2_UNORM,10, CONVF_SNORM | CONVF_R | CONVF_G | CONVF_B | CONVF_A },
{ XBOX_DXGI_FORMAT_R4G4_UNORM, 4, CONVF_UNORM | CONVF_R | CONVF_G }, { XBOX_DXGI_FORMAT_R4G4_UNORM, 4, CONVF_UNORM | CONVF_R | CONVF_G },
}; };
@ -2916,7 +2916,12 @@ DWORD DirectX::_GetConvertFlags(DXGI_FORMAT format)
} }
_Use_decl_annotations_ _Use_decl_annotations_
void DirectX::_ConvertScanline(XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outFormat, DXGI_FORMAT inFormat, DWORD flags) void DirectX::_ConvertScanline(
XMVECTOR* pBuffer,
size_t count,
DXGI_FORMAT outFormat,
DXGI_FORMAT inFormat,
DWORD flags)
{ {
assert(pBuffer && count > 0 && (((uintptr_t)pBuffer & 0xF) == 0)); assert(pBuffer && count > 0 && (((uintptr_t)pBuffer & 0xF) == 0));
assert(IsValid(outFormat) && !IsTypeless(outFormat) && !IsPlanar(outFormat) && !IsPalettized(outFormat)); assert(IsValid(outFormat) && !IsTypeless(outFormat) && !IsPlanar(outFormat) && !IsPalettized(outFormat));
@ -3011,10 +3016,9 @@ void DirectX::_ConvertScanline(XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outF
DWORD diffFlags = in->flags ^ out->flags; DWORD diffFlags = in->flags ^ out->flags;
if (diffFlags != 0) if (diffFlags != 0)
{ {
static const XMVECTORF32 s_two = { 2.0f, 2.0f, 2.0f, 2.0f };
if (diffFlags & CONVF_DEPTH) if (diffFlags & CONVF_DEPTH)
{ {
//--- Depth conversions ---
if (in->flags & CONVF_DEPTH) if (in->flags & CONVF_DEPTH)
{ {
// CONVF_DEPTH -> !CONVF_DEPTH // CONVF_DEPTH -> !CONVF_DEPTH
@ -3033,8 +3037,7 @@ void DirectX::_ConvertScanline(XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outF
XMVECTOR v1 = XMVectorSplatY(v); XMVECTOR v1 = XMVectorSplatY(v);
v1 = XMVectorClamp(v1, g_XMZero, S); v1 = XMVectorClamp(v1, g_XMZero, S);
v1 = XMVectorDivide(v1, S); v1 = XMVectorDivide(v1, S);
v = XMVectorSelect(v1, v, g_XMSelect1110); *ptr++ = XMVectorSelect(v1, v, g_XMSelect1110);
*ptr++ = v;
} }
} }
else if (out->flags & CONVF_SNORM) else if (out->flags & CONVF_SNORM)
@ -3047,9 +3050,8 @@ void DirectX::_ConvertScanline(XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outF
XMVECTOR v1 = XMVectorSplatY(v); XMVECTOR v1 = XMVectorSplatY(v);
v1 = XMVectorClamp(v1, g_XMZero, S); v1 = XMVectorClamp(v1, g_XMZero, S);
v1 = XMVectorDivide(v1, S); v1 = XMVectorDivide(v1, S);
v1 = XMVectorMultiplyAdd(v1, s_two, g_XMNegativeOne); v1 = XMVectorMultiplyAdd(v1, g_XMTwo, g_XMNegativeOne);
v = XMVectorSelect(v1, v, g_XMSelect1110); *ptr++ = XMVectorSelect(v1, v, g_XMSelect1110);
*ptr++ = v;
} }
} }
else else
@ -3059,8 +3061,7 @@ void DirectX::_ConvertScanline(XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outF
{ {
XMVECTOR v = *ptr; XMVECTOR v = *ptr;
XMVECTOR v1 = XMVectorSplatY(v); XMVECTOR v1 = XMVectorSplatY(v);
v = XMVectorSelect(v1, v, g_XMSelect1110); *ptr++ = XMVectorSelect(v1, v, g_XMSelect1110);
*ptr++ = v;
} }
} }
} }
@ -3075,8 +3076,7 @@ void DirectX::_ConvertScanline(XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outF
XMVECTOR v = *ptr; XMVECTOR v = *ptr;
XMVECTOR v1 = XMVectorSaturate(v); XMVECTOR v1 = XMVectorSaturate(v);
v1 = XMVectorSplatX(v1); v1 = XMVectorSplatX(v1);
v = XMVectorSelect(v, v1, g_XMSelect1110); *ptr++ = XMVectorSelect(v, v1, g_XMSelect1110);
*ptr++ = v;
} }
} }
else if (out->flags & CONVF_SNORM) else if (out->flags & CONVF_SNORM)
@ -3088,10 +3088,9 @@ void DirectX::_ConvertScanline(XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outF
for (size_t i = 0; i < count; ++i) for (size_t i = 0; i < count; ++i)
{ {
XMVECTOR v = *ptr; XMVECTOR v = *ptr;
XMVECTOR v1 = XMVectorMultiplyAdd(v, s_two, g_XMNegativeOne); XMVECTOR v1 = XMVectorMultiplyAdd(v, g_XMTwo, g_XMNegativeOne);
v1 = XMVectorSplatX(v1); v1 = XMVectorSplatX(v1);
v = XMVectorSelect(v, v1, g_XMSelect1110); *ptr++ = XMVectorSelect(v, v1, g_XMSelect1110);
*ptr++ = v;
} }
} }
else else
@ -3103,8 +3102,7 @@ void DirectX::_ConvertScanline(XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outF
XMVECTOR v = *ptr; XMVECTOR v = *ptr;
XMVECTOR v1 = XMVectorClamp(v, g_XMNegativeOne, g_XMOne); XMVECTOR v1 = XMVectorClamp(v, g_XMNegativeOne, g_XMOne);
v1 = XMVectorSplatX(v1); v1 = XMVectorSplatX(v1);
v = XMVectorSelect(v, v1, g_XMSelect1110); *ptr++ = XMVectorSelect(v, v1, g_XMSelect1110);
*ptr++ = v;
} }
} }
} }
@ -3115,8 +3113,7 @@ void DirectX::_ConvertScanline(XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outF
{ {
XMVECTOR v = *ptr; XMVECTOR v = *ptr;
XMVECTOR v1 = XMVectorSplatX(v); XMVECTOR v1 = XMVectorSplatX(v);
v = XMVectorSelect(v, v1, g_XMSelect1110); *ptr++ = XMVectorSelect(v, v1, g_XMSelect1110);
*ptr++ = v;
} }
} }
} }
@ -3134,8 +3131,7 @@ void DirectX::_ConvertScanline(XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outF
{ {
XMVECTOR v = *ptr; XMVECTOR v = *ptr;
XMVECTOR v1 = XMVectorSplatY(v); XMVECTOR v1 = XMVectorSplatY(v);
v = XMVectorSelect(v, v1, g_XMSelect1000); *ptr++ = XMVectorSelect(v, v1, g_XMSelect1000);
*ptr++ = v;
} }
} }
break; break;
@ -3147,8 +3143,7 @@ void DirectX::_ConvertScanline(XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outF
{ {
XMVECTOR v = *ptr; XMVECTOR v = *ptr;
XMVECTOR v1 = XMVectorSplatZ(v); XMVECTOR v1 = XMVectorSplatZ(v);
v = XMVectorSelect(v, v1, g_XMSelect1000); *ptr++ = XMVectorSelect(v, v1, g_XMSelect1000);
*ptr++ = v;
} }
} }
break; break;
@ -3161,8 +3156,7 @@ void DirectX::_ConvertScanline(XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outF
{ {
XMVECTOR v = *ptr; XMVECTOR v = *ptr;
XMVECTOR v1 = XMVector3Dot(v, g_Grayscale); XMVECTOR v1 = XMVector3Dot(v, g_Grayscale);
v = XMVectorSelect(v, v1, g_XMSelect1000); *ptr++ = XMVectorSelect(v, v1, g_XMSelect1000);
*ptr++ = v;
} }
break; break;
} }
@ -3176,8 +3170,7 @@ void DirectX::_ConvertScanline(XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outF
{ {
XMVECTOR v = *ptr; XMVECTOR v = *ptr;
XMVECTOR v1 = XMVectorSplatX(v); XMVECTOR v1 = XMVectorSplatX(v);
v = XMVectorSelect(v, v1, g_XMSelect1000); *ptr++ = XMVectorSelect(v, v1, g_XMSelect1000);
*ptr++ = v;
} }
} }
break; break;
@ -3194,8 +3187,7 @@ void DirectX::_ConvertScanline(XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outF
{ {
XMVECTOR v = *ptr; XMVECTOR v = *ptr;
XMVECTOR v1 = XMVectorMultiplyAdd(v, g_XMOneHalf, g_XMOneHalf); XMVECTOR v1 = XMVectorMultiplyAdd(v, g_XMOneHalf, g_XMOneHalf);
v = XMVectorSelect(v, v1, g_XMSelect1000); *ptr++ = XMVectorSelect(v, v1, g_XMSelect1000);
*ptr++ = v;
} }
} }
else if (in->flags & CONVF_FLOAT) else if (in->flags & CONVF_FLOAT)
@ -3206,8 +3198,7 @@ void DirectX::_ConvertScanline(XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outF
{ {
XMVECTOR v = *ptr; XMVECTOR v = *ptr;
XMVECTOR v1 = XMVectorSaturate(v); XMVECTOR v1 = XMVectorSaturate(v);
v = XMVectorSelect(v, v1, g_XMSelect1000); *ptr++ = XMVectorSelect(v, v1, g_XMSelect1000);
*ptr++ = v;
} }
} }
} }
@ -3227,8 +3218,7 @@ void DirectX::_ConvertScanline(XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outF
XMVECTOR v = *ptr; XMVECTOR v = *ptr;
XMVECTOR v1 = XMVectorMultiply(v, S); XMVECTOR v1 = XMVectorMultiply(v, S);
v1 = XMVectorSplatW(v1); v1 = XMVectorSplatW(v1);
v = XMVectorSelect(v, v1, select0100); *ptr++ = XMVectorSelect(v, v1, select0100);
*ptr++ = v;
} }
} }
else if (in->flags & CONVF_SNORM) else if (in->flags & CONVF_SNORM)
@ -3241,8 +3231,7 @@ void DirectX::_ConvertScanline(XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outF
XMVECTOR v1 = XMVectorMultiplyAdd(v, g_XMOneHalf, g_XMOneHalf); XMVECTOR v1 = XMVectorMultiplyAdd(v, g_XMOneHalf, g_XMOneHalf);
v1 = XMVectorMultiply(v1, S); v1 = XMVectorMultiply(v1, S);
v1 = XMVectorSplatW(v1); v1 = XMVectorSplatW(v1);
v = XMVectorSelect(v, v1, select0100); *ptr++ = XMVectorSelect(v, v1, select0100);
*ptr++ = v;
} }
} }
else else
@ -3252,8 +3241,7 @@ void DirectX::_ConvertScanline(XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outF
{ {
XMVECTOR v = *ptr; XMVECTOR v = *ptr;
XMVECTOR v1 = XMVectorSplatW(v); XMVECTOR v1 = XMVectorSplatW(v);
v = XMVectorSelect(v, v1, select0100); *ptr++ = XMVectorSelect(v, v1, select0100);
*ptr++ = v;
} }
} }
} }
@ -3272,14 +3260,14 @@ void DirectX::_ConvertScanline(XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outF
{ {
XMVECTOR v = *ptr; XMVECTOR v = *ptr;
XMVECTOR v1 = XMVectorSaturate(v); XMVECTOR v1 = XMVectorSaturate(v);
v = XMVectorSelect(v, v1, g_XMSelect1000); *ptr++ = XMVectorSelect(v, v1, g_XMSelect1000);
*ptr++ = v;
} }
} }
} }
} }
else if (out->flags & CONVF_UNORM) else if (out->flags & CONVF_UNORM)
{ {
//--- Converting to a UNORM ---
if (in->flags & CONVF_SNORM) if (in->flags & CONVF_SNORM)
{ {
// SNORM -> UNORM // SNORM -> UNORM
@ -3292,17 +3280,31 @@ void DirectX::_ConvertScanline(XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outF
} }
else if (in->flags & CONVF_FLOAT) else if (in->flags & CONVF_FLOAT)
{ {
// FLOAT -> UNORM
XMVECTOR* ptr = pBuffer; XMVECTOR* ptr = pBuffer;
for (size_t i = 0; i < count; ++i) if (!(in->flags & CONVF_POS_ONLY) && (flags & TEX_FILTER_FLOAT_X2BIAS))
{ {
XMVECTOR v = *ptr; // FLOAT -> UNORM (x2 bias)
*ptr++ = XMVectorSaturate(v); for (size_t i = 0; i < count; ++i)
{
XMVECTOR v = *ptr;
v = XMVectorClamp(v, g_XMNegativeOne, g_XMOne);
*ptr++ = XMVectorMultiplyAdd(v, g_XMOneHalf, g_XMOneHalf);
}
}
else
{
// FLOAT -> UNORM
for (size_t i = 0; i < count; ++i)
{
XMVECTOR v = *ptr;
*ptr++ = XMVectorSaturate(v);
}
} }
} }
} }
else if (out->flags & CONVF_SNORM) else if (out->flags & CONVF_SNORM)
{ {
//--- Converting to a SNORM ---
if (in->flags & CONVF_UNORM) if (in->flags & CONVF_UNORM)
{ {
// UNORM -> SNORM // UNORM -> SNORM
@ -3310,17 +3312,92 @@ void DirectX::_ConvertScanline(XMVECTOR* pBuffer, size_t count, DXGI_FORMAT outF
for (size_t i = 0; i < count; ++i) for (size_t i = 0; i < count; ++i)
{ {
XMVECTOR v = *ptr; XMVECTOR v = *ptr;
*ptr++ = XMVectorMultiplyAdd(v, s_two, g_XMNegativeOne); *ptr++ = XMVectorMultiplyAdd(v, g_XMTwo, g_XMNegativeOne);
} }
} }
else if (in->flags & CONVF_FLOAT) else if (in->flags & CONVF_FLOAT)
{ {
// FLOAT -> SNORM
XMVECTOR* ptr = pBuffer; XMVECTOR* ptr = pBuffer;
for (size_t i = 0; i < count; ++i) if ((in->flags & CONVF_POS_ONLY) && (flags & TEX_FILTER_FLOAT_X2BIAS))
{ {
XMVECTOR v = *ptr; // FLOAT (positive only, x2 bias) -> SNORM
*ptr++ = XMVectorClamp(v, g_XMNegativeOne, g_XMOne); for (size_t i = 0; i < count; ++i)
{
XMVECTOR v = *ptr;
v = XMVectorSaturate(v);
*ptr++ = XMVectorMultiplyAdd(v, g_XMTwo, g_XMNegativeOne);
}
}
else
{
// FLOAT -> SNORM
for (size_t i = 0; i < count; ++i)
{
XMVECTOR v = *ptr;
*ptr++ = XMVectorClamp(v, g_XMNegativeOne, g_XMOne);
}
}
}
}
else if (diffFlags & CONVF_UNORM)
{
//--- Converting from a UNORM ---
assert(in->flags & CONVF_UNORM);
if (out->flags & CONVF_FLOAT)
{
if (!(out->flags & CONVF_POS_ONLY) && (flags & TEX_FILTER_FLOAT_X2BIAS))
{
// UNORM (x2 bias) -> FLOAT
XMVECTOR* ptr = pBuffer;
for (size_t i = 0; i < count; ++i)
{
XMVECTOR v = *ptr;
*ptr++ = XMVectorMultiplyAdd(v, g_XMTwo, g_XMNegativeOne);
}
}
}
}
else if (diffFlags & CONVF_POS_ONLY)
{
if (flags & TEX_FILTER_FLOAT_X2BIAS)
{
if (in->flags & CONVF_POS_ONLY)
{
if (out->flags & CONVF_FLOAT)
{
// FLOAT (positive only, x2 bias) -> FLOAT
XMVECTOR* ptr = pBuffer;
for (size_t i = 0; i < count; ++i)
{
XMVECTOR v = *ptr;
v = XMVectorSaturate(v);
*ptr++ = XMVectorMultiplyAdd(v, g_XMTwo, g_XMNegativeOne);
}
}
}
else if (out->flags & CONVF_POS_ONLY)
{
if (in->flags & CONVF_FLOAT)
{
// FLOAT -> FLOAT (positive only, x2 bias)
XMVECTOR* ptr = pBuffer;
for (size_t i = 0; i < count; ++i)
{
XMVECTOR v = *ptr;
v = XMVectorClamp(v, g_XMNegativeOne, g_XMOne);
*ptr++ = XMVectorMultiplyAdd(v, g_XMOneHalf, g_XMOneHalf);
}
}
else if (in->flags & CONVF_SNORM)
{
// SNORM -> FLOAT (positive only, x2 bias)
XMVECTOR* ptr = pBuffer;
for (size_t i = 0; i < count; ++i)
{
XMVECTOR v = *ptr;
*ptr++ = XMVectorMultiplyAdd(v, g_XMOneHalf, g_XMOneHalf);
}
}
} }
} }
} }

View File

@ -163,6 +163,7 @@ namespace DirectX
CONVF_PACKED = 0x400, CONVF_PACKED = 0x400,
CONVF_BC = 0x800, CONVF_BC = 0x800,
CONVF_YUV = 0x1000, CONVF_YUV = 0x1000,
CONVF_POS_ONLY = 0x2000,
CONVF_R = 0x10000, CONVF_R = 0x10000,
CONVF_G = 0x20000, CONVF_G = 0x20000,
CONVF_B = 0x40000, CONVF_B = 0x40000,

View File

@ -88,6 +88,7 @@ enum OPTIONS
OPT_WIC_LOSSLESS, OPT_WIC_LOSSLESS,
OPT_COLORKEY, OPT_COLORKEY,
OPT_TONEMAP, OPT_TONEMAP,
OPT_X2_BIAS,
OPT_MAX OPT_MAX
}; };
@ -157,6 +158,7 @@ const SValue g_pOptions[] =
{ L"wiclossless", OPT_WIC_LOSSLESS }, { L"wiclossless", OPT_WIC_LOSSLESS },
{ L"c", OPT_COLORKEY }, { L"c", OPT_COLORKEY },
{ L"tonemap", OPT_TONEMAP }, { L"tonemap", OPT_TONEMAP },
{ L"x2bias", OPT_X2_BIAS },
{ nullptr, 0 } { nullptr, 0 }
}; };
@ -676,6 +678,7 @@ namespace
L" (defaults to 1.0)\n"); L" (defaults to 1.0)\n");
wprintf(L" -c <hex-RGB> colorkey (a.k.a. chromakey) transparency\n"); wprintf(L" -c <hex-RGB> colorkey (a.k.a. chromakey) transparency\n");
wprintf(L" -tonemap Apply a tonemap operator based on maximum luminance\n"); wprintf(L" -tonemap Apply a tonemap operator based on maximum luminance\n");
wprintf(L" -x2bias Enable *2 - 1 conversion cases for unorm/pos-only-float\n");
wprintf(L"\n <format>: "); wprintf(L"\n <format>: ");
PrintList(13, g_pFormats); PrintList(13, g_pFormats);
@ -861,6 +864,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN;
DWORD dwFilter = TEX_FILTER_DEFAULT; DWORD dwFilter = TEX_FILTER_DEFAULT;
DWORD dwSRGB = 0; DWORD dwSRGB = 0;
DWORD dwConvert = 0;
DWORD dwCompress = TEX_COMPRESS_DEFAULT; DWORD dwCompress = TEX_COMPRESS_DEFAULT;
DWORD dwFilterOpts = 0; DWORD dwFilterOpts = 0;
DWORD FileType = CODEC_DDS; DWORD FileType = CODEC_DDS;
@ -1259,6 +1263,10 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
colorKey &= 0xFFFFFF; colorKey &= 0xFFFFFF;
useColorKey = true; useColorKey = true;
break; break;
case OPT_X2_BIAS:
dwConvert |= TEX_FILTER_FLOAT_X2BIAS;
break;
} }
} }
else if (wcspbrk(pArg, L"?*") != nullptr) else if (wcspbrk(pArg, L"?*") != nullptr)
@ -1733,7 +1741,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
} }
hr = Convert(image->GetImages(), image->GetImageCount(), image->GetMetadata(), tformat, hr = Convert(image->GetImages(), image->GetImageCount(), image->GetMetadata(), tformat,
dwFilter | dwFilterOpts | dwSRGB, TEX_THRESHOLD_DEFAULT, *timage); dwFilter | dwFilterOpts | dwSRGB | dwConvert, TEX_THRESHOLD_DEFAULT, *timage);
if (FAILED(hr)) if (FAILED(hr))
{ {
wprintf(L" FAILED [convert] (%x)\n", hr); wprintf(L" FAILED [convert] (%x)\n", hr);