Unify BGRA masks
A few formats require flipping the R and B channels of the channels
mask. This CL centralizes that logic in a single spot.
Bug: b/204322086
Change-Id: I6eef8ba0c831f595ebffa94dfef9a65b64d52101
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/69948
Commit-Queue: Alexis Hétu <sugoi@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Pipeline/Constants.cpp b/src/Pipeline/Constants.cpp
index 0570609..dda1f39 100644
--- a/src/Pipeline/Constants.cpp
+++ b/src/Pipeline/Constants.cpp
@@ -235,19 +235,17 @@
for(int i = 0; i < 8; i++)
{
- mask565Q[i] = word4((i & 0x1 ? 0xF800 : 0) | (i & 0x2 ? 0x07E0 : 0) | (i & 0x4 ? 0x001F : 0));
+ mask565Q[i] = word4((i & 0x1 ? 0x001F : 0) | (i & 0x2 ? 0x07E0 : 0) | (i & 0x4 ? 0xF800 : 0));
mask11X[i] = dword4((i & 0x1 ? 0x000007FFu : 0) | (i & 0x2 ? 0x003FF800u : 0) | (i & 0x4 ? 0xFFC00000u : 0));
}
for(int i = 0; i < 16; i++)
{
- mask5551Q[i] = word4((i & 0x1 ? 0x7C00 : 0) | (i & 0x2 ? 0x03E0 : 0) | (i & 0x4 ? 0x001F : 0) | (i & 8 ? 0x8000 : 0));
+ mask5551Q[i] = word4((i & 0x1 ? 0x001F : 0) | (i & 0x2 ? 0x03E0 : 0) | (i & 0x4 ? 0x7C00 : 0) | (i & 8 ? 0x8000 : 0));
maskr5g5b5a1Q[i] = word4((i & 0x1 ? 0xF800 : 0) | (i & 0x2 ? 0x07C0 : 0) | (i & 0x4 ? 0x003E : 0) | (i & 8 ? 0x0001 : 0));
maskb5g5r5a1Q[i] = word4((i & 0x1 ? 0x003E : 0) | (i & 0x2 ? 0x07C0 : 0) | (i & 0x4 ? 0xF800 : 0) | (i & 8 ? 0x0001 : 0));
- mask4rgbaQ[i] = word4((i & 0x1 ? 0xF000 : 0) | (i & 0x2 ? 0x0F00 : 0) | (i & 0x4 ? 0x00F0 : 0) | (i & 8 ? 0x000F : 0));
- mask4bgraQ[i] = word4((i & 0x1 ? 0x00F0 : 0) | (i & 0x2 ? 0x0F00 : 0) | (i & 0x4 ? 0xF000 : 0) | (i & 8 ? 0x000F : 0));
- mask4abgrQ[i] = word4((i & 0x1 ? 0x000F : 0) | (i & 0x2 ? 0x00F0 : 0) | (i & 0x4 ? 0x0F00 : 0) | (i & 8 ? 0xF000 : 0));
- mask4argbQ[i] = word4((i & 0x1 ? 0x0F00 : 0) | (i & 0x2 ? 0x00F0 : 0) | (i & 0x4 ? 0x000F : 0) | (i & 8 ? 0xF000 : 0));
+ mask4argbQ[i] = word4((i & 0x1 ? 0x00F0 : 0) | (i & 0x2 ? 0x0F00 : 0) | (i & 0x4 ? 0xF000 : 0) | (i & 8 ? 0x000F : 0));
+ mask4rgbaQ[i] = word4((i & 0x1 ? 0x000F : 0) | (i & 0x2 ? 0x00F0 : 0) | (i & 0x4 ? 0x0F00 : 0) | (i & 8 ? 0xF000 : 0));
}
for(int i = 0; i < 4; i++)
diff --git a/src/Pipeline/Constants.hpp b/src/Pipeline/Constants.hpp
index a939a7c..a857747 100644
--- a/src/Pipeline/Constants.hpp
+++ b/src/Pipeline/Constants.hpp
@@ -103,8 +103,6 @@
word4 maskr5g5b5a1Q[16]; // 4 bit writemask -> R5G5B5A1 bit patterns, replicated 4x
word4 maskb5g5r5a1Q[16]; // 4 bit writemask -> B5G5R5A1 bit patterns, replicated 4x
word4 mask4rgbaQ[16]; // 4 bit writemask -> R4G4B4A4 bit patterns, replicated 4x
- word4 mask4bgraQ[16]; // 4 bit writemask -> B4G4R4A4 bit patterns, replicated 4x
- word4 mask4abgrQ[16]; // 4 bit writemask -> A4B4G4R4 bit patterns, replicated 4x
word4 mask4argbQ[16]; // 4 bit writemask -> A4R4G4B4 bit patterns, replicated 4x
dword4 mask11X[8]; // 3 bit writemask -> B10G11R11 bit patterns, replicated 4x
diff --git a/src/Pipeline/PixelRoutine.cpp b/src/Pipeline/PixelRoutine.cpp
index 600d65e..1d46605 100644
--- a/src/Pipeline/PixelRoutine.cpp
+++ b/src/Pipeline/PixelRoutine.cpp
@@ -889,7 +889,8 @@
Int pitchB = *Pointer<Int>(data + OFFSET(DrawData, colorPitchB[index]));
- switch(state.colorFormat[index])
+ vk::Format format = state.colorFormat[index];
+ switch(format)
{
case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
buffer += 2 * x;
@@ -1169,7 +1170,7 @@
}
break;
default:
- UNSUPPORTED("VkFormat %d", int(state.colorFormat[index]));
+ UNSUPPORTED("VkFormat %d", int(format));
}
if(isSRGB(index))
@@ -1185,7 +1186,8 @@
linearToSRGB16_12_16(current);
}
- switch(state.colorFormat[index])
+ vk::Format format = state.colorFormat[index];
+ switch(format)
{
case VK_FORMAT_B8G8R8A8_UNORM:
case VK_FORMAT_B8G8R8A8_SRGB:
@@ -1235,8 +1237,13 @@
}
int writeMask = state.colorWriteActive(index);
+ if(format.isBGRformat())
+ {
+ // For BGR formats, flip R and B channels in the channels mask
+ writeMask = (writeMask & 0x0000000A) | (writeMask & 0x00000001) << 2 | (writeMask & 0x00000004) >> 2;
+ }
- switch(state.colorFormat[index])
+ switch(format)
{
case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
{
@@ -1438,7 +1445,7 @@
}
break;
default:
- UNSUPPORTED("VkFormat: %d", int(state.colorFormat[index]));
+ UNSUPPORTED("VkFormat: %d", int(format));
}
Short4 c01 = current.z;
@@ -1463,7 +1470,7 @@
Pointer<Byte> buffer = cBuffer;
Int pitchB = *Pointer<Int>(data + OFFSET(DrawData, colorPitchB[index]));
- switch(state.colorFormat[index])
+ switch(format)
{
case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
case VK_FORMAT_B4G4R4A4_UNORM_PACK16:
@@ -1474,22 +1481,18 @@
Int value = *Pointer<Int>(buffer);
Int channelMask;
- switch(state.colorFormat[index])
+ switch(format)
{
case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
- channelMask = *Pointer<Int>(constants + OFFSET(Constants, mask4rgbaQ[writeMask][0]));
- break;
case VK_FORMAT_B4G4R4A4_UNORM_PACK16:
- channelMask = *Pointer<Int>(constants + OFFSET(Constants, mask4bgraQ[writeMask][0]));
- break;
- case VK_FORMAT_A4R4G4B4_UNORM_PACK16:
channelMask = *Pointer<Int>(constants + OFFSET(Constants, mask4argbQ[writeMask][0]));
break;
+ case VK_FORMAT_A4R4G4B4_UNORM_PACK16:
case VK_FORMAT_A4B4G4R4_UNORM_PACK16:
- channelMask = *Pointer<Int>(constants + OFFSET(Constants, mask4abgrQ[writeMask][0]));
+ channelMask = *Pointer<Int>(constants + OFFSET(Constants, mask4rgbaQ[writeMask][0]));
break;
default:
- UNREACHABLE("Format: %s", vk::Stringify(state.colorFormat[index]).c_str());
+ UNREACHABLE("Format: %s", vk::Stringify(format).c_str());
}
Int c01 = Extract(As<Int2>(current.x), 0);
@@ -1623,8 +1626,6 @@
case VK_FORMAT_B8G8R8A8_UNORM:
case VK_FORMAT_B8G8R8A8_SRGB:
{
- writeMask = (writeMask & 0x0000000A) | (writeMask & 0x00000001) << 2 | (writeMask & 0x00000004) >> 2;
-
buffer += x * 4;
Short4 value = *Pointer<Short4>(buffer);
Short4 channelMask = *Pointer<Short4>(constants + OFFSET(Constants, maskB4Q[writeMask]));
@@ -1715,8 +1716,6 @@
}
break;
case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
- writeMask = (writeMask & 0x0000000A) | (writeMask & 0x00000001) << 2 | (writeMask & 0x00000004) >> 2;
- // [[fallthrough]]
case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
{
buffer += 4 * x;
@@ -1741,7 +1740,7 @@
}
break;
default:
- UNSUPPORTED("VkFormat: %d", int(state.colorFormat[index]));
+ UNSUPPORTED("VkFormat: %d", int(format));
}
}
@@ -2674,6 +2673,11 @@
}
int writeMask = state.colorWriteActive(index);
+ if(format.isBGRformat())
+ {
+ // For BGR formats, flip R and B channels in the channels mask
+ writeMask = (writeMask & 0x0000000A) | (writeMask & 0x00000001) << 2 | (writeMask & 0x00000004) >> 2;
+ }
Int xMask; // Combination of all masks
@@ -3135,8 +3139,6 @@
break;
case VK_FORMAT_B8G8R8A8_UNORM:
case VK_FORMAT_B8G8R8A8_SRGB:
- writeMask = (writeMask & 0x0000000A) | (writeMask & 0x00000001) << 2 | (writeMask & 0x00000004) >> 2;
- // [[fallthrough]]
case VK_FORMAT_R8G8B8A8_SINT:
case VK_FORMAT_R8G8B8A8_UINT:
case VK_FORMAT_A8B8G8R8_UINT_PACK32:
@@ -3258,38 +3260,38 @@
Int channelMask;
Short4 current;
- switch(state.colorFormat[index])
+ switch(format)
{
case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
- channelMask = *Pointer<Int>(constants + OFFSET(Constants, mask4rgbaQ[writeMask][0]));
+ channelMask = *Pointer<Int>(constants + OFFSET(Constants, mask4argbQ[writeMask][0]));
current = (UShort4(As<Int4>(color.x)) & UShort4(0xF)) << 12 |
(UShort4(As<Int4>(color.y)) & UShort4(0xF)) << 8 |
(UShort4(As<Int4>(color.z)) & UShort4(0xF)) << 4 |
(UShort4(As<Int4>(color.w)) & UShort4(0xF));
break;
case VK_FORMAT_B4G4R4A4_UNORM_PACK16:
- channelMask = *Pointer<Int>(constants + OFFSET(Constants, mask4bgraQ[writeMask][0]));
+ channelMask = *Pointer<Int>(constants + OFFSET(Constants, mask4argbQ[writeMask][0]));
current = (UShort4(As<Int4>(color.z)) & UShort4(0xF)) << 12 |
(UShort4(As<Int4>(color.y)) & UShort4(0xF)) << 8 |
(UShort4(As<Int4>(color.x)) & UShort4(0xF)) << 4 |
(UShort4(As<Int4>(color.w)) & UShort4(0xF));
break;
case VK_FORMAT_A4R4G4B4_UNORM_PACK16:
- channelMask = *Pointer<Int>(constants + OFFSET(Constants, mask4argbQ[writeMask][0]));
+ channelMask = *Pointer<Int>(constants + OFFSET(Constants, mask4rgbaQ[writeMask][0]));
current = (UShort4(As<Int4>(color.w)) & UShort4(0xF)) << 12 |
(UShort4(As<Int4>(color.x)) & UShort4(0xF)) << 8 |
(UShort4(As<Int4>(color.y)) & UShort4(0xF)) << 4 |
(UShort4(As<Int4>(color.z)) & UShort4(0xF));
break;
case VK_FORMAT_A4B4G4R4_UNORM_PACK16:
- channelMask = *Pointer<Int>(constants + OFFSET(Constants, mask4abgrQ[writeMask][0]));
+ channelMask = *Pointer<Int>(constants + OFFSET(Constants, mask4rgbaQ[writeMask][0]));
current = (UShort4(As<Int4>(color.w)) & UShort4(0xF)) << 12 |
(UShort4(As<Int4>(color.z)) & UShort4(0xF)) << 8 |
(UShort4(As<Int4>(color.y)) & UShort4(0xF)) << 4 |
(UShort4(As<Int4>(color.x)) & UShort4(0xF));
break;
default:
- UNREACHABLE("Format: %s", vk::Stringify(state.colorFormat[index]).c_str());
+ UNREACHABLE("Format: %s", vk::Stringify(format).c_str());
}
Int c01 = Extract(As<Int2>(current), 0);
@@ -3437,8 +3439,6 @@
break;
case VK_FORMAT_B5G6R5_UNORM_PACK16:
{
- writeMask = (writeMask & 0x0000000A) | (writeMask & 0x00000001) << 2 | (writeMask & 0x00000004) >> 2;
-
buffer += 2 * x;
Int value = *Pointer<Int>(buffer);
diff --git a/src/Vulkan/VkFormat.cpp b/src/Vulkan/VkFormat.cpp
index cdf40ac..61a1667 100644
--- a/src/Vulkan/VkFormat.cpp
+++ b/src/Vulkan/VkFormat.cpp
@@ -353,6 +353,40 @@
}
}
+bool Format::isBGRformat() const
+{
+ switch(format)
+ {
+ case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
+ case VK_FORMAT_A4R4G4B4_UNORM_PACK16:
+ case VK_FORMAT_R5G6B5_UNORM_PACK16:
+ case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
+ case VK_FORMAT_B8G8R8_UNORM:
+ case VK_FORMAT_B8G8R8_SNORM:
+ case VK_FORMAT_B8G8R8_USCALED:
+ case VK_FORMAT_B8G8R8_SSCALED:
+ case VK_FORMAT_B8G8R8_UINT:
+ case VK_FORMAT_B8G8R8_SINT:
+ case VK_FORMAT_B8G8R8_SRGB:
+ case VK_FORMAT_B8G8R8A8_UNORM:
+ case VK_FORMAT_B8G8R8A8_SNORM:
+ case VK_FORMAT_B8G8R8A8_USCALED:
+ case VK_FORMAT_B8G8R8A8_SSCALED:
+ case VK_FORMAT_B8G8R8A8_UINT:
+ case VK_FORMAT_B8G8R8A8_SINT:
+ case VK_FORMAT_B8G8R8A8_SRGB:
+ case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
+ case VK_FORMAT_A2R10G10B10_SNORM_PACK32:
+ case VK_FORMAT_A2R10G10B10_USCALED_PACK32:
+ case VK_FORMAT_A2R10G10B10_SSCALED_PACK32:
+ case VK_FORMAT_A2R10G10B10_UINT_PACK32:
+ case VK_FORMAT_A2R10G10B10_SINT_PACK32:
+ return true;
+ default:
+ return false;
+ }
+}
+
bool Format::isSRGBformat() const
{
switch(format)
diff --git a/src/Vulkan/VkFormat.hpp b/src/Vulkan/VkFormat.hpp
index 3cff4a0..994e112 100644
--- a/src/Vulkan/VkFormat.hpp
+++ b/src/Vulkan/VkFormat.hpp
@@ -43,6 +43,7 @@
VkFormat getClearFormat() const;
bool isStencil() const;
bool isDepth() const;
+ bool isBGRformat() const;
bool isSRGBformat() const;
bool isFloatFormat() const;
bool isYcbcrFormat() const;