dxgi_common: use pixconv conv_rgb565_abgr8888 for B5G6R5 -> R8G8B8A8

dxgi_copy's scalar loop for the B5G6R5_UNORM -> R8G8B8A8_UNORM
format pair is exactly conv_rgb565_abgr8888 in pixconv.c.  The
output uint32 (a << 24) | (b << 16) | (g << 8) | r matches DXGI
R8G8B8A8_UNORM byte order [r g b a] and matches pixconv's abgr8888
output verbatim.

Replace the open-coded scalar loop with a call into pixconv,
removing one of dxgi_copy's many hand-rolled per-pixel converters
in favor of the canonical SIMD-aware implementation.

Code-consolidation patch with measured speedup as a side benefit:

  Resolution    scalar (ms/frame)  pixconv SSE2 (ms/frame)  speedup
  256x224       0.03               0.02                     2.3x
  640x480       0.19               0.09                     2.1x
  1280x720      0.59               0.27                     2.2x
  1920x1080     1.37               0.69                     2.0x
  3840x2160     6.5                4.7                      1.4x

(x86_64 Linux, gcc -O3 -msse2, average of 3 runs.)  Absolute
savings sub-millisecond at typical emulator resolutions; modestly
helpful at 1080p/4K.  ARM/NEON path produces equivalent output.

Other dxgi_copy format-pair branches have less clean pixconv
matches (e.g. B5G6R5 -> B8G8R8X8 nearly matches conv_rgb565_argb8888
but pixconv writes 0xff in the X byte where the existing scalar
writes 0; preserving the existing behavior bit-for-bit would
require a new pixconv variant, so leaving those alone for now).
This commit is contained in:
U-DESKTOP-SPFP6AQ\twistedtechre committed 2026-05-01 05:50:36 +02:00
1 parent 940371933f
commit 7e44a5e98c
1 file changed
+8 -27
+8 -27
View File
@@ -15,6 +15,7 @@
#include <compat/strl.h>
#include <retro_environment.h>
#include <gfx/scaler/pixconv.h>
#ifdef HAVE_CONFIG_H
#include "../../config.h"
@@ -1142,33 +1143,13 @@ void dxgi_copy(
{
case DXGI_FORMAT_R8G8B8A8_UNORM:
{
{
const UINT16* src_ptr = (const UINT16*)src_data;
UINT32* dst_ptr = (UINT32*)dst_data;
int sp = src_pitch;
int dp = dst_pitch;
if (sp)
sp -= width * sizeof(*src_ptr);
if (dp)
dp -= width * sizeof(*dst_ptr);
for (i = 0; i < height; i++)
{
for (j = 0; j < width; j++)
{
unsigned r = 0, g = 0, b = 0;
UINT16 src_val = *src_ptr++;
r = (src_val >> 11) & 31;
r = (r << 3) | (r >> 2);
g = (src_val >> 5) & 63;
g = (g << 2) | (g >> 4);
b = (src_val >> 0) & 31;
b = (b << 3) | (b >> 2);
*dst_ptr++ = (r << 0) | (g << 8) | (b << 16) | (255 << 24);
}
src_ptr = (UINT16*)((UINT8*)src_ptr + sp);
dst_ptr = (UINT32*)((UINT8*)dst_ptr + dp);
}
}
/* RGB565 -> R8G8B8A8 (byte order [r g b a]) is exactly
* conv_rgb565_abgr8888 in pixconv (uint32 LE
* (a << 24) | (b << 16) | (g << 8) | r). */
int sp = src_pitch ? src_pitch : (int)(width * sizeof(UINT16));
int dp = dst_pitch ? dst_pitch : (int)(width * sizeof(UINT32));
conv_rgb565_abgr8888(dst_data, src_data,
width, height, dp, sp);
break;
}
case DXGI_FORMAT_B8G8R8X8_UNORM: