wine-staging/patches/wined3d-DXTn/0003-wined3d-add-DXT1-to-B4G4R4A4-DXT1-to-B5G5R5A1-and-DX.patch

224 lines
9.0 KiB
Diff
Raw Normal View History

From 845cd7d5bb57a9d54987de39073f2efd2de5ccc4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Wed, 26 Nov 2014 14:24:57 +0100
Subject: wined3d: add DXT1 to B4G4R4A4, DXT1 to B5G5R5A1 and DXT3 to B4G4R4A4
conversion.
---
dlls/wined3d/dxtn.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++
dlls/wined3d/surface.c | 42 +++++++++++++++++++
2 files changed, 150 insertions(+)
diff --git a/dlls/wined3d/dxtn.c b/dlls/wined3d/dxtn.c
index c9889cc..fa8c789 100644
--- a/dlls/wined3d/dxtn.c
+++ b/dlls/wined3d/dxtn.c
@@ -64,6 +64,70 @@ static inline BOOL dxt1_to_x8r8g8b8(const BYTE *src, BYTE *dst, DWORD pitch_in,
return TRUE;
}
+static inline BOOL dxt1_to_x4r4g4b4(const BYTE *src, BYTE *dst, DWORD pitch_in,
+ DWORD pitch_out, unsigned int w, unsigned int h, BOOL alpha)
+{
+ unsigned int x, y;
+ DWORD color;
+
+ TRACE("Converting %ux%u pixels, pitches %u %u\n", w, h, pitch_in, pitch_out);
+
+ for (y = 0; y < h; ++y)
+ {
+ WORD *dst_line = (WORD *)(dst + y * pitch_out);
+ for (x = 0; x < w; ++x)
+ {
+ /* pfetch_2d_texel_rgba_dxt1 doesn't correctly handle pitch */
+ pfetch_2d_texel_rgba_dxt1(0, src + (y / 4) * pitch_in + (x / 4) * 16,
+ x & 3, y & 3, &color);
+ if (alpha)
+ {
+ dst_line[x] = ((color & 0xf0000000) >> 16) | ((color & 0xf00000) >> 20) |
+ ((color & 0xf000) >> 8) | ((color & 0xf0) << 4);
+ }
+ else
+ {
+ dst_line[x] = 0xf000 | ((color & 0xf00000) >> 20) |
+ ((color & 0xf000) >> 8) | ((color & 0xf0) << 4);
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+static inline BOOL dxt1_to_x1r5g5b5(const BYTE *src, BYTE *dst, DWORD pitch_in,
+ DWORD pitch_out, unsigned int w, unsigned int h, BOOL alpha)
+{
+ unsigned int x, y;
+ DWORD color;
+
+ TRACE("Converting %ux%u pixels, pitches %u %u\n", w, h, pitch_in, pitch_out);
+
+ for (y = 0; y < h; ++y)
+ {
+ WORD *dst_line = (WORD *)(dst + y * pitch_out);
+ for (x = 0; x < w; ++x)
+ {
+ /* pfetch_2d_texel_rgba_dxt1 doesn't correctly handle pitch */
+ pfetch_2d_texel_rgba_dxt1(0, src + (y / 4) * pitch_in + (x / 4) * 16,
+ x & 3, y & 3, &color);
+ if (alpha)
+ {
+ dst_line[x] = ((color & 0x80000000) >> 16) | ((color & 0xf80000) >> 19) |
+ ((color & 0xf800) >> 6) | ((color & 0xf8) << 7);
+ }
+ else
+ {
+ dst_line[x] = 0x8000 | ((color & 0xf80000) >> 19) |
+ ((color & 0xf800) >> 6) | ((color & 0xf8) << 7);
+ }
+ }
+ }
+
+ return TRUE;
+}
+
static inline BOOL dxt3_to_x8r8g8b8(const BYTE *src, BYTE *dst, DWORD pitch_in,
DWORD pitch_out, unsigned int w, unsigned int h, BOOL alpha)
{
@@ -96,6 +160,38 @@ static inline BOOL dxt3_to_x8r8g8b8(const BYTE *src, BYTE *dst, DWORD pitch_in,
return TRUE;
}
+static inline BOOL dxt3_to_x4r4g4b4(const BYTE *src, BYTE *dst, DWORD pitch_in,
+ DWORD pitch_out, unsigned int w, unsigned int h, BOOL alpha)
+{
+ unsigned int x, y;
+ DWORD color;
+
+ TRACE("Converting %ux%u pixels, pitches %u %u\n", w, h, pitch_in, pitch_out);
+
+ for (y = 0; y < h; ++y)
+ {
+ WORD *dst_line = (WORD *)(dst + y * pitch_out);
+ for (x = 0; x < w; ++x)
+ {
+ /* pfetch_2d_texel_rgba_dxt3 doesn't correctly handle pitch */
+ pfetch_2d_texel_rgba_dxt3(0, src + (y / 4) * pitch_in + (x / 4) * 16,
+ x & 3, y & 3, &color);
+ if (alpha)
+ {
+ dst_line[x] = ((color & 0xf0000000) >> 16) | ((color & 0xf00000) >> 20) |
+ ((color & 0xf000) >> 8) | ((color & 0xf0) << 4);
+ }
+ else
+ {
+ dst_line[x] = 0xf000 | ((color & 0xf00000) >> 20) |
+ ((color & 0xf000) >> 8) | ((color & 0xf0) << 4);
+ }
+ }
+ }
+
+ return TRUE;
+}
+
static inline BOOL dxt5_to_x8r8g8b8(const BYTE *src, BYTE *dst, DWORD pitch_in,
DWORD pitch_out, unsigned int w, unsigned int h, BOOL alpha)
{
@@ -235,6 +331,14 @@ BOOL wined3d_dxt1_decode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch
return dxt1_to_x8r8g8b8(src, dst, pitch_in, pitch_out, w, h, TRUE);
case WINED3DFMT_B8G8R8X8_UNORM:
return dxt1_to_x8r8g8b8(src, dst, pitch_in, pitch_out, w, h, FALSE);
+ case WINED3DFMT_B4G4R4A4_UNORM:
+ return dxt1_to_x4r4g4b4(src, dst, pitch_in, pitch_out, w, h, TRUE);
+ case WINED3DFMT_B4G4R4X4_UNORM:
+ return dxt1_to_x4r4g4b4(src, dst, pitch_in, pitch_out, w, h, FALSE);
+ case WINED3DFMT_B5G5R5A1_UNORM:
+ return dxt1_to_x1r5g5b5(src, dst, pitch_in, pitch_out, w, h, TRUE);
+ case WINED3DFMT_B5G5R5X1_UNORM:
+ return dxt1_to_x1r5g5b5(src, dst, pitch_in, pitch_out, w, h, FALSE);
default:
break;
}
@@ -258,6 +362,10 @@ BOOL wined3d_dxt3_decode(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch
return dxt3_to_x8r8g8b8(src, dst, pitch_in, pitch_out, w, h, TRUE);
case WINED3DFMT_B8G8R8X8_UNORM:
return dxt3_to_x8r8g8b8(src, dst, pitch_in, pitch_out, w, h, FALSE);
+ case WINED3DFMT_B4G4R4A4_UNORM:
+ return dxt3_to_x4r4g4b4(src, dst, pitch_in, pitch_out, w, h, TRUE);
+ case WINED3DFMT_B4G4R4X4_UNORM:
+ return dxt3_to_x4r4g4b4(src, dst, pitch_in, pitch_out, w, h, FALSE);
default:
break;
}
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index e224df4..a123ffd 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -2427,6 +2427,30 @@ static void convert_dxt1_x8r8g8b8(const BYTE *src, BYTE *dst,
wined3d_dxt1_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8X8_UNORM, w, h);
}
+static void convert_dxt1_a4r4g4b4(const BYTE *src, BYTE *dst,
+ DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+ wined3d_dxt1_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B4G4R4A4_UNORM, w, h);
+}
+
+static void convert_dxt1_x4r4g4b4(const BYTE *src, BYTE *dst,
+ DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+ wined3d_dxt1_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B4G4R4X4_UNORM, w, h);
+}
+
+static void convert_dxt1_a1r5g5b5(const BYTE *src, BYTE *dst,
+ DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+ wined3d_dxt1_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B5G5R5A1_UNORM, w, h);
+}
+
+static void convert_dxt1_x1r5g5b5(const BYTE *src, BYTE *dst,
+ DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+ wined3d_dxt1_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B5G5R5X1_UNORM, w, h);
+}
+
static void convert_dxt3_a8r8g8b8(const BYTE *src, BYTE *dst,
DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
{
@@ -2439,6 +2463,18 @@ static void convert_dxt3_x8r8g8b8(const BYTE *src, BYTE *dst,
wined3d_dxt3_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B8G8R8X8_UNORM, w, h);
}
+static void convert_dxt3_a4r4g4b4(const BYTE *src, BYTE *dst,
+ DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+ wined3d_dxt3_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B4G4R4A4_UNORM, w, h);
+}
+
+static void convert_dxt3_x4r4g4b4(const BYTE *src, BYTE *dst,
+ DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+ wined3d_dxt3_decode(src, dst, pitch_in, pitch_out, WINED3DFMT_B4G4R4X4_UNORM, w, h);
+}
+
static void convert_dxt5_a8r8g8b8(const BYTE *src, BYTE *dst,
DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
{
@@ -2517,8 +2553,14 @@ static const struct d3dfmt_converter_desc converters[] =
/* decode DXT */
{WINED3DFMT_DXT1, WINED3DFMT_B8G8R8A8_UNORM, convert_dxt1_a8r8g8b8},
{WINED3DFMT_DXT1, WINED3DFMT_B8G8R8X8_UNORM, convert_dxt1_x8r8g8b8},
+ {WINED3DFMT_DXT1, WINED3DFMT_B4G4R4A4_UNORM, convert_dxt1_a4r4g4b4},
+ {WINED3DFMT_DXT1, WINED3DFMT_B4G4R4X4_UNORM, convert_dxt1_x4r4g4b4},
+ {WINED3DFMT_DXT1, WINED3DFMT_B5G5R5A1_UNORM, convert_dxt1_a1r5g5b5},
+ {WINED3DFMT_DXT1, WINED3DFMT_B5G5R5X1_UNORM, convert_dxt1_x1r5g5b5},
{WINED3DFMT_DXT3, WINED3DFMT_B8G8R8A8_UNORM, convert_dxt3_a8r8g8b8},
{WINED3DFMT_DXT3, WINED3DFMT_B8G8R8X8_UNORM, convert_dxt3_x8r8g8b8},
+ {WINED3DFMT_DXT3, WINED3DFMT_B4G4R4A4_UNORM, convert_dxt3_a4r4g4b4},
+ {WINED3DFMT_DXT3, WINED3DFMT_B4G4R4X4_UNORM, convert_dxt3_x4r4g4b4},
{WINED3DFMT_DXT5, WINED3DFMT_B8G8R8A8_UNORM, convert_dxt5_a8r8g8b8},
{WINED3DFMT_DXT5, WINED3DFMT_B8G8R8X8_UNORM, convert_dxt5_x8r8g8b8},
--
1.9.1