From 69d910d52fb2c6a98a6658faa2efa9b95982e68b 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 6623e64..57da0df 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) { @@ -232,6 +328,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; } @@ -252,6 +356,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 4fc917d..689fc0e 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -2428,6 +2428,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) { @@ -2440,6 +2464,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) { @@ -2521,8 +2557,14 @@ static const struct d3dfmt_converter_desc dxtn_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}, -- 2.2.1