Add TEX_FILTER_RGB_COPY_ALPHA for RGBA to R and RGBA to RG convert control (#349)

This commit is contained in:
Chuck Walbourn 2023-05-12 11:27:02 -07:00 коммит произвёл GitHub
Родитель e0a7be5a4b
Коммит f5d41447f8
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 100 добавлений и 28 удалений

Просмотреть файл

@ -575,8 +575,9 @@ namespace DirectX
TEX_FILTER_RGB_COPY_RED = 0x1000,
TEX_FILTER_RGB_COPY_GREEN = 0x2000,
TEX_FILTER_RGB_COPY_BLUE = 0x4000,
// When converting RGB to R, defaults to using grayscale. These flags indicate copying a specific channel instead
// When converting RGB to RG, defaults to copying RED | GREEN. These flags control which channels are selected instead.
TEX_FILTER_RGB_COPY_ALPHA = 0x8000,
// When converting RGB(A) to R, defaults to using grayscale. These flags indicate copying a specific channel instead
// When converting RGB(A) to RG, defaults to copying RED | GREEN. These flags control which channels are selected instead.
TEX_FILTER_DITHER = 0x10000,
// Use ordered 4x4 dithering for any required conversions

Просмотреть файл

@ -3280,8 +3280,8 @@ void DirectX::Internal::ConvertScanline(
{
// !CONVF_DEPTH -> CONVF_DEPTH
// RGB -> Depth (red channel)
switch (flags & (TEX_FILTER_RGB_COPY_RED | TEX_FILTER_RGB_COPY_GREEN | TEX_FILTER_RGB_COPY_BLUE))
// RGB -> Depth (red channel or other specified channel)
switch (flags & (TEX_FILTER_RGB_COPY_RED | TEX_FILTER_RGB_COPY_GREEN | TEX_FILTER_RGB_COPY_BLUE | TEX_FILTER_RGB_COPY_ALPHA))
{
case TEX_FILTER_RGB_COPY_GREEN:
{
@ -3307,6 +3307,18 @@ void DirectX::Internal::ConvertScanline(
}
break;
case TEX_FILTER_RGB_COPY_ALPHA:
{
XMVECTOR* ptr = pBuffer;
for (size_t i = 0; i < count; ++i)
{
const XMVECTOR v = *ptr;
const XMVECTOR v1 = XMVectorSplatW(v);
*ptr++ = XMVectorSelect(v, v1, g_XMSelect1000);
}
}
break;
default:
if ((in->flags & CONVF_UNORM) && ((in->flags & CONVF_RGB_MASK) == (CONVF_R | CONVF_G | CONVF_B)))
{
@ -3574,6 +3586,7 @@ void DirectX::Internal::ConvertScanline(
if (((out->flags & CONVF_RGBA_MASK) == CONVF_A) && !(in->flags & CONVF_A))
{
// !CONVF_A -> A format
// We ignore TEX_FILTER_RGB_COPY_ALPHA since there's no input alpha channel.
switch (flags & (TEX_FILTER_RGB_COPY_RED | TEX_FILTER_RGB_COPY_GREEN | TEX_FILTER_RGB_COPY_BLUE))
{
case TEX_FILTER_RGB_COPY_GREEN:
@ -3669,8 +3682,8 @@ void DirectX::Internal::ConvertScanline(
{
if ((out->flags & CONVF_RGB_MASK) == CONVF_R)
{
// RGB format -> R format
switch (flags & (TEX_FILTER_RGB_COPY_RED | TEX_FILTER_RGB_COPY_GREEN | TEX_FILTER_RGB_COPY_BLUE))
// RGB(A) format -> R format
switch (flags & (TEX_FILTER_RGB_COPY_RED | TEX_FILTER_RGB_COPY_GREEN | TEX_FILTER_RGB_COPY_BLUE | TEX_FILTER_RGB_COPY_ALPHA))
{
case TEX_FILTER_RGB_COPY_GREEN:
{
@ -3696,6 +3709,18 @@ void DirectX::Internal::ConvertScanline(
}
break;
case TEX_FILTER_RGB_COPY_ALPHA:
{
XMVECTOR* ptr = pBuffer;
for (size_t i = 0; i < count; ++i)
{
const XMVECTOR v = *ptr;
const XMVECTOR v1 = XMVectorSplatW(v);
*ptr++ = XMVectorSelect(v, v1, g_XMSelect1110);
}
}
break;
default:
if (in->flags & CONVF_UNORM)
{
@ -3724,37 +3749,83 @@ void DirectX::Internal::ConvertScanline(
}
else if ((out->flags & CONVF_RGB_MASK) == (CONVF_R | CONVF_G))
{
// RGB format -> RG format
switch (static_cast<int>(flags & (TEX_FILTER_RGB_COPY_RED | TEX_FILTER_RGB_COPY_GREEN | TEX_FILTER_RGB_COPY_BLUE)))
if ((flags & TEX_FILTER_RGB_COPY_ALPHA) && (in->flags & CONVF_A))
{
case (static_cast<int>(TEX_FILTER_RGB_COPY_RED) | static_cast<int>(TEX_FILTER_RGB_COPY_BLUE)):
// RGBA -> RG format
switch (static_cast<int>(flags & (TEX_FILTER_RGB_COPY_RED | TEX_FILTER_RGB_COPY_GREEN | TEX_FILTER_RGB_COPY_BLUE | TEX_FILTER_RGB_COPY_ALPHA)))
{
XMVECTOR* ptr = pBuffer;
for (size_t i = 0; i < count; ++i)
case (static_cast<int>(TEX_FILTER_RGB_COPY_RED) | static_cast<int>(TEX_FILTER_RGB_COPY_ALPHA)):
default:
{
const XMVECTOR v = *ptr;
const XMVECTOR v1 = XMVectorSwizzle<0, 2, 0, 2>(v);
*ptr++ = XMVectorSelect(v, v1, g_XMSelect1100);
XMVECTOR* ptr = pBuffer;
for (size_t i = 0; i < count; ++i)
{
const XMVECTOR v = *ptr;
const XMVECTOR v1 = XMVectorSwizzle<0, 3, 0, 3>(v);
*ptr++ = XMVectorSelect(v, v1, g_XMSelect1100);
}
}
}
break;
break;
case (static_cast<int>(TEX_FILTER_RGB_COPY_GREEN) | static_cast<int>(TEX_FILTER_RGB_COPY_BLUE)):
case (static_cast<int>(TEX_FILTER_RGB_COPY_GREEN) | static_cast<int>(TEX_FILTER_RGB_COPY_ALPHA)):
{
XMVECTOR* ptr = pBuffer;
for (size_t i = 0; i < count; ++i)
{
const XMVECTOR v = *ptr;
const XMVECTOR v1 = XMVectorSwizzle<1, 3, 1, 3>(v);
*ptr++ = XMVectorSelect(v, v1, g_XMSelect1100);
}
}
break;
case (static_cast<int>(TEX_FILTER_RGB_COPY_BLUE) | static_cast<int>(TEX_FILTER_RGB_COPY_ALPHA)):
{
XMVECTOR* ptr = pBuffer;
for (size_t i = 0; i < count; ++i)
{
const XMVECTOR v = *ptr;
const XMVECTOR v1 = XMVectorSwizzle<2, 3, 2, 3>(v);
*ptr++ = XMVectorSelect(v, v1, g_XMSelect1100);
}
}
break;
}
}
else
{
// RGB format -> RG format
switch (static_cast<int>(flags & (TEX_FILTER_RGB_COPY_RED | TEX_FILTER_RGB_COPY_GREEN | TEX_FILTER_RGB_COPY_BLUE)))
{
XMVECTOR* ptr = pBuffer;
for (size_t i = 0; i < count; ++i)
case (static_cast<int>(TEX_FILTER_RGB_COPY_RED) | static_cast<int>(TEX_FILTER_RGB_COPY_BLUE)):
{
const XMVECTOR v = *ptr;
const XMVECTOR v1 = XMVectorSwizzle<1, 2, 3, 0>(v);
*ptr++ = XMVectorSelect(v, v1, g_XMSelect1100);
XMVECTOR* ptr = pBuffer;
for (size_t i = 0; i < count; ++i)
{
const XMVECTOR v = *ptr;
const XMVECTOR v1 = XMVectorSwizzle<0, 2, 0, 2>(v);
*ptr++ = XMVectorSelect(v, v1, g_XMSelect1100);
}
}
}
break;
break;
case (static_cast<int>(TEX_FILTER_RGB_COPY_RED) | static_cast<int>(TEX_FILTER_RGB_COPY_GREEN)):
default:
// Leave data unchanged and the store will handle this...
break;
case (static_cast<int>(TEX_FILTER_RGB_COPY_GREEN) | static_cast<int>(TEX_FILTER_RGB_COPY_BLUE)):
{
XMVECTOR* ptr = pBuffer;
for (size_t i = 0; i < count; ++i)
{
const XMVECTOR v = *ptr;
const XMVECTOR v1 = XMVectorSwizzle<1, 2, 3, 0>(v);
*ptr++ = XMVectorSelect(v, v1, g_XMSelect1100);
}
}
break;
case (static_cast<int>(TEX_FILTER_RGB_COPY_RED) | static_cast<int>(TEX_FILTER_RGB_COPY_GREEN)):
default:
// Leave data unchanged and the store will handle this...
break;
}
}
}
}