Explorar o código

Ensure 16-bit -> 32-bit conversion is consistent between blitters

The SSE, LUT, and other blitters should have the same results for 16-bit -> 32-bit conversion
Sam Lantinga hai 1 día
pai
achega
dbd5dd8c75
Modificáronse 3 ficheiros con 229 adicións e 55 borrados
  1. 84 51
      src/video/SDL_blit_N.c
  2. 65 4
      src/video/SDL_pixels.c
  3. 80 0
      test/testautomation_surface.c

+ 84 - 51
src/video/SDL_blit_N.c

@@ -1336,14 +1336,47 @@ static void Blit_RGB565_32(SDL_BlitInfo *info, const Uint32 *mapR, const Uint32
 #endif // USE_DUFFS_LOOP
 }
 
-#if 0
 // This is the code used to generate the lookup tables below:
+#if 0
 #include <SDL3/SDL.h>
 #include <stdio.h>
 
-static Uint32 Calculate(int v, int vmax, int shift)
+#define GENERATE_SHIFTS
+
+static Uint32 Calculate(int v, int bits, int vmax, int shift)
 {
+#if defined(GENERATE_FLOOR)
+    return (Uint32)SDL_floor(v * 255.0f / vmax) << shift;
+#elif defined(GENERATE_ROUND)
     return (Uint32)SDL_roundf(v * 255.0f / vmax) << shift;
+#elif defined(GENERATE_SHIFTS)
+    switch (bits) {
+    case 1:
+        v = (v << 7) | (v << 6) | (v << 5) | (v << 4) | (v << 3) | (v << 2) | (v << 1) | v;
+        break;
+    case 2:
+        v = (v << 6) | (v << 4) | (v << 2) | v;
+        break;
+    case 3:
+        v = (v << 5) | (v << 2) | (v >> 1);
+        break;
+    case 4:
+        v = (v << 4) | v;
+        break;
+    case 5:
+        v = (v << 3) | (v >> 2);
+        break;
+    case 6:
+        v = (v << 2) | (v >> 4);
+        break;
+    case 7:
+        v = (v << 1) | (v >> 6);
+        break;
+    case 8:
+        break;
+    }
+    return (Uint32)v << shift;
+#endif
 }
 
 static void PrintLUT(const char *src, const char *dst, const char *channel, int bits, int shift)
@@ -1355,7 +1388,7 @@ static void PrintLUT(const char *src, const char *dst, const char *channel, int
         if ((v % 4) == 0) {
             printf("\n    ");
         }
-        printf("0x%.8x", Calculate(v, vmax, shift));
+        printf("0x%.8x", Calculate(v, bits, vmax, shift));
         if (v < vmax) {
             printf(",");
             if (((v + 1) % 4) != 0) {
@@ -1393,21 +1426,21 @@ int main(int argc, char *argv[])
 // Special optimized blit for RGB565 -> ARGB8888
 
 static const Uint32 RGB565_ARGB8888_LUT_R[32] = {
-    0x00000000, 0x00080000, 0x00100000, 0x00190000,
-    0x00210000, 0x00290000, 0x00310000, 0x003a0000,
+    0x00000000, 0x00080000, 0x00100000, 0x00180000,
+    0x00210000, 0x00290000, 0x00310000, 0x00390000,
     0x00420000, 0x004a0000, 0x00520000, 0x005a0000,
     0x00630000, 0x006b0000, 0x00730000, 0x007b0000,
     0x00840000, 0x008c0000, 0x00940000, 0x009c0000,
     0x00a50000, 0x00ad0000, 0x00b50000, 0x00bd0000,
-    0x00c50000, 0x00ce0000, 0x00d60000, 0x00de0000,
-    0x00e60000, 0x00ef0000, 0x00f70000, 0x00ff0000
+    0x00c60000, 0x00ce0000, 0x00d60000, 0x00de0000,
+    0x00e70000, 0x00ef0000, 0x00f70000, 0x00ff0000
 };
 
 static const Uint32 RGB565_ARGB8888_LUT_G[64] = {
     0x00000000, 0x00000400, 0x00000800, 0x00000c00,
     0x00001000, 0x00001400, 0x00001800, 0x00001c00,
-    0x00002000, 0x00002400, 0x00002800, 0x00002d00,
-    0x00003100, 0x00003500, 0x00003900, 0x00003d00,
+    0x00002000, 0x00002400, 0x00002800, 0x00002c00,
+    0x00003000, 0x00003400, 0x00003800, 0x00003c00,
     0x00004100, 0x00004500, 0x00004900, 0x00004d00,
     0x00005100, 0x00005500, 0x00005900, 0x00005d00,
     0x00006100, 0x00006500, 0x00006900, 0x00006d00,
@@ -1416,21 +1449,21 @@ static const Uint32 RGB565_ARGB8888_LUT_G[64] = {
     0x00009200, 0x00009600, 0x00009a00, 0x00009e00,
     0x0000a200, 0x0000a600, 0x0000aa00, 0x0000ae00,
     0x0000b200, 0x0000b600, 0x0000ba00, 0x0000be00,
-    0x0000c200, 0x0000c600, 0x0000ca00, 0x0000ce00,
-    0x0000d200, 0x0000d700, 0x0000db00, 0x0000df00,
+    0x0000c300, 0x0000c700, 0x0000cb00, 0x0000cf00,
+    0x0000d300, 0x0000d700, 0x0000db00, 0x0000df00,
     0x0000e300, 0x0000e700, 0x0000eb00, 0x0000ef00,
     0x0000f300, 0x0000f700, 0x0000fb00, 0x0000ff00
 };
 
 static const Uint32 RGB565_ARGB8888_LUT_B[32] = {
-    0x00000000, 0x00000008, 0x00000010, 0x00000019,
-    0x00000021, 0x00000029, 0x00000031, 0x0000003a,
+    0x00000000, 0x00000008, 0x00000010, 0x00000018,
+    0x00000021, 0x00000029, 0x00000031, 0x00000039,
     0x00000042, 0x0000004a, 0x00000052, 0x0000005a,
     0x00000063, 0x0000006b, 0x00000073, 0x0000007b,
     0x00000084, 0x0000008c, 0x00000094, 0x0000009c,
     0x000000a5, 0x000000ad, 0x000000b5, 0x000000bd,
-    0x000000c5, 0x000000ce, 0x000000d6, 0x000000de,
-    0x000000e6, 0x000000ef, 0x000000f7, 0x000000ff
+    0x000000c6, 0x000000ce, 0x000000d6, 0x000000de,
+    0x000000e7, 0x000000ef, 0x000000f7, 0x000000ff
 };
 
 static void Blit_RGB565_ARGB8888(SDL_BlitInfo * info)
@@ -1441,21 +1474,21 @@ static void Blit_RGB565_ARGB8888(SDL_BlitInfo * info)
 // Special optimized blit for RGB565 -> ABGR8888
 
 static const Uint32 RGB565_ABGR8888_LUT_R[32] = {
-    0x00000000, 0x00000008, 0x00000010, 0x00000019,
-    0x00000021, 0x00000029, 0x00000031, 0x0000003a,
+    0x00000000, 0x00000008, 0x00000010, 0x00000018,
+    0x00000021, 0x00000029, 0x00000031, 0x00000039,
     0x00000042, 0x0000004a, 0x00000052, 0x0000005a,
     0x00000063, 0x0000006b, 0x00000073, 0x0000007b,
     0x00000084, 0x0000008c, 0x00000094, 0x0000009c,
     0x000000a5, 0x000000ad, 0x000000b5, 0x000000bd,
-    0x000000c5, 0x000000ce, 0x000000d6, 0x000000de,
-    0x000000e6, 0x000000ef, 0x000000f7, 0x000000ff
+    0x000000c6, 0x000000ce, 0x000000d6, 0x000000de,
+    0x000000e7, 0x000000ef, 0x000000f7, 0x000000ff
 };
 
 static const Uint32 RGB565_ABGR8888_LUT_G[64] = {
     0x00000000, 0x00000400, 0x00000800, 0x00000c00,
     0x00001000, 0x00001400, 0x00001800, 0x00001c00,
-    0x00002000, 0x00002400, 0x00002800, 0x00002d00,
-    0x00003100, 0x00003500, 0x00003900, 0x00003d00,
+    0x00002000, 0x00002400, 0x00002800, 0x00002c00,
+    0x00003000, 0x00003400, 0x00003800, 0x00003c00,
     0x00004100, 0x00004500, 0x00004900, 0x00004d00,
     0x00005100, 0x00005500, 0x00005900, 0x00005d00,
     0x00006100, 0x00006500, 0x00006900, 0x00006d00,
@@ -1464,21 +1497,21 @@ static const Uint32 RGB565_ABGR8888_LUT_G[64] = {
     0x00009200, 0x00009600, 0x00009a00, 0x00009e00,
     0x0000a200, 0x0000a600, 0x0000aa00, 0x0000ae00,
     0x0000b200, 0x0000b600, 0x0000ba00, 0x0000be00,
-    0x0000c200, 0x0000c600, 0x0000ca00, 0x0000ce00,
-    0x0000d200, 0x0000d700, 0x0000db00, 0x0000df00,
+    0x0000c300, 0x0000c700, 0x0000cb00, 0x0000cf00,
+    0x0000d300, 0x0000d700, 0x0000db00, 0x0000df00,
     0x0000e300, 0x0000e700, 0x0000eb00, 0x0000ef00,
     0x0000f300, 0x0000f700, 0x0000fb00, 0x0000ff00
 };
 
 static const Uint32 RGB565_ABGR8888_LUT_B[32] = {
-    0x00000000, 0x00080000, 0x00100000, 0x00190000,
-    0x00210000, 0x00290000, 0x00310000, 0x003a0000,
+    0x00000000, 0x00080000, 0x00100000, 0x00180000,
+    0x00210000, 0x00290000, 0x00310000, 0x00390000,
     0x00420000, 0x004a0000, 0x00520000, 0x005a0000,
     0x00630000, 0x006b0000, 0x00730000, 0x007b0000,
     0x00840000, 0x008c0000, 0x00940000, 0x009c0000,
     0x00a50000, 0x00ad0000, 0x00b50000, 0x00bd0000,
-    0x00c50000, 0x00ce0000, 0x00d60000, 0x00de0000,
-    0x00e60000, 0x00ef0000, 0x00f70000, 0x00ff0000
+    0x00c60000, 0x00ce0000, 0x00d60000, 0x00de0000,
+    0x00e70000, 0x00ef0000, 0x00f70000, 0x00ff0000
 };
 
 static void Blit_RGB565_ABGR8888(SDL_BlitInfo * info)
@@ -1489,21 +1522,21 @@ static void Blit_RGB565_ABGR8888(SDL_BlitInfo * info)
 // Special optimized blit for RGB565 -> RGBA8888
 
 static const Uint32 RGB565_RGBA8888_LUT_R[32] = {
-    0x00000000, 0x08000000, 0x10000000, 0x19000000,
-    0x21000000, 0x29000000, 0x31000000, 0x3a000000,
+    0x00000000, 0x08000000, 0x10000000, 0x18000000,
+    0x21000000, 0x29000000, 0x31000000, 0x39000000,
     0x42000000, 0x4a000000, 0x52000000, 0x5a000000,
     0x63000000, 0x6b000000, 0x73000000, 0x7b000000,
     0x84000000, 0x8c000000, 0x94000000, 0x9c000000,
     0xa5000000, 0xad000000, 0xb5000000, 0xbd000000,
-    0xc5000000, 0xce000000, 0xd6000000, 0xde000000,
-    0xe6000000, 0xef000000, 0xf7000000, 0xff000000
+    0xc6000000, 0xce000000, 0xd6000000, 0xde000000,
+    0xe7000000, 0xef000000, 0xf7000000, 0xff000000
 };
 
 static const Uint32 RGB565_RGBA8888_LUT_G[64] = {
     0x00000000, 0x00040000, 0x00080000, 0x000c0000,
     0x00100000, 0x00140000, 0x00180000, 0x001c0000,
-    0x00200000, 0x00240000, 0x00280000, 0x002d0000,
-    0x00310000, 0x00350000, 0x00390000, 0x003d0000,
+    0x00200000, 0x00240000, 0x00280000, 0x002c0000,
+    0x00300000, 0x00340000, 0x00380000, 0x003c0000,
     0x00410000, 0x00450000, 0x00490000, 0x004d0000,
     0x00510000, 0x00550000, 0x00590000, 0x005d0000,
     0x00610000, 0x00650000, 0x00690000, 0x006d0000,
@@ -1512,21 +1545,21 @@ static const Uint32 RGB565_RGBA8888_LUT_G[64] = {
     0x00920000, 0x00960000, 0x009a0000, 0x009e0000,
     0x00a20000, 0x00a60000, 0x00aa0000, 0x00ae0000,
     0x00b20000, 0x00b60000, 0x00ba0000, 0x00be0000,
-    0x00c20000, 0x00c60000, 0x00ca0000, 0x00ce0000,
-    0x00d20000, 0x00d70000, 0x00db0000, 0x00df0000,
+    0x00c30000, 0x00c70000, 0x00cb0000, 0x00cf0000,
+    0x00d30000, 0x00d70000, 0x00db0000, 0x00df0000,
     0x00e30000, 0x00e70000, 0x00eb0000, 0x00ef0000,
     0x00f30000, 0x00f70000, 0x00fb0000, 0x00ff0000
 };
 
 static const Uint32 RGB565_RGBA8888_LUT_B[32] = {
-    0x00000000, 0x00000800, 0x00001000, 0x00001900,
-    0x00002100, 0x00002900, 0x00003100, 0x00003a00,
+    0x00000000, 0x00000800, 0x00001000, 0x00001800,
+    0x00002100, 0x00002900, 0x00003100, 0x00003900,
     0x00004200, 0x00004a00, 0x00005200, 0x00005a00,
     0x00006300, 0x00006b00, 0x00007300, 0x00007b00,
     0x00008400, 0x00008c00, 0x00009400, 0x00009c00,
     0x0000a500, 0x0000ad00, 0x0000b500, 0x0000bd00,
-    0x0000c500, 0x0000ce00, 0x0000d600, 0x0000de00,
-    0x0000e600, 0x0000ef00, 0x0000f700, 0x0000ff00
+    0x0000c600, 0x0000ce00, 0x0000d600, 0x0000de00,
+    0x0000e700, 0x0000ef00, 0x0000f700, 0x0000ff00
 };
 
 static void Blit_RGB565_RGBA8888(SDL_BlitInfo * info)
@@ -1537,21 +1570,21 @@ static void Blit_RGB565_RGBA8888(SDL_BlitInfo * info)
 // Special optimized blit for RGB565 -> BGRA8888
 
 static const Uint32 RGB565_BGRA8888_LUT_R[32] = {
-    0x00000000, 0x00000800, 0x00001000, 0x00001900,
-    0x00002100, 0x00002900, 0x00003100, 0x00003a00,
+    0x00000000, 0x00000800, 0x00001000, 0x00001800,
+    0x00002100, 0x00002900, 0x00003100, 0x00003900,
     0x00004200, 0x00004a00, 0x00005200, 0x00005a00,
     0x00006300, 0x00006b00, 0x00007300, 0x00007b00,
     0x00008400, 0x00008c00, 0x00009400, 0x00009c00,
     0x0000a500, 0x0000ad00, 0x0000b500, 0x0000bd00,
-    0x0000c500, 0x0000ce00, 0x0000d600, 0x0000de00,
-    0x0000e600, 0x0000ef00, 0x0000f700, 0x0000ff00
+    0x0000c600, 0x0000ce00, 0x0000d600, 0x0000de00,
+    0x0000e700, 0x0000ef00, 0x0000f700, 0x0000ff00
 };
 
 static const Uint32 RGB565_BGRA8888_LUT_G[64] = {
     0x00000000, 0x00040000, 0x00080000, 0x000c0000,
     0x00100000, 0x00140000, 0x00180000, 0x001c0000,
-    0x00200000, 0x00240000, 0x00280000, 0x002d0000,
-    0x00310000, 0x00350000, 0x00390000, 0x003d0000,
+    0x00200000, 0x00240000, 0x00280000, 0x002c0000,
+    0x00300000, 0x00340000, 0x00380000, 0x003c0000,
     0x00410000, 0x00450000, 0x00490000, 0x004d0000,
     0x00510000, 0x00550000, 0x00590000, 0x005d0000,
     0x00610000, 0x00650000, 0x00690000, 0x006d0000,
@@ -1560,21 +1593,21 @@ static const Uint32 RGB565_BGRA8888_LUT_G[64] = {
     0x00920000, 0x00960000, 0x009a0000, 0x009e0000,
     0x00a20000, 0x00a60000, 0x00aa0000, 0x00ae0000,
     0x00b20000, 0x00b60000, 0x00ba0000, 0x00be0000,
-    0x00c20000, 0x00c60000, 0x00ca0000, 0x00ce0000,
-    0x00d20000, 0x00d70000, 0x00db0000, 0x00df0000,
+    0x00c30000, 0x00c70000, 0x00cb0000, 0x00cf0000,
+    0x00d30000, 0x00d70000, 0x00db0000, 0x00df0000,
     0x00e30000, 0x00e70000, 0x00eb0000, 0x00ef0000,
     0x00f30000, 0x00f70000, 0x00fb0000, 0x00ff0000
 };
 
 static const Uint32 RGB565_BGRA8888_LUT_B[32] = {
-    0x00000000, 0x08000000, 0x10000000, 0x19000000,
-    0x21000000, 0x29000000, 0x31000000, 0x3a000000,
+    0x00000000, 0x08000000, 0x10000000, 0x18000000,
+    0x21000000, 0x29000000, 0x31000000, 0x39000000,
     0x42000000, 0x4a000000, 0x52000000, 0x5a000000,
     0x63000000, 0x6b000000, 0x73000000, 0x7b000000,
     0x84000000, 0x8c000000, 0x94000000, 0x9c000000,
     0xa5000000, 0xad000000, 0xb5000000, 0xbd000000,
-    0xc5000000, 0xce000000, 0xd6000000, 0xde000000,
-    0xe6000000, 0xef000000, 0xf7000000, 0xff000000
+    0xc6000000, 0xce000000, 0xd6000000, 0xde000000,
+    0xe7000000, 0xef000000, 0xf7000000, 0xff000000
 };
 
 static void Blit_RGB565_BGRA8888(SDL_BlitInfo * info)

+ 65 - 4
src/video/SDL_pixels.c

@@ -28,6 +28,67 @@
 
 // Lookup tables to expand partial bytes to the full 0..255 range
 
+// This is the code used to generate the lookup tables below:
+#if 0
+#include <stdio.h>
+#include <SDL3/SDL.h>
+
+#define GENERATE_SHIFTS
+
+static Uint32 Calculate(int v, int bits, int vmax, int shift)
+{
+#if defined(GENERATE_FLOOR)
+    return (Uint32)SDL_floor(v * 255.0f / vmax) << shift;
+#elif defined(GENERATE_ROUND)
+    return (Uint32)SDL_roundf(v * 255.0f / vmax) << shift;
+#elif defined(GENERATE_SHIFTS)
+    switch (bits) {
+    case 1:
+        v = (v << 7) | (v << 6) | (v << 5) | (v << 4) | (v << 3) | (v << 2) | (v << 1) | v;
+        break;
+    case 2:
+        v = (v << 6) | (v << 4) | (v << 2) | v;
+        break;
+    case 3:
+        v = (v << 5) | (v << 2) | (v >> 1);
+        break;
+    case 4:
+        v = (v << 4) | v;
+        break;
+    case 5:
+        v = (v << 3) | (v >> 2);
+        break;
+    case 6:
+        v = (v << 2) | (v >> 4);
+        break;
+    case 7:
+        v = (v << 1) | (v >> 6);
+        break;
+    case 8:
+        break;
+    }
+    return (Uint32)v << shift;
+#endif
+}
+
+int main(int argc, char *argv[])
+{
+    int i, b;
+
+    for (b = 1; b <= 8; ++b) {
+        printf("static const Uint8 lookup_%d[] = {\n    ", b);
+        for (i = 0; i < (1 << b); ++i) {
+            if (i > 0) {
+                printf(", ");
+            }
+            printf("%d", Calculate(i, b, (1 << b) - 1, 0));
+        }
+        printf("\n};\n\n");
+    }
+    return 0;
+}
+#endif
+
 static const Uint8 lookup_0[] = {
     255
 };
@@ -41,7 +102,7 @@ static const Uint8 lookup_2[] = {
 };
 
 static const Uint8 lookup_3[] = {
-    0, 36, 72, 109, 145, 182, 218, 255
+    0, 36, 73, 109, 146, 182, 219, 255
 };
 
 static const Uint8 lookup_4[] = {
@@ -49,15 +110,15 @@ static const Uint8 lookup_4[] = {
 };
 
 static const Uint8 lookup_5[] = {
-    0, 8, 16, 24, 32, 41, 49, 57, 65, 74, 82, 90, 98, 106, 115, 123, 131, 139, 148, 156, 164, 172, 180, 189, 197, 205, 213, 222, 230, 238, 246, 255
+    0, 8, 16, 24, 33, 41, 49, 57, 66, 74, 82, 90, 99, 107, 115, 123, 132, 140, 148, 156, 165, 173, 181, 189, 198, 206, 214, 222, 231, 239, 247, 255
 };
 
 static const Uint8 lookup_6[] = {
-    0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 129, 133, 137, 141, 145, 149, 153, 157, 161, 165, 170, 174, 178, 182, 186, 190, 194, 198, 202, 206, 210, 214, 218, 222, 226, 230, 234, 238, 242, 246, 250, 255
+    0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 65, 69, 73, 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 130, 134, 138, 142, 146, 150, 154, 158, 162, 166, 170, 174, 178, 182, 186, 190, 195, 199, 203, 207, 211, 215, 219, 223, 227, 231, 235, 239, 243, 247, 251, 255
 };
 
 static const Uint8 lookup_7[] = {
-    0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 255
+    0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 129, 131, 133, 135, 137, 139, 141, 143, 145, 147, 149, 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171, 173, 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231, 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255
 };
 
 static const Uint8 lookup_8[] = {

+ 80 - 0
test/testautomation_surface.c

@@ -1642,6 +1642,81 @@ static int SDLCALL surface_testScale(void *arg)
     return TEST_COMPLETED;
 }
 
+#define GENERATE_SHIFTS
+
+static Uint32 Calculate(int v, int bits, int vmax, int shift)
+{
+#if defined(GENERATE_FLOOR)
+    return (Uint32)SDL_floor(v * 255.0f / vmax) << shift;
+#elif defined(GENERATE_ROUND)
+    return (Uint32)SDL_roundf(v * 255.0f / vmax) << shift;
+#elif defined(GENERATE_SHIFTS)
+    switch (bits) {
+    case 1:
+        v = (v << 7) | (v << 6) | (v << 5) | (v << 4) | (v << 3) | (v << 2) | (v << 1) | v;
+        break;
+    case 2:
+        v = (v << 6) | (v << 4) | (v << 2) | v;
+        break;
+    case 3:
+        v = (v << 5) | (v << 2) | (v >> 1);
+        break;
+    case 4:
+        v = (v << 4) | v;
+        break;
+    case 5:
+        v = (v << 3) | (v >> 2);
+        break;
+    case 6:
+        v = (v << 2) | (v >> 4);
+        break;
+    case 7:
+        v = (v << 1) | (v >> 6);
+        break;
+    case 8:
+        break;
+    }
+    return (Uint32)v << shift;
+#endif
+}
+
+static Uint32 Calculate565toARGB(int v)
+{
+    Uint8 r = (v & 0xF800) >> 11;
+    Uint8 g = (v & 0x07E0) >> 5;
+    Uint8 b = (v & 0x001F);
+    return 0xFF000000 |
+            Calculate(r, 5, 31, 16) |
+            Calculate(g, 6, 63, 8) |
+            Calculate(b, 5, 31, 0);
+}
+
+static int SDLCALL surface_test16BitTo32Bit(void *arg)
+{
+    static Uint16 pixels[1 << 16];
+    static Uint32 expected[1 << 16];
+    int i, ret;
+    SDL_Surface *surface16;
+    SDL_Surface *surface32;
+    SDL_Surface *expected32;
+
+    for (i = 0; i < SDL_arraysize(pixels); ++i) {
+        pixels[i] = i;
+        expected[i] = Calculate565toARGB(i);
+    }
+
+    surface16 = SDL_CreateSurfaceFrom(SDL_arraysize(pixels), 1, SDL_PIXELFORMAT_RGB565, pixels, sizeof(pixels));
+    surface32 = SDL_ConvertSurface(surface16, SDL_PIXELFORMAT_ARGB8888);
+    expected32 = SDL_CreateSurfaceFrom(SDL_arraysize(expected), 1, SDL_PIXELFORMAT_ARGB8888, expected, sizeof(expected));
+    ret = SDLTest_CompareSurfaces(surface32, expected32, 0);
+    SDLTest_AssertCheck(ret == 0, "Validate result from SDLTest_CompareSurfaces, expected: 0, got: %i", ret);
+    SDL_DestroySurface(surface16);
+    SDL_DestroySurface(surface32);
+    SDL_DestroySurface(expected32);
+
+    return TEST_COMPLETED;
+}
+
 
 /* ================= Test References ================== */
 
@@ -1754,6 +1829,10 @@ static const SDLTest_TestCaseReference surfaceTestScale = {
     surface_testScale, "surface_testScale", "Test scaling operations.", TEST_ENABLED
 };
 
+static const SDLTest_TestCaseReference surfaceTest16BitTo32Bit = {
+    surface_test16BitTo32Bit, "surface_test16BitTo32Bit", "Test conversion from 16-bit to 32-bit pixels.", TEST_ENABLED
+};
+
 /* Sequence of Surface test cases */
 static const SDLTest_TestCaseReference *surfaceTests[] = {
     &surfaceTestInvalidFormat,
@@ -1783,6 +1862,7 @@ static const SDLTest_TestCaseReference *surfaceTests[] = {
     &surfaceTestClearSurface,
     &surfaceTestPremultiplyAlpha,
     &surfaceTestScale,
+    &surfaceTest16BitTo32Bit,
     NULL
 };