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 committed by GitHub
parent e0a7be5a4b
commit f5d41447f8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 100 additions and 28 deletions

View File

@ -575,8 +575,9 @@ namespace DirectX
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,
// When converting RGB to R, defaults to using grayscale. These flags indicate copying a specific channel instead TEX_FILTER_RGB_COPY_ALPHA = 0x8000,
// When converting RGB to RG, defaults to copying RED | GREEN. These flags control which channels are selected instead. // 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, TEX_FILTER_DITHER = 0x10000,
// Use ordered 4x4 dithering for any required conversions // Use ordered 4x4 dithering for any required conversions

View File

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