https://git.reactos.org/?p=reactos.git;a=commitdiff;h=30328cab077264492608e0...
commit 30328cab077264492608e0cf1edc9c764ebd44c6 Author: winesync ros-dev@reactos.org AuthorDate: Sat Jan 4 02:09:33 2020 +0100 Commit: Jérôme Gardou zefklop@users.noreply.github.com CommitDate: Wed Feb 26 18:19:18 2020 +0100
[WINESYNC]d3dx9_36: add DXTn support
wine-staging patch by Christian Costa titan.costa@gmail.com --- dll/directx/wine/d3dx9_36/d3dx9.cmake | 2 +- dll/directx/wine/d3dx9_36/surface.c | 102 ++++++++++- modules/rostests/winetests/d3dx9_36/surface.c | 8 +- .../0014-d3dx9_36__add_DXTn_support.diff | 203 +++++++++++++++++++++ 4 files changed, 302 insertions(+), 13 deletions(-)
diff --git a/dll/directx/wine/d3dx9_36/d3dx9.cmake b/dll/directx/wine/d3dx9_36/d3dx9.cmake index 77dd1cde119..900a8bfe887 100644 --- a/dll/directx/wine/d3dx9_36/d3dx9.cmake +++ b/dll/directx/wine/d3dx9_36/d3dx9.cmake @@ -35,7 +35,7 @@ function(add_d3dx9_target __version) set_module_type(${module} win32dll) add_dependencies(${module} d3d_idl_headers) target_link_libraries(${module} dxguid wine) - add_importlibs(${module} d3dcompiler_43 d3dxof user32 ole32 gdi32 msvcrt kernel32 ntdll) + add_importlibs(${module} d3dcompiler_43 d3dxof d3dwine user32 ole32 gdi32 msvcrt kernel32 ntdll) add_delay_importlibs(${module} windowscodecs) add_pch(${module} ../d3dx9_36/precomp.h SOURCE) add_cd_file(TARGET ${module} DESTINATION reactos/system32 FOR all) diff --git a/dll/directx/wine/d3dx9_36/surface.c b/dll/directx/wine/d3dx9_36/surface.c index d236feb0b83..3c308d36c8f 100644 --- a/dll/directx/wine/d3dx9_36/surface.c +++ b/dll/directx/wine/d3dx9_36/surface.c @@ -27,6 +27,8 @@ #include "ole2.h" #include "wincodec.h"
+#include "wine/wined3d.h" + WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
HRESULT WINAPI WICCreateImagingFactory_Proxy(UINT, IWICImagingFactory**); @@ -1876,6 +1878,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 * @@ -1915,10 +1935,12 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface, { const struct pixel_format_desc *srcformatdesc, *destformatdesc; IDirect3DSurface9 *surface; + void *tmp_src_memory = NULL, *tmp_dst_memory = NULL; + dxtn_conversion_func pre_convert = NULL, post_convert = NULL; D3DSURFACE_DESC surfdesc; D3DLOCKED_RECT lockrect; struct volume src_size, dst_size; - HRESULT hr; + HRESULT hr = 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, @@ -1999,18 +2021,65 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface, } else /* Stretching or format conversion. */ { - if (!is_conversion_from_supported(srcformatdesc) - || !is_conversion_to_supported(destformatdesc)) + 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); unlock_surface(dst_surface, &lockrect, surface, FALSE); return E_NOTIMPL; }
+ /* handle pre-conversion */ + if (pre_convert) + { + tmp_src_memory = HeapAlloc(GetProcessHeap(), 0, src_size.width * src_size.height * sizeof(DWORD)); + if (!tmp_src_memory) + { + hr = E_OUTOFMEMORY; + goto done; + } + 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)) + { + hr = E_FAIL; + goto done; + } + 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) + { + hr = E_OUTOFMEMORY; + goto done; + } + 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) */ { @@ -2019,12 +2088,29 @@ 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)) + { + hr = E_FAIL; + } } }
- return unlock_surface(dst_surface, &lockrect, surface, TRUE); +done: + if (pre_convert) + HeapFree(GetProcessHeap(), 0, tmp_src_memory); + if (post_convert) + HeapFree(GetProcessHeap(), 0, tmp_dst_memory); + + unlock_surface(dst_surface, &lockrect, surface, TRUE); + return hr; }
/************************************************************ diff --git a/modules/rostests/winetests/d3dx9_36/surface.c b/modules/rostests/winetests/d3dx9_36/surface.c index 2c83dc23499..95b64a0fa78 100644 --- a/modules/rostests/winetests/d3dx9_36/surface.c +++ b/modules/rostests/winetests/d3dx9_36/surface.c @@ -1224,7 +1224,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); } @@ -1250,7 +1250,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); } @@ -1263,10 +1263,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/sdk/tools/winesync/d3dx9_staging/0014-d3dx9_36__add_DXTn_support.diff b/sdk/tools/winesync/d3dx9_staging/0014-d3dx9_36__add_DXTn_support.diff new file mode 100644 index 00000000000..96b30a5f056 --- /dev/null +++ b/sdk/tools/winesync/d3dx9_staging/0014-d3dx9_36__add_DXTn_support.diff @@ -0,0 +1,203 @@ +diff --git a/dll/directx/wine/d3dx9_36/d3dx9.cmake b/dll/directx/wine/d3dx9_36/d3dx9.cmake +index 77dd1cde..900a8bfe 100644 +--- a/dll/directx/wine/d3dx9_36/d3dx9.cmake ++++ b/dll/directx/wine/d3dx9_36/d3dx9.cmake +@@ -35,7 +35,7 @@ function(add_d3dx9_target __version) + set_module_type(${module} win32dll) + add_dependencies(${module} d3d_idl_headers) + target_link_libraries(${module} dxguid wine) +- add_importlibs(${module} d3dcompiler_43 d3dxof user32 ole32 gdi32 msvcrt kernel32 ntdll) ++ add_importlibs(${module} d3dcompiler_43 d3dxof d3dwine user32 ole32 gdi32 msvcrt kernel32 ntdll) + add_delay_importlibs(${module} windowscodecs) + add_pch(${module} ../d3dx9_36/precomp.h SOURCE) + add_cd_file(TARGET ${module} DESTINATION reactos/system32 FOR all) +diff --git a/dll/directx/wine/d3dx9_36/surface.c b/dll/directx/wine/d3dx9_36/surface.c +index d236feb0..3c308d36 100644 +--- a/dll/directx/wine/d3dx9_36/surface.c ++++ b/dll/directx/wine/d3dx9_36/surface.c +@@ -27,6 +27,8 @@ + #include "ole2.h" + #include "wincodec.h" + ++#include "wine/wined3d.h" ++ + WINE_DEFAULT_DEBUG_CHANNEL(d3dx); + + HRESULT WINAPI WICCreateImagingFactory_Proxy(UINT, IWICImagingFactory**); +@@ -1876,6 +1878,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 + * +@@ -1915,10 +1935,12 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface, + { + const struct pixel_format_desc *srcformatdesc, *destformatdesc; + IDirect3DSurface9 *surface; ++ void *tmp_src_memory = NULL, *tmp_dst_memory = NULL; ++ dxtn_conversion_func pre_convert = NULL, post_convert = NULL; + D3DSURFACE_DESC surfdesc; + D3DLOCKED_RECT lockrect; + struct volume src_size, dst_size; +- HRESULT hr; ++ HRESULT hr = 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, +@@ -1999,18 +2021,65 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface, + } + else /* Stretching or format conversion. */ + { +- if (!is_conversion_from_supported(srcformatdesc) +- || !is_conversion_to_supported(destformatdesc)) ++ 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); + unlock_surface(dst_surface, &lockrect, surface, FALSE); + return E_NOTIMPL; + } + ++ /* handle pre-conversion */ ++ if (pre_convert) ++ { ++ tmp_src_memory = HeapAlloc(GetProcessHeap(), 0, src_size.width * src_size.height * sizeof(DWORD)); ++ if (!tmp_src_memory) ++ { ++ hr = E_OUTOFMEMORY; ++ goto done; ++ } ++ 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)) ++ { ++ hr = E_FAIL; ++ goto done; ++ } ++ 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) ++ { ++ hr = E_OUTOFMEMORY; ++ goto done; ++ } ++ 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) */ + { +@@ -2019,12 +2088,29 @@ 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)) ++ { ++ hr = E_FAIL; ++ } + } + } + +- return unlock_surface(dst_surface, &lockrect, surface, TRUE); ++done: ++ if (pre_convert) ++ HeapFree(GetProcessHeap(), 0, tmp_src_memory); ++ if (post_convert) ++ HeapFree(GetProcessHeap(), 0, tmp_dst_memory); ++ ++ unlock_surface(dst_surface, &lockrect, surface, TRUE); ++ return hr; + } + + /************************************************************ +diff --git a/modules/rostests/winetests/d3dx9_36/surface.c b/modules/rostests/winetests/d3dx9_36/surface.c +index 2c83dc23..95b64a0f 100644 +--- a/modules/rostests/winetests/d3dx9_36/surface.c ++++ b/modules/rostests/winetests/d3dx9_36/surface.c +@@ -1224,7 +1224,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); + } +@@ -1250,7 +1250,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); + } +@@ -1263,10 +1263,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);