https://git.reactos.org/?p=reactos.git;a=commitdiff;h=83d1420b3c069ee81897f…
commit 83d1420b3c069ee81897f288f1098049d21cd75f
Author: winesync <ros-dev(a)reactos.org>
AuthorDate: Wed Feb 5 22:11:40 2020 +0100
Commit: Jérôme Gardou <zefklop(a)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(a)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);