Based off of original patch by Christian Costa, with minor modifications --- dlls/d3dx9_24/Makefile.in | 2 +- dlls/d3dx9_25/Makefile.in | 2 +- dlls/d3dx9_26/Makefile.in | 2 +- dlls/d3dx9_27/Makefile.in | 2 +- dlls/d3dx9_28/Makefile.in | 2 +- dlls/d3dx9_29/Makefile.in | 2 +- dlls/d3dx9_30/Makefile.in | 2 +- dlls/d3dx9_31/Makefile.in | 2 +- dlls/d3dx9_32/Makefile.in | 2 +- dlls/d3dx9_33/Makefile.in | 2 +- dlls/d3dx9_34/Makefile.in | 2 +- dlls/d3dx9_35/Makefile.in | 2 +- dlls/d3dx9_36/Makefile.in | 2 +- dlls/d3dx9_36/surface.c | 100 +++++++++++++++++++++++++++++++++++++++--- dlls/d3dx9_36/tests/surface.c | 8 ++-- dlls/d3dx9_37/Makefile.in | 2 +- dlls/d3dx9_38/Makefile.in | 2 +- dlls/d3dx9_39/Makefile.in | 2 +- dlls/d3dx9_40/Makefile.in | 2 +- dlls/d3dx9_41/Makefile.in | 2 +- dlls/d3dx9_42/Makefile.in | 2 +- dlls/d3dx9_43/Makefile.in | 2 +- 22 files changed, 117 insertions(+), 31 deletions(-)
diff --git a/dlls/d3dx9_24/Makefile.in b/dlls/d3dx9_24/Makefile.in index 482c92d64e..d969a55b10 100644 --- a/dlls/d3dx9_24/Makefile.in +++ b/dlls/d3dx9_24/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=24 MODULE = d3dx9_24.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36
C_SRCS = \ diff --git a/dlls/d3dx9_25/Makefile.in b/dlls/d3dx9_25/Makefile.in index be4c76980e..b232290d25 100644 --- a/dlls/d3dx9_25/Makefile.in +++ b/dlls/d3dx9_25/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=25 MODULE = d3dx9_25.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36
C_SRCS = \ diff --git a/dlls/d3dx9_26/Makefile.in b/dlls/d3dx9_26/Makefile.in index c5e9e85bfb..525009d292 100644 --- a/dlls/d3dx9_26/Makefile.in +++ b/dlls/d3dx9_26/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=26 MODULE = d3dx9_26.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36
C_SRCS = \ diff --git a/dlls/d3dx9_27/Makefile.in b/dlls/d3dx9_27/Makefile.in index ee7f0e2449..da98482d24 100644 --- a/dlls/d3dx9_27/Makefile.in +++ b/dlls/d3dx9_27/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=27 MODULE = d3dx9_27.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36
C_SRCS = \ diff --git a/dlls/d3dx9_28/Makefile.in b/dlls/d3dx9_28/Makefile.in index 094420013d..d50e035853 100644 --- a/dlls/d3dx9_28/Makefile.in +++ b/dlls/d3dx9_28/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=28 MODULE = d3dx9_28.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36
C_SRCS = \ diff --git a/dlls/d3dx9_29/Makefile.in b/dlls/d3dx9_29/Makefile.in index 88cb110ff5..cfc1a15034 100644 --- a/dlls/d3dx9_29/Makefile.in +++ b/dlls/d3dx9_29/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=29 MODULE = d3dx9_29.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36
C_SRCS = \ diff --git a/dlls/d3dx9_30/Makefile.in b/dlls/d3dx9_30/Makefile.in index 6ab2ff2451..726c92e8fd 100644 --- a/dlls/d3dx9_30/Makefile.in +++ b/dlls/d3dx9_30/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=30 MODULE = d3dx9_30.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36
C_SRCS = \ diff --git a/dlls/d3dx9_31/Makefile.in b/dlls/d3dx9_31/Makefile.in index 3d44da147d..201430127c 100644 --- a/dlls/d3dx9_31/Makefile.in +++ b/dlls/d3dx9_31/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=31 MODULE = d3dx9_31.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36
C_SRCS = \ diff --git a/dlls/d3dx9_32/Makefile.in b/dlls/d3dx9_32/Makefile.in index 37cc2797af..442258d8f3 100644 --- a/dlls/d3dx9_32/Makefile.in +++ b/dlls/d3dx9_32/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=32 MODULE = d3dx9_32.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36
C_SRCS = \ diff --git a/dlls/d3dx9_33/Makefile.in b/dlls/d3dx9_33/Makefile.in index 5b03ec134d..cc98ed2501 100644 --- a/dlls/d3dx9_33/Makefile.in +++ b/dlls/d3dx9_33/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=33 MODULE = d3dx9_33.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36
C_SRCS = \ diff --git a/dlls/d3dx9_34/Makefile.in b/dlls/d3dx9_34/Makefile.in index b7f9c46d5e..4862fe94af 100644 --- a/dlls/d3dx9_34/Makefile.in +++ b/dlls/d3dx9_34/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=34 MODULE = d3dx9_34.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36
C_SRCS = \ diff --git a/dlls/d3dx9_35/Makefile.in b/dlls/d3dx9_35/Makefile.in index 9c196ea038..3f529c9915 100644 --- a/dlls/d3dx9_35/Makefile.in +++ b/dlls/d3dx9_35/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=35 MODULE = d3dx9_35.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36
C_SRCS = \ diff --git a/dlls/d3dx9_36/Makefile.in b/dlls/d3dx9_36/Makefile.in index da8098dd8d..166031e6a4 100644 --- a/dlls/d3dx9_36/Makefile.in +++ b/dlls/d3dx9_36/Makefile.in @@ -1,7 +1,7 @@ EXTRADEFS = -DD3DX_SDK_VERSION=36 MODULE = d3dx9_36.dll IMPORTLIB = d3dx9 -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d
C_SRCS = \ animation.c \ diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c index 0a6e20e8f1..a33b6e2e45 100644 --- a/dlls/d3dx9_36/surface.c +++ b/dlls/d3dx9_36/surface.c @@ -27,6 +27,8 @@ #include "ole2.h" #include "wincodec.h"
+#include "wine/wined3d.h" + WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
@@ -1715,6 +1717,24 @@ void point_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slic } }
+typedef BOOL (*dxtn_conversion_func)(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out, + enum wined3d_format_id format, unsigned int w, unsigned int h); + +static dxtn_conversion_func get_dxtn_conversion_func(D3DFORMAT format, BOOL encode) +{ + switch (format) + { + case D3DFMT_DXT1: + return encode ? wined3d_dxt1_encode : wined3d_dxt1_decode; + case D3DFMT_DXT3: + return encode ? wined3d_dxt3_encode : wined3d_dxt3_decode; + case D3DFMT_DXT5: + return encode ? wined3d_dxt5_encode : wined3d_dxt5_decode; + default: + return NULL; + } +} + /************************************************************ * D3DXLoadSurfaceFromMemory * @@ -1756,6 +1776,7 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface, D3DSURFACE_DESC surfdesc; D3DLOCKED_RECT lockrect; struct volume src_size, dst_size; + HRESULT ret = D3D_OK;
TRACE("(%p, %p, %s, %p, %#x, %u, %p, %s, %#x, 0x%08x)\n", dst_surface, dst_palette, wine_dbgstr_rect(dst_rect), src_memory, src_format, @@ -1837,8 +1858,15 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface, } else /* Stretching or format conversion. */ { - if (!is_conversion_from_supported(srcformatdesc) - || !is_conversion_to_supported(destformatdesc)) + dxtn_conversion_func pre_convert, post_convert; + void *tmp_src_memory = NULL, *tmp_dst_memory = NULL; + UINT tmp_src_pitch, tmp_dst_pitch; + + pre_convert = get_dxtn_conversion_func(srcformatdesc->format, FALSE); + post_convert = get_dxtn_conversion_func(destformatdesc->format, TRUE); + + if ((!pre_convert && !is_conversion_from_supported(srcformatdesc)) || + (!post_convert && !is_conversion_to_supported(destformatdesc))) { FIXME("Unsupported format conversion %#x -> %#x.\n", src_format, surfdesc.Format); return E_NOTIMPL; @@ -1847,10 +1875,52 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface, if (FAILED(IDirect3DSurface9_LockRect(dst_surface, &lockrect, dst_rect, 0))) return D3DXERR_INVALIDDATA;
+ /* handle pre-conversion */ + if (pre_convert) + { + tmp_src_memory = HeapAlloc(GetProcessHeap(), 0, src_size.width * src_size.height * sizeof(DWORD)); + if (!tmp_src_memory) + { + ret = E_OUTOFMEMORY; + goto error; + } + tmp_src_pitch = src_size.width * sizeof(DWORD); + if (!pre_convert(src_memory, tmp_src_memory, src_pitch, tmp_src_pitch, + WINED3DFMT_B8G8R8A8_UNORM, src_size.width, src_size.height)) + { + ret = E_FAIL; + goto error; + } + srcformatdesc = get_format_info(D3DFMT_A8R8G8B8); + } + else + { + tmp_src_memory = (void *)src_memory; + tmp_src_pitch = src_pitch; + } + + /* handle post-conversion */ + if (post_convert) + { + tmp_dst_memory = HeapAlloc(GetProcessHeap(), 0, dst_size.width * dst_size.height * sizeof(DWORD)); + if (!tmp_dst_memory) + { + ret = E_OUTOFMEMORY; + goto error; + } + tmp_dst_pitch = dst_size.width * sizeof(DWORD); + destformatdesc = get_format_info(D3DFMT_A8R8G8B8); + } + else + { + tmp_dst_memory = lockrect.pBits; + tmp_dst_pitch = lockrect.Pitch; + } + if ((filter & 0xf) == D3DX_FILTER_NONE) { - convert_argb_pixels(src_memory, src_pitch, 0, &src_size, srcformatdesc, - lockrect.pBits, lockrect.Pitch, 0, &dst_size, destformatdesc, color_key, src_palette); + convert_argb_pixels(tmp_src_memory, tmp_src_pitch, 0, &src_size, srcformatdesc, + tmp_dst_memory, tmp_dst_pitch, 0, &dst_size, destformatdesc, color_key, src_palette); } else /* if ((filter & 0xf) == D3DX_FILTER_POINT) */ { @@ -1859,14 +1929,30 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface,
/* Always apply a point filter until D3DX_FILTER_LINEAR, * D3DX_FILTER_TRIANGLE and D3DX_FILTER_BOX are implemented. */ - point_filter_argb_pixels(src_memory, src_pitch, 0, &src_size, srcformatdesc, - lockrect.pBits, lockrect.Pitch, 0, &dst_size, destformatdesc, color_key, src_palette); + point_filter_argb_pixels(tmp_src_memory, tmp_src_pitch, 0, &src_size, srcformatdesc, + tmp_dst_memory, tmp_dst_pitch, 0, &dst_size, destformatdesc, color_key, src_palette); + } + + /* handle post-conversion */ + if (post_convert) + { + if (!post_convert(tmp_dst_memory, lockrect.pBits, tmp_dst_pitch, lockrect.Pitch, + WINED3DFMT_B8G8R8A8_UNORM, dst_size.width, dst_size.height)) + { + ret = E_FAIL; + goto error; + } }
+error: + if (pre_convert) + HeapFree(GetProcessHeap(), 0, tmp_src_memory); + if (post_convert) + HeapFree(GetProcessHeap(), 0, tmp_dst_memory); IDirect3DSurface9_UnlockRect(dst_surface); }
- return D3D_OK; + return ret; }
/************************************************************ diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c index 324e2af3eb..5fc2657536 100644 --- a/dlls/d3dx9_36/tests/surface.c +++ b/dlls/d3dx9_36/tests/surface.c @@ -1179,7 +1179,7 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device) hr = IDirect3DTexture9_GetSurfaceLevel(tex, 0, &newsurf); ok(SUCCEEDED(hr), "Failed to get the surface, hr %#x.\n", hr); hr = D3DXLoadSurfaceFromSurface(newsurf, NULL, NULL, surf, NULL, NULL, D3DX_FILTER_NONE, 0); - todo_wine ok(SUCCEEDED(hr), "Failed to convert pixels to DXT3 format.\n"); + ok(SUCCEEDED(hr), "Failed to convert pixels to DXT3 format.\n"); check_release((IUnknown*)newsurf, 1); check_release((IUnknown*)tex, 0); } @@ -1205,7 +1205,7 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device) hr = IDirect3DTexture9_GetSurfaceLevel(tex, 0, &newsurf); ok(SUCCEEDED(hr), "Failed to get the surface, hr %#x.\n", hr); hr = D3DXLoadSurfaceFromSurface(newsurf, NULL, NULL, surf, NULL, NULL, D3DX_FILTER_NONE, 0); - todo_wine ok(SUCCEEDED(hr), "Failed to convert pixels to DXT5 format.\n"); + ok(SUCCEEDED(hr), "Failed to convert pixels to DXT5 format.\n"); check_release((IUnknown*)newsurf, 1); check_release((IUnknown*)tex, 0); } @@ -1218,10 +1218,10 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device) hr = IDirect3DTexture9_GetSurfaceLevel(tex, 0, &newsurf); ok(SUCCEEDED(hr), "Failed to get the surface, hr %#x.\n", hr); hr = D3DXLoadSurfaceFromSurface(newsurf, NULL, NULL, surf, NULL, NULL, D3DX_FILTER_NONE, 0); - todo_wine ok(SUCCEEDED(hr), "Failed to convert pixels to DXT1 format.\n"); + ok(SUCCEEDED(hr), "Failed to convert pixels to DXT1 format.\n");
hr = D3DXLoadSurfaceFromSurface(surf, NULL, NULL, newsurf, NULL, NULL, D3DX_FILTER_NONE, 0); - todo_wine ok(SUCCEEDED(hr), "Failed to convert pixels from DXT1 format.\n"); + ok(SUCCEEDED(hr), "Failed to convert pixels from DXT1 format.\n");
check_release((IUnknown*)newsurf, 1); check_release((IUnknown*)tex, 0); diff --git a/dlls/d3dx9_37/Makefile.in b/dlls/d3dx9_37/Makefile.in index ab790a4d5c..51382c7109 100644 --- a/dlls/d3dx9_37/Makefile.in +++ b/dlls/d3dx9_37/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=37 MODULE = d3dx9_37.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36
C_SRCS = \ diff --git a/dlls/d3dx9_38/Makefile.in b/dlls/d3dx9_38/Makefile.in index 6125c2da67..f6257cbdec 100644 --- a/dlls/d3dx9_38/Makefile.in +++ b/dlls/d3dx9_38/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=38 MODULE = d3dx9_38.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36
C_SRCS = \ diff --git a/dlls/d3dx9_39/Makefile.in b/dlls/d3dx9_39/Makefile.in index d97a787c67..a68ee9f3ad 100644 --- a/dlls/d3dx9_39/Makefile.in +++ b/dlls/d3dx9_39/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=39 MODULE = d3dx9_39.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36
C_SRCS = \ diff --git a/dlls/d3dx9_40/Makefile.in b/dlls/d3dx9_40/Makefile.in index 36c5a210cd..7f2cfe1a47 100644 --- a/dlls/d3dx9_40/Makefile.in +++ b/dlls/d3dx9_40/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=40 MODULE = d3dx9_40.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36
C_SRCS = \ diff --git a/dlls/d3dx9_41/Makefile.in b/dlls/d3dx9_41/Makefile.in index d4552cf608..c5c3ab1aae 100644 --- a/dlls/d3dx9_41/Makefile.in +++ b/dlls/d3dx9_41/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=41 MODULE = d3dx9_41.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36
C_SRCS = \ diff --git a/dlls/d3dx9_42/Makefile.in b/dlls/d3dx9_42/Makefile.in index 5806fce66c..e9a8e89da5 100644 --- a/dlls/d3dx9_42/Makefile.in +++ b/dlls/d3dx9_42/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=42 MODULE = d3dx9_42.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36
C_SRCS = \ diff --git a/dlls/d3dx9_43/Makefile.in b/dlls/d3dx9_43/Makefile.in index 72ba8b4c1e..33185bf7a8 100644 --- a/dlls/d3dx9_43/Makefile.in +++ b/dlls/d3dx9_43/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=43 MODULE = d3dx9_43.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36
C_SRCS = \