diff --git a/README.md b/README.md index 95375342..0e9dfb6f 100644 --- a/README.md +++ b/README.md @@ -39,9 +39,10 @@ Wine. All those differences are also documented on the Included bug fixes and improvements =================================== -**Bugfixes and features included in the next upcoming release [5]:** +**Bugfixes and features included in the next upcoming release [6]:** * Avoid race-conditions of async WSARecv() operations with write watches. +* Black & White needs DXTn software decoding support ([Wine Bug #14939](https://bugs.winehq.org/show_bug.cgi?id=14939)) * Fix issues with dragging layers between images in Adobe Photoshop 7.0 ([Wine Bug #12007](https://bugs.winehq.org/show_bug.cgi?id=12007)) * Implement exclusive mode in PulseAudio backend ([Wine Bug #37042](https://bugs.winehq.org/show_bug.cgi?id=37042)) * Take abs() of vertex z coordinate as FFP fog coordinate diff --git a/patches/Makefile b/patches/Makefile index 6301b24d..79f55f21 100644 --- a/patches/Makefile +++ b/patches/Makefile @@ -1636,6 +1636,7 @@ winebuild-LinkerVersion.ok: # | This patchset fixes the following Wine bugs: # | * [#25486] Lego Stunt Rally requires DXTn software de/encoding support # | * [#29586] Tumblebugs 2 requires DXTn software encoding support +# | * [#14939] Black & White needs DXTn software decoding support # | # | Modified files: # | * configure.ac, dlls/wined3d/Makefile.in, dlls/wined3d/dxtn.c, dlls/wined3d/surface.c, dlls/wined3d/wined3d.spec, @@ -1645,9 +1646,11 @@ winebuild-LinkerVersion.ok: wined3d-DXTn.ok: $(call APPLY_FILE,wined3d-DXTn/0001-wined3d-Add-support-for-DXTn-software-decoding-throu.patch) $(call APPLY_FILE,wined3d-DXTn/0002-wined3d-Improve-DXTn-support-and-export-conversion-f.patch) + $(call APPLY_FILE,wined3d-DXTn/0003-wined3d-add-DXT1-to-B4G4R4A4-DXT1-to-B5G5R5A1-and-DX.patch) @( \ echo '+ { "Michael Müller", "wined3d: Add support for DXTn software decoding through libtxc_dxtn.", 1 },'; \ echo '+ { "Christian Costa", "wined3d: Improve DXTn support and export conversion functions for d3dx9_36.", 1 },'; \ + echo '+ { "Michael Müller", "wined3d: add DXT1 to B4G4R4A4, DXT1 to B5G5R5A1 and DXT3 to B4G4R4A4 conversion.", 1 },'; \ ) > wined3d-DXTn.ok # Patchset wined3d-FFP_Fog diff --git a/patches/wined3d-DXTn/0003-wined3d-add-DXT1-to-B4G4R4A4-DXT1-to-B5G5R5A1-and-DX.patch b/patches/wined3d-DXTn/0003-wined3d-add-DXT1-to-B4G4R4A4-DXT1-to-B5G5R5A1-and-DX.patch new file mode 100644 index 00000000..5db4849e --- /dev/null +++ b/patches/wined3d-DXTn/0003-wined3d-add-DXT1-to-B4G4R4A4-DXT1-to-B5G5R5A1-and-DX.patch @@ -0,0 +1,223 @@ +From 845cd7d5bb57a9d54987de39073f2efd2de5ccc4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +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 + diff --git a/patches/wined3d-DXTn/definition b/patches/wined3d-DXTn/definition index ed10a977..3a8f9a50 100644 --- a/patches/wined3d-DXTn/definition +++ b/patches/wined3d-DXTn/definition @@ -1,2 +1,3 @@ Fixes: [25486] Lego Stunt Rally requires DXTn software de/encoding support Fixes: [29586] Tumblebugs 2 requires DXTn software encoding support +Fixes: [14939] Black & White needs DXTn software decoding support