Fix for true integer blit to lower bit depth image
Blitting from a higher bit depth source to a lower bit depth
destination was not working properly because Vulkan expects
clamping, while the blitter was truncating the values.
From section 19.5. Image Copies with Scaling:
"Signed and unsigned integers are converted by first
clamping to the representable range of the destination
format, then casting the value."
This fixes all remaining failures in:
dEQP-VK.api.copy_and_blit.core.blit_image.all_formats.color.*
Bug b/119620767
Change-Id: Ibd1c1e4be4f5107e7d423781b46021f4c5df1070
Reviewed-on: https://swiftshader-review.googlesource.com/c/23368
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Chris Forbes <chrisforbes@google.com>
diff --git a/src/Device/Blitter.cpp b/src/Device/Blitter.cpp
index 5819ca4..dcc5d4e 100644
--- a/src/Device/Blitter.cpp
+++ b/src/Device/Blitter.cpp
@@ -771,6 +771,37 @@
switch(state.destFormat)
{
+ case VK_FORMAT_A2B10G10R10_UINT_PACK32:
+ c = Min(As<UInt4>(c), UInt4(0x03FF, 0x03FF, 0x03FF, 0x0003));
+ break;
+ case VK_FORMAT_A8B8G8R8_UINT_PACK32:
+ case VK_FORMAT_R8G8B8A8_UINT:
+ case VK_FORMAT_R8G8_UINT:
+ case VK_FORMAT_R8_UINT:
+ c = Min(As<UInt4>(c), UInt4(0xFF));
+ break;
+ case VK_FORMAT_R16G16B16A16_UINT:
+ case VK_FORMAT_R16G16_UINT:
+ case VK_FORMAT_R16_UINT:
+ c = Min(As<UInt4>(c), UInt4(0xFFFF));
+ break;
+ case VK_FORMAT_A8B8G8R8_SINT_PACK32:
+ case VK_FORMAT_R8G8B8A8_SINT:
+ case VK_FORMAT_R8G8_SINT:
+ case VK_FORMAT_R8_SINT:
+ c = Min(Max(c, Int4(-0x80)), Int4(0x7F));
+ break;
+ case VK_FORMAT_R16G16B16A16_SINT:
+ case VK_FORMAT_R16G16_SINT:
+ case VK_FORMAT_R16_SINT:
+ c = Min(Max(c, Int4(-0x8000)), Int4(0x7FFF));
+ break;
+ default:
+ break;
+ }
+
+ switch(state.destFormat)
+ {
case VK_FORMAT_A8B8G8R8_SINT_PACK32:
case VK_FORMAT_R8G8B8A8_SINT:
if(writeA) { *Pointer<SByte>(element + 3) = SByte(Extract(c, 3)); }