diff --git a/README.md b/README.md index c42e066a..6f0d7e1e 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ Wine. All those differences are also documented on the Included bug fixes and improvements ----------------------------------- -**Bug fixes and features included in the next upcoming release [14]:** +**Bug fixes and features included in the next upcoming release [15]:** * Add shell32 placeholder icons to match offsets with Windows ([Wine Bug #30185](https://bugs.winehq.org/show_bug.cgi?id=30185)) * Add stub for iphlpapi.ConvertInterfaceLuidToGuid ([Wine Bug #38576](https://bugs.winehq.org/show_bug.cgi?id=38576)) @@ -52,6 +52,7 @@ Included bug fixes and improvements * Fix NULL pointer dereference in get_frame_by_name ([Wine Bug #34982](https://bugs.winehq.org/show_bug.cgi?id=34982)) * Fix crash in Gothic 1/2 with builtin directmusic caused by wrong return value ([Wine Bug #7425](https://bugs.winehq.org/show_bug.cgi?id=7425)) * Fix handling of opening a file with RootDirectory pointing to a file handle +* Fix scaling behaviour of images and mipmap levels in IDirect3DTexture2_Load (needed for example by Prezzie Hunt) * Return fake device type when systemroot is located on virtual disk ([Wine Bug #36546](https://bugs.winehq.org/show_bug.cgi?id=36546)) * Support for ws2_32.dll.WSAPoll ([Wine Bug #38601](https://bugs.winehq.org/show_bug.cgi?id=38601)) * Use random names when caching very long urls in wininet diff --git a/debian/changelog b/debian/changelog index e2c987c2..334887af 100644 --- a/debian/changelog +++ b/debian/changelog @@ -18,6 +18,8 @@ wine-staging (1.7.44) UNRELEASED; urgency=low * Added patch to output winedbg system information also to the terminal, not only to dialog. * Added patch to allow hiding wine version information from applications. + * Added patch to fix scaling behaviour of images and mipmap levels in + IDirect3DTexture2_Load. * Removed patch to reset device state in SysKeyboard*Impl_Acquire (accepted upstream). * Removed patch to avoid creating thread queues for foreign threads in diff --git a/patches/ddraw-IDirect3DTexture2_Load/0001-ddraw-Allow-size-and-format-conversions-in-IDirect3D.patch b/patches/ddraw-IDirect3DTexture2_Load/0001-ddraw-Allow-size-and-format-conversions-in-IDirect3D.patch new file mode 100644 index 00000000..56ec51bc --- /dev/null +++ b/patches/ddraw-IDirect3DTexture2_Load/0001-ddraw-Allow-size-and-format-conversions-in-IDirect3D.patch @@ -0,0 +1,204 @@ +From 3e9c3ba84739fdd41205e1dd4ea8ad686871defb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sat, 30 May 2015 02:55:03 +0200 +Subject: ddraw: Allow size and format conversions in IDirect3DTexture2::Load. + +--- + dlls/ddraw/surface.c | 147 ++++++++++++++++++++++++++------------------------- + 1 file changed, 76 insertions(+), 71 deletions(-) + +diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c +index f716cfc..f3bea20 100644 +--- a/dlls/ddraw/surface.c ++++ b/dlls/ddraw/surface.c +@@ -5048,6 +5048,46 @@ static struct ddraw_surface *get_sub_mimaplevel(struct ddraw_surface *surface) + return impl_from_IDirectDrawSurface7(next_level); + } + ++static BOOL compare_format(DDPIXELFORMAT *format1, DDPIXELFORMAT *format2) ++{ ++ if ((format1->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_FOURCC)) != ++ (format2->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_FOURCC))) ++ return FALSE; ++ ++ if (format1->dwFlags & (DDPF_RGB|DDPF_YUV)) ++ { ++ if (!(format1->dwFlags & DDPF_ALPHA)) ++ { ++ /* The RGB and YUV bits are stored in the same fields */ ++ if (format1->u1.dwRGBBitCount != format2->u1.dwRGBBitCount) ++ return FALSE; ++ ++ if (format1->u2.dwRBitMask != format2->u2.dwRBitMask) ++ return FALSE; ++ ++ if (format1->u3.dwGBitMask != format2->u3.dwGBitMask) ++ return FALSE; ++ ++ if (format1->u4.dwBBitMask != format2->u4.dwBBitMask) ++ return FALSE; ++ } ++ ++ if (format1->dwFlags & (DDPF_ALPHAPIXELS | DDPF_ALPHA)) ++ { ++ if (format1->u5.dwRGBAlphaBitMask != format2->u5.dwRGBAlphaBitMask) ++ return FALSE; ++ } ++ } ++ ++ if (format1->dwFlags & DDPF_FOURCC) ++ { ++ if (format1->dwFourCC != format2->dwFourCC) ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ + /***************************************************************************** + * IDirect3DTexture2::Load + * +@@ -5081,91 +5121,57 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu + + wined3d_mutex_lock(); + +- if (((src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) +- != (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)) +- || (src_surface->surface_desc.u2.dwMipMapCount != dst_surface->surface_desc.u2.dwMipMapCount)) +- { +- ERR("Trying to load surfaces with different mip-map counts.\n"); +- } +- + for (;;) + { +- struct ddraw_palette *dst_pal, *src_pal; +- DDSURFACEDESC *src_desc, *dst_desc; ++ DDSURFACEDESC *src_desc = (DDSURFACEDESC *)&src_surface->surface_desc; + + TRACE("Copying surface %p to surface %p (mipmap level %d).\n", + src_surface, dst_surface, src_surface->mipmap_level); + +- /* Suppress the ALLOCONLOAD flag */ +- dst_surface->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD; +- +- /* Get the palettes */ +- dst_pal = dst_surface->palette; +- src_pal = src_surface->palette; +- +- if (src_pal) ++ if (compare_format(&src_surface->surface_desc.u4.ddpfPixelFormat, ++ &dst_surface->surface_desc.u4.ddpfPixelFormat)) + { +- PALETTEENTRY palent[256]; ++ struct ddraw_palette *dst_pal, *src_pal; + +- if (!dst_pal) +- { +- wined3d_mutex_unlock(); +- return DDERR_NOPALETTEATTACHED; +- } +- IDirectDrawPalette_GetEntries(&src_pal->IDirectDrawPalette_iface, 0, 0, 256, palent); +- IDirectDrawPalette_SetEntries(&dst_pal->IDirectDrawPalette_iface, 0, 0, 256, palent); +- } ++ /* Get the palettes */ ++ dst_pal = dst_surface->palette; ++ src_pal = src_surface->palette; + +- /* Copy one surface on the other */ +- dst_desc = (DDSURFACEDESC *)&(dst_surface->surface_desc); +- src_desc = (DDSURFACEDESC *)&(src_surface->surface_desc); ++ if (src_pal) ++ { ++ PALETTEENTRY palent[256]; + +- if ((src_desc->dwWidth != dst_desc->dwWidth) || (src_desc->dwHeight != dst_desc->dwHeight)) +- { +- /* Should also check for same pixel format, u1.lPitch, ... */ +- ERR("Error in surface sizes.\n"); +- wined3d_mutex_unlock(); +- return D3DERR_TEXTURE_LOAD_FAILED; +- } +- else +- { +- struct wined3d_map_desc src_map_desc, dst_map_desc; ++ if (!dst_pal) ++ { ++ wined3d_mutex_unlock(); ++ return DDERR_NOPALETTEATTACHED; ++ } ++ IDirectDrawPalette_GetEntries(&src_pal->IDirectDrawPalette_iface, 0, 0, 256, palent); ++ IDirectDrawPalette_SetEntries(&dst_pal->IDirectDrawPalette_iface, 0, 0, 256, palent); ++ } + +- /* Copy the src blit color key if the source has one, don't erase +- * the destination's ckey if the source has none */ + if (src_desc->dwFlags & DDSD_CKSRCBLT) + { + IDirectDrawSurface7_SetColorKey(&dst_surface->IDirectDrawSurface7_iface, + DDCKEY_SRCBLT, &src_desc->ddckCKSrcBlt); + } ++ } ++ else ++ { ++ if (src_desc->dwFlags & DDSD_CKSRCBLT) ++ return E_FAIL; ++ } + +- /* Copy the main memory texture into the surface that corresponds +- * to the OpenGL texture object. */ +- +- hr = wined3d_surface_map(src_surface->wined3d_surface, &src_map_desc, NULL, 0); +- if (FAILED(hr)) +- { +- ERR("Failed to lock source surface, hr %#x.\n", hr); +- wined3d_mutex_unlock(); +- return D3DERR_TEXTURE_LOAD_FAILED; +- } +- +- hr = wined3d_surface_map(dst_surface->wined3d_surface, &dst_map_desc, NULL, 0); +- if (FAILED(hr)) +- { +- ERR("Failed to lock destination surface, hr %#x.\n", hr); +- wined3d_surface_unmap(src_surface->wined3d_surface); +- wined3d_mutex_unlock(); +- return D3DERR_TEXTURE_LOAD_FAILED; +- } +- +- if (dst_surface->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) +- memcpy(dst_map_desc.data, src_map_desc.data, src_surface->surface_desc.u1.dwLinearSize); +- else +- memcpy(dst_map_desc.data, src_map_desc.data, src_map_desc.row_pitch * src_desc->dwHeight); ++ /* Suppress the ALLOCONLOAD flag */ ++ dst_surface->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD; + +- wined3d_surface_unmap(src_surface->wined3d_surface); +- wined3d_surface_unmap(dst_surface->wined3d_surface); ++ hr = wined3d_surface_blt(dst_surface->wined3d_surface, NULL, src_surface->wined3d_surface, ++ NULL, 0, NULL, WINED3D_TEXF_LINEAR); ++ if (FAILED(hr)) ++ { ++ ERR("Failed to blit surface, hr %#x.\n", hr); ++ wined3d_mutex_unlock(); ++ return hr; + } + + if (src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) +@@ -5178,12 +5184,11 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu + else + dst_surface = NULL; + ++ if (src_surface && !dst_surface) ++ return DDERR_NOTFOUND; ++ + if (!src_surface || !dst_surface) +- { +- if (src_surface != dst_surface) +- ERR("Loading surface with different mipmap structure.\n"); + break; +- } + } + + wined3d_mutex_unlock(); +-- +2.4.2 + diff --git a/patches/ddraw-IDirect3DTexture2_Load/0002-ddraw-tests-Add-more-tests-for-IDirect3DTexture2-Loa.patch b/patches/ddraw-IDirect3DTexture2_Load/0002-ddraw-tests-Add-more-tests-for-IDirect3DTexture2-Loa.patch new file mode 100644 index 00000000..37891308 --- /dev/null +++ b/patches/ddraw-IDirect3DTexture2_Load/0002-ddraw-tests-Add-more-tests-for-IDirect3DTexture2-Loa.patch @@ -0,0 +1,484 @@ +From 4498bb259a9ab5e5bf6f8a55dc96b6ac24c82e09 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sat, 30 May 2015 02:56:19 +0200 +Subject: ddraw/tests: Add more tests for IDirect3DTexture2::Load. + +--- + dlls/ddraw/tests/d3d.c | 373 ++++++++++++++++++++++++++++++++++++++++++++++ + dlls/ddraw/tests/ddraw2.c | 28 +++- + 2 files changed, 400 insertions(+), 1 deletion(-) + +diff --git a/dlls/ddraw/tests/d3d.c b/dlls/ddraw/tests/d3d.c +index ec4197a..d35d0e0 100644 +--- a/dlls/ddraw/tests/d3d.c ++++ b/dlls/ddraw/tests/d3d.c +@@ -1515,6 +1515,288 @@ static BOOL colortables_check_equality(PALETTEENTRY table1[256], PALETTEENTRY ta + return TRUE; + } + ++static void fill_surface(IDirectDrawSurface *surface, DWORD fillcolor, int level) ++{ ++ DDSCAPS caps = {DDSCAPS_COMPLEX}; ++ IDirectDrawSurface *surface2; ++ DDSURFACEDESC ddsd; ++ DWORD x, y; ++ HRESULT hr; ++ int curlevel = -1; ++ ++ IDirectDrawSurface_AddRef(surface); ++ ++ while (surface) ++ { ++ curlevel++; ++ ++ if (level == -1 || curlevel == level) ++ { ++ memset(&ddsd, 0, sizeof(ddsd)); ++ ddsd.dwSize = sizeof(ddsd); ++ ++ hr = IDirectDrawSurface_Lock(surface, NULL, &ddsd, DDLOCK_WAIT, NULL); ++ ok(hr == DD_OK, "IDirectDrawSurface_Lock returned: %x\n", hr); ++ ++ for (y = 0; y < ddsd.dwHeight; y++) ++ { ++ if (U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount == 32) ++ { ++ DWORD *textureRow = (DWORD *)((char *)ddsd.lpSurface + y * U1(ddsd).lPitch); ++ for (x = 0; x < ddsd.dwWidth; x++) ++ *textureRow++ = fillcolor; ++ } ++ else if (U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount == 16) ++ { ++ WORD *textureRow = (WORD *)((char *)ddsd.lpSurface + y * U1(ddsd).lPitch); ++ for (x = 0; x < ddsd.dwWidth; x++) ++ *textureRow++ = fillcolor; ++ } ++ else ++ { ++ ok(0, "Unsupported format!\n"); ++ break; ++ } ++ } ++ ++ hr = IDirectDrawSurface_Unlock(surface, NULL); ++ ok(hr == DD_OK, "IDirectDrawSurface_Unlock returned: %x\n", hr); ++ } ++ ++ if (level != -1 && curlevel >= level) ++ { ++ IDirectDrawSurface_Release(surface); ++ break; ++ } ++ ++ if (IDirectDrawSurface_GetAttachedSurface(surface, &caps, &surface2) != DD_OK) ++ surface2 = NULL; ++ ++ IDirectDrawSurface_Release(surface); ++ surface = surface2; ++ } ++} ++ ++static BOOL check_surface(IDirectDrawSurface *surface, DWORD fillcolor, int level) ++{ ++ DDSCAPS caps = {DDSCAPS_COMPLEX}; ++ IDirectDrawSurface *surface2; ++ DDSURFACEDESC ddsd; ++ int curlevel = -1; ++ BOOL result = TRUE; ++ DWORD x, y; ++ HRESULT hr; ++ ++ IDirectDrawSurface_AddRef(surface); ++ fillcolor &= 0x00ffffff; ++ ++ while (surface) ++ { ++ curlevel++; ++ ++ if (level == -1 || curlevel == level) ++ { ++ memset(&ddsd, 0, sizeof(ddsd)); ++ ddsd.dwSize = sizeof(ddsd); ++ ++ hr = IDirectDrawSurface_Lock(surface, NULL, &ddsd, DDLOCK_WAIT, NULL); ++ ok(hr == DD_OK, "IDirectDrawSurface_Lock returned: %x\n", hr); ++ ++ for (y = 0; y < ddsd.dwHeight; y++) ++ { ++ if (U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount == 32) ++ { ++ DWORD *textureRow = (DWORD *)((char *)ddsd.lpSurface + y * U1(ddsd).lPitch); ++ for (x = 0; x < ddsd.dwWidth; x++) ++ { ++ if ((*textureRow & 0x00ffffff) != fillcolor) ++ { ++ ok(0, "Expected color %x, got %x at (%d, %d) in level %d\n", ++ fillcolor, *textureRow, x, y, curlevel); ++ result = FALSE; ++ goto end; ++ } ++ textureRow++; ++ } ++ } ++ else if (U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount == 16) ++ { ++ WORD *textureRow = (WORD *)((char *)ddsd.lpSurface + y * U1(ddsd).lPitch); ++ for (x = 0; x < ddsd.dwWidth; x++) ++ { ++ if (*textureRow != fillcolor) ++ { ++ ok(0, "Expected color %x, got %x at (%d, %d) in level %d\n", ++ fillcolor, *textureRow, x, y, curlevel); ++ result = FALSE; ++ goto end; ++ } ++ textureRow++; ++ } ++ } ++ else ++ { ++ ok(0, "Unsupported format!\n"); ++ break; ++ } ++ } ++ ++ end: ++ hr = IDirectDrawSurface_Unlock(surface, NULL); ++ ok(hr == DD_OK, "IDirectDrawSurface_Unlock returned: %x\n", hr); ++ } ++ ++ if (level != -1 && curlevel >= level) ++ { ++ IDirectDrawSurface_Release(surface); ++ break; ++ } ++ ++ if (IDirectDrawSurface_GetAttachedSurface(surface, &caps, &surface2) != DD_OK) ++ surface2 = NULL; ++ ++ IDirectDrawSurface_Release(surface); ++ surface = surface2; ++ } ++ ++ return result; ++} ++ ++struct rgb_format ++{ ++ DWORD dwRGBBitCount; ++ DWORD dwRBitMask; ++ DWORD dwGBitMask; ++ DWORD dwBBitMask; ++}; ++ ++struct mipmap_surface_info ++{ ++ struct rgb_format *format; ++ DWORD width; ++ DWORD height; ++ int levels; ++ DWORD fill[4]; ++}; ++ ++struct rgb_format test_rgb24 = {32, 0x00FF0000, 0x0000FF00, 0x000000FF}; ++struct rgb_format test_rgb16 = {16, 0xf800, 0x07e0, 0x001f}; ++ ++struct ++{ ++ struct mipmap_surface_info surfaces[2]; ++ HRESULT hres; ++ int level_check; ++ DWORD fill_check[4]; ++} ++load_tests[] = ++{ ++ /* different formats */ ++ { {{&test_rgb16, 256, 256, 0, {0x1234}}, ++ {&test_rgb24, 256, 256, 0, {0x789ABC}} }, ++ DD_OK, 1, {0x1045A5}}, ++ { {{&test_rgb24, 256, 256, 0, {0x123456}}, ++ {&test_rgb16, 256, 256, 0, {0x1234}} }, ++ DD_OK, 1, {0x11AA}}, ++ ++ /* different sizes, but no mipmap */ ++ { {{&test_rgb24, 256, 256, 0, {0xff0000}}, ++ {&test_rgb24, 256, 256, 0, {0x00ff00}} }, ++ DD_OK, 1, {0xff0000}}, ++ { {{&test_rgb24, 512, 512, 0, {0x00ff00}}, ++ {&test_rgb24, 256, 256, 0, {0x0000ff}} }, ++ DD_OK, 1, {0x00ff00}}, ++ { {{&test_rgb24, 256, 256, 0, {0x0000ff}}, ++ {&test_rgb24, 512, 512, 0, {0xff0000}} }, ++ DD_OK, 1, {0x0000ff}}, ++ ++ /* different sizes, 1 mapmip level */ ++ { {{&test_rgb24, 256, 256, 1, {0xff0000}}, ++ {&test_rgb24, 256, 256, 1, {0x00ff00}} }, ++ DD_OK, 1, {0xff0000}}, ++ { {{&test_rgb24, 512, 512, 1, {0x00ff00}}, ++ {&test_rgb24, 256, 256, 1, {0x0000ff}} }, ++ DD_OK, 1, {0x00ff00}}, ++ { {{&test_rgb24, 256, 256, 1, {0x0000ff}}, ++ {&test_rgb24, 512, 512, 1, {0xff0000}} }, ++ DD_OK, 1, {0x0000ff}}, ++ ++ /* different sizes, 2 mapmip levels */ ++ { {{&test_rgb24, 256, 256, 2, {0xff0000, 0x0000ff}}, ++ {&test_rgb24, 256, 256, 2, {0x00ff00, 0x00ff00}} }, ++ DD_OK, 2, {0xff0000, 0x0000ff}}, ++ { {{&test_rgb24, 512, 512, 2, {0xff0000, 0x0000ff}}, ++ {&test_rgb24, 256, 256, 2, {0x00ff00, 0x00ff00}} }, ++ DD_OK, 2, {0xff0000, 0x0000ff}}, ++ { {{&test_rgb24, 256, 256, 2, {0xff0000, 0x0000ff}}, ++ {&test_rgb24, 512, 512, 2, {0x00ff00, 0x00ff00}} }, ++ DD_OK, 2, {0xff0000, 0x0000ff}}, ++ ++ /* different sizes, source mipmap levels > dest mimap levels */ ++ { {{&test_rgb24, 256, 256, 3, {0xff0000, 0x0000ff, 0x808080}}, ++ {&test_rgb24, 256, 256, 2, {0x00ff00, 0x00ff00}} }, ++ DDERR_NOTFOUND, 0, {}}, ++ { {{&test_rgb24, 512, 512, 3, {0xff0000, 0x0000ff, 0x808080}}, ++ {&test_rgb24, 256, 256, 2, {0x00ff00, 0x00ff00}} }, ++ DDERR_NOTFOUND, 0, {}}, ++ { {{&test_rgb24, 256, 256, 3, {0xff0000, 0x0000ff, 0x808080}}, ++ {&test_rgb24, 512, 512, 2, {0x00ff00, 0x00ff00}} }, ++ DDERR_NOTFOUND, 0, {}}, ++ ++ /* different sizes, source mipmap levels < dest mipmap levels */ ++ { {{&test_rgb24, 256, 256, 2, {0xff0000, 0x0000ff}}, ++ {&test_rgb24, 256, 256, 3, {0x00ff00, 0x00ff00, 0x808080}} }, ++ DD_OK, 3, {0xff0000, 0x0000ff, 0x808080}}, ++ { {{&test_rgb24, 512, 512, 2, {0xff0000, 0x0000ff}}, ++ {&test_rgb24, 256, 256, 3, {0x00ff00, 0x00ff00, 0x808080}} }, ++ DD_OK, 3, {0xff0000, 0x0000ff, 0x808080}}, ++ { {{&test_rgb24, 256, 256, 2, {0xff0000, 0x0000ff}}, ++ {&test_rgb24, 512, 512, 3, {0x00ff00, 0x00ff00, 0x808080}} }, ++ DD_OK, 3, {0xff0000, 0x0000ff, 0x808080}}, ++ ++ /* different sizes, different formats */ ++ { {{&test_rgb24, 256, 256, 2, {0xff0000, 0x0000ff}}, ++ {&test_rgb16, 256, 256, 2, {0x07e0, 0x07e0}} }, ++ DD_OK, 2, {0xf800, 0x001f}}, ++ { {{&test_rgb24, 512, 512, 2, {0xff0000, 0x0000ff}}, ++ {&test_rgb16, 256, 256, 2, {0x07e0, 0x07e0}} }, ++ DD_OK, 2, {0xf800, 0x001f}}, ++ { {{&test_rgb24, 256, 256, 2, {0xff0000, 0x0000ff}}, ++ {&test_rgb16, 512, 512, 2, {0x07e0, 0x07e0}} }, ++ DD_OK, 2, {0xf800, 0x001f}}, ++ ++ { {{&test_rgb16, 256, 256, 2, {0xf800, 0x001f}}, ++ {&test_rgb24, 256, 256, 2, {0x00ff00, 0x00ff00}} }, ++ DD_OK, 2, {0xff0000, 0x0000ff}}, ++ { {{&test_rgb16, 512, 512, 2, {0xf800, 0x001f}}, ++ {&test_rgb24, 256, 256, 2, {0x00ff00, 0x00ff00}} }, ++ DD_OK, 2, {0xff0000, 0x0000ff}}, ++ { {{&test_rgb16, 256, 256, 2, {0xf800, 0x001f}}, ++ {&test_rgb24, 512, 512, 2, {0x00ff00, 0x00ff00}} }, ++ DD_OK, 2, {0xff0000, 0x0000ff}}, ++ ++ /* different sizes, source mipmap levels < destmipmap levels , different format */ ++ { {{&test_rgb24, 256, 256, 2, {0xff0000, 0x0000ff}}, ++ {&test_rgb16, 256, 256, 3, {0x07e0, 0x07e0, 0x1234}} }, ++ DD_OK, 3, {0xf800, 0x001f, 0x1234}}, ++ { {{&test_rgb24, 512, 512, 2, {0xff0000, 0x0000ff}}, ++ {&test_rgb16, 256, 256, 3, {0x07e0, 0x07e0, 0x1234}} }, ++ DD_OK, 3, {0xf800, 0x001f, 0x1234}}, ++ { {{&test_rgb24, 256, 256, 2, {0xff0000, 0x0000ff}}, ++ {&test_rgb16, 512, 512, 3, {0x07e0, 0x07e0, 0x1234}} }, ++ DD_OK, 3, {0xf800, 0x001f, 0x1234}}, ++ ++ { {{&test_rgb16, 256, 256, 2, {0xf800, 0x001f}}, ++ {&test_rgb24, 256, 256, 3, {0x00ff00, 0x00ff00, 0x808080}} }, ++ DD_OK, 3, {0xff0000, 0x0000ff, 0x808080}}, ++ { {{&test_rgb16, 512, 512, 2, {0xf800, 0x001f}}, ++ {&test_rgb24, 256, 256, 3, {0x00ff00, 0x00ff00, 0x808080}} }, ++ DD_OK, 3, {0xff0000, 0x0000ff, 0x808080}}, ++ { {{&test_rgb16, 256, 256, 2, {0xf800, 0x001f}}, ++ {&test_rgb24, 512, 512, 3, {0x00ff00, 0x00ff00, 0x808080}} }, ++ DD_OK, 3, {0xff0000, 0x0000ff, 0x808080}}, ++}; ++ + /* test palette handling in IDirect3DTexture_Load */ + static void TextureLoadTest(void) + { +@@ -1578,6 +1860,97 @@ static void TextureLoadTest(void) + hr = IDirect3DTexture_Load(Texture2, Texture); + ok(hr == DD_OK, "IDirect3DTexture_Load returned %08x\n", hr); + ++ for (i = 0; i < sizeof(load_tests) / sizeof(load_tests[0]); i++) ++ { ++ IDirectDrawSurface *TexSurfaces[2] = {NULL, NULL}; ++ IDirect3DTexture *Textures[2] = {NULL, NULL}; ++ DDSURFACEDESC ddsd2; ++ int j, k; ++ ++ for (j = 0; j < 2; j++) ++ { ++ memset(&ddsd2, 0, sizeof (ddsd2)); ++ ddsd2.dwSize = sizeof (ddsd2); ++ ddsd2.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT; ++ ddsd2.dwHeight = load_tests[i].surfaces[j].height; ++ ddsd2.dwWidth = load_tests[i].surfaces[j].width; ++ ddsd2.ddsCaps.dwCaps = DDSCAPS_TEXTURE; ++ ddsd2.ddpfPixelFormat.dwSize = sizeof(ddsd2.ddpfPixelFormat); ++ ddsd2.ddpfPixelFormat.dwFlags = DDPF_RGB; ++ U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount = load_tests[i].surfaces[j].format->dwRGBBitCount; ++ U2(U4(ddsd2).ddpfPixelFormat).dwRBitMask = load_tests[i].surfaces[j].format->dwRBitMask; ++ U3(U4(ddsd2).ddpfPixelFormat).dwGBitMask = load_tests[i].surfaces[j].format->dwGBitMask; ++ U4(U4(ddsd2).ddpfPixelFormat).dwBBitMask = load_tests[i].surfaces[j].format->dwBBitMask; ++ ++ if (load_tests[i].surfaces[j].levels) ++ { ++ ddsd2.dwFlags |= DDSD_MIPMAPCOUNT; ++ ddsd2.ddsCaps.dwCaps |= DDSCAPS_MIPMAP | DDSCAPS_COMPLEX; ++ U2(ddsd2).dwMipMapCount = load_tests[i].surfaces[j].levels; ++ } ++ ++ hr = IDirectDraw_CreateSurface(DirectDraw1, &ddsd2, &TexSurfaces[j], NULL); ++ ok(hr == D3D_OK, "IDirectDraw_CreateSurface returned %08x for surface %d in test %d\n", hr, j, i); ++ if (FAILED(hr)) goto next; ++ ++ hr = IDirectDrawSurface_QueryInterface(TexSurfaces[j], &IID_IDirect3DTexture, (void *)&Textures[j]); ++ ok(hr == D3D_OK, "IDirectDrawSurface_QueryInterface returned %08x for surface %d in test %d\n", hr, j, i); ++ if (FAILED(hr)) goto next; ++ ++ if (load_tests[i].surfaces[j].levels) ++ { ++ for (k = 0; k < load_tests[i].surfaces[j].levels; k++) ++ fill_surface(TexSurfaces[j], load_tests[i].surfaces[j].fill[k], k); ++ } ++ else ++ fill_surface(TexSurfaces[j], load_tests[i].surfaces[j].fill[0], -1); ++ } ++ ++ hr = IDirect3DTexture_Load(Textures[1], Textures[0]); ++ ok(hr == load_tests[i].hres, "IDirect3DTexture_Load returned %08x, expected %08x\n", hr, load_tests[i].hres); ++ if (hr != DD_OK) goto next; ++ ++ memset(&ddsd2, 0, sizeof (ddsd2)); ++ ddsd2.dwSize = sizeof(ddsd2); ++ hr = IDirectDrawSurface_GetSurfaceDesc(TexSurfaces[1], &ddsd2); ++ ok(hr == DD_OK, "IDirectDrawSurface_GetSurfaceDesc returned %08x\n", hr); ++ ++ if (load_tests[i].surfaces[1].levels) ++ { ++ ok(U2(ddsd2).dwMipMapCount == load_tests[i].surfaces[1].levels, ++ "Expected %d mipmap levels, got %d in run %d\n", load_tests[i].surfaces[1].levels, ++ U2(ddsd2).dwMipMapCount, i); ++ } ++ ++ for (k = 0; k < load_tests[i].level_check; k++) ++ { ++ if (!check_surface(TexSurfaces[1], load_tests[i].fill_check[k], k)) ++ ok(0, "Check surface failed in test %d\n", i); ++ } ++ ++ ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == load_tests[i].surfaces[1].format->dwRGBBitCount, ++ "Expected %d rgb bits, got %d in run %d\n", load_tests[i].surfaces[1].format->dwRGBBitCount, ++ U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount, i); ++ ++ ok(U1(U4(ddsd2).ddpfPixelFormat).dwRBitMask == load_tests[i].surfaces[1].format->dwRBitMask, ++ "Expected %08x red bits, got %08x in run %d\n", load_tests[i].surfaces[1].format->dwRBitMask, ++ U1(U4(ddsd2).ddpfPixelFormat).dwRBitMask, i); ++ ++ ok(U1(U4(ddsd2).ddpfPixelFormat).dwGBitMask == load_tests[i].surfaces[1].format->dwGBitMask, ++ "Expected %08x green bits, got %08x in run %d\n", load_tests[i].surfaces[1].format->dwGBitMask, ++ U1(U4(ddsd2).ddpfPixelFormat).dwGBitMask, i); ++ ++ ok(U1(U4(ddsd2).ddpfPixelFormat).dwBBitMask == load_tests[i].surfaces[1].format->dwBBitMask, ++ "Expected %08x blue bits, got %08x in run %d\n", load_tests[i].surfaces[1].format->dwBBitMask, ++ U1(U4(ddsd2).ddpfPixelFormat).dwBBitMask, i); ++ ++ next: ++ if (Textures[0]) IDirect3DTexture_Release(Textures[0]); ++ if (TexSurfaces[0]) IDirectDrawSurface_Release(TexSurfaces[0]); ++ if (Textures[1]) IDirect3DTexture_Release(Textures[1]); ++ if (TexSurfaces[1]) IDirectDrawSurface_Release(TexSurfaces[1]); ++ } ++ + for (i = 0; i < 256; i++) { + table1[i].peRed = i; + table1[i].peGreen = i; +diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c +index 0cb1ca4..a2489e4 100644 +--- a/dlls/ddraw/tests/ddraw2.c ++++ b/dlls/ddraw/tests/ddraw2.c +@@ -1121,8 +1121,10 @@ static void test_texture_load_ckey(void) + IDirectDraw2 *ddraw = NULL; + IDirectDrawSurface *src = NULL; + IDirectDrawSurface *dst = NULL; ++ IDirectDrawSurface *dst2 = NULL; + IDirect3DTexture *src_tex = NULL; + IDirect3DTexture *dst_tex = NULL; ++ IDirect3DTexture *dst2_tex = NULL; + DDSURFACEDESC ddsd; + HRESULT hr; + DDCOLORKEY ckey; +@@ -1134,16 +1136,31 @@ static void test_texture_load_ckey(void) + + memset(&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); +- ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; ++ ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT; + ddsd.dwHeight = 128; + ddsd.dwWidth = 128; + ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY; ++ ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat); ++ ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB; ++ U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32; ++ U2(ddsd.ddpfPixelFormat).dwRBitMask = 0x00FF0000; ++ U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x0000FF00; ++ U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x000000FF; ++ + hr = IDirectDraw2_CreateSurface(ddraw, &ddsd, &src, NULL); + ok(SUCCEEDED(hr), "Failed to create source texture, hr %#x.\n", hr); + ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE; + hr = IDirectDraw2_CreateSurface(ddraw, &ddsd, &dst, NULL); + ok(SUCCEEDED(hr), "Failed to create destination texture, hr %#x.\n", hr); + ++ U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 16; ++ U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xf800; ++ U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x07e0; ++ U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x001f; ++ ++ hr = IDirectDraw2_CreateSurface(ddraw, &ddsd, &dst2, NULL); ++ ok(SUCCEEDED(hr), "Failed to create destination texture, hr %#x.\n", hr); ++ + hr = IDirectDrawSurface_QueryInterface(src, &IID_IDirect3DTexture, (void **)&src_tex); + ok(SUCCEEDED(hr) || hr == E_NOINTERFACE, "Failed to get Direct3DTexture interface, hr %#x.\n", hr); + if (FAILED(hr)) +@@ -1154,6 +1171,8 @@ static void test_texture_load_ckey(void) + } + hr = IDirectDrawSurface_QueryInterface(dst, &IID_IDirect3DTexture, (void **)&dst_tex); + ok(SUCCEEDED(hr), "Failed to get Direct3DTexture interface, hr %#x.\n", hr); ++ hr = IDirectDrawSurface_QueryInterface(dst2, &IID_IDirect3DTexture, (void **)&dst2_tex); ++ ok(SUCCEEDED(hr), "Failed to get Direct3DTexture interface, hr %#x.\n", hr); + + /* No surface has a color key */ + hr = IDirect3DTexture_Load(dst_tex, src_tex); +@@ -1182,6 +1201,11 @@ static void test_texture_load_ckey(void) + ok(ckey.dwColorSpaceLowValue == 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey.dwColorSpaceLowValue); + ok(ckey.dwColorSpaceHighValue == 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey.dwColorSpaceHighValue); + ++ /* Source surface has a color key but destination differs in format */ ++ ckey.dwColorSpaceLowValue = ckey.dwColorSpaceHighValue = 0x0; ++ hr = IDirect3DTexture_Load(dst2_tex, src_tex); ++ ok(hr == E_FAIL, "Got unexpected hr %#x, expected E_FAIL.\n", hr); ++ + /* Both surfaces have a color key: Dest ckey is overwritten */ + ckey.dwColorSpaceLowValue = ckey.dwColorSpaceHighValue = 0x000000ff; + hr = IDirectDrawSurface_SetColorKey(dst, DDCKEY_SRCBLT, &ckey); +@@ -1206,8 +1230,10 @@ static void test_texture_load_ckey(void) + ok(ckey.dwColorSpaceHighValue == 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey.dwColorSpaceHighValue); + + done: ++ if (dst2_tex) IDirect3DTexture_Release(dst2_tex); + if (dst_tex) IDirect3DTexture_Release(dst_tex); + if (src_tex) IDirect3DTexture_Release(src_tex); ++ if (dst2) IDirectDrawSurface_Release(dst2); + if (dst) IDirectDrawSurface_Release(dst); + if (src) IDirectDrawSurface_Release(src); + if (ddraw) IDirectDraw2_Release(ddraw); +-- +2.4.2 + diff --git a/patches/ddraw-IDirect3DTexture2_Load/definition b/patches/ddraw-IDirect3DTexture2_Load/definition new file mode 100644 index 00000000..0cf63c87 --- /dev/null +++ b/patches/ddraw-IDirect3DTexture2_Load/definition @@ -0,0 +1 @@ +Fixes: Fix scaling behaviour of images and mipmap levels in IDirect3DTexture2_Load (needed for example by Prezzie Hunt) diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 2eda540c..c5a5e3af 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -111,6 +111,7 @@ patch_enable_all () enable_dbghelp_Debug_Symbols="$1" enable_ddraw_EnumSurfaces="$1" enable_ddraw_Hotpatch="$1" + enable_ddraw_IDirect3DTexture2_Load="$1" enable_ddraw_d3d_execute_buffer="$1" enable_dinput_Events="$1" enable_dmstyle_IPersistStream_ParseReference="$1" @@ -400,6 +401,9 @@ patch_enable () ddraw-Hotpatch) enable_ddraw_Hotpatch="$2" ;; + ddraw-IDirect3DTexture2_Load) + enable_ddraw_IDirect3DTexture2_Load="$2" + ;; ddraw-d3d_execute_buffer) enable_ddraw_d3d_execute_buffer="$2" ;; @@ -2006,23 +2010,6 @@ if test "$enable_Staging" -eq 1; then ) >> "$patchlist" fi -# Patchset server-Misc_ACL -# | -# | This patchset fixes the following Wine bugs: -# | * [#15980] GetSecurityInfo returns NULL DACL for process object -# | -# | Modified files: -# | * dlls/advapi32/tests/security.c, server/process.c, server/security.h, server/token.c -# | -if test "$enable_server_Misc_ACL" -eq 1; then - patch_apply server-Misc_ACL/0001-server-Add-default-security-descriptor-ownership-for.patch - patch_apply server-Misc_ACL/0002-server-Add-default-security-descriptor-DACL-for-proc.patch - ( - echo '+ { "Erich E. Hoover", "server: Add default security descriptor ownership for processes.", 1 },'; - echo '+ { "Erich E. Hoover", "server: Add default security descriptor DACL for processes.", 1 },'; - ) >> "$patchlist" -fi - # Patchset server-CreateProcess_ACLs # | # | This patchset fixes the following Wine bugs: @@ -2042,6 +2029,23 @@ if test "$enable_server_CreateProcess_ACLs" -eq 1; then ) >> "$patchlist" fi +# Patchset server-Misc_ACL +# | +# | This patchset fixes the following Wine bugs: +# | * [#15980] GetSecurityInfo returns NULL DACL for process object +# | +# | Modified files: +# | * dlls/advapi32/tests/security.c, server/process.c, server/security.h, server/token.c +# | +if test "$enable_server_Misc_ACL" -eq 1; then + patch_apply server-Misc_ACL/0001-server-Add-default-security-descriptor-ownership-for.patch + patch_apply server-Misc_ACL/0002-server-Add-default-security-descriptor-DACL-for-proc.patch + ( + echo '+ { "Erich E. Hoover", "server: Add default security descriptor ownership for processes.", 1 },'; + echo '+ { "Erich E. Hoover", "server: Add default security descriptor DACL for processes.", 1 },'; + ) >> "$patchlist" +fi + # Patchset advapi32-LsaLookupSids # | # | Modified files: @@ -2533,6 +2537,20 @@ if test "$enable_ddraw_Hotpatch" -eq 1; then ) >> "$patchlist" fi +# Patchset ddraw-IDirect3DTexture2_Load +# | +# | Modified files: +# | * dlls/ddraw/surface.c, dlls/ddraw/tests/d3d.c, dlls/ddraw/tests/ddraw2.c +# | +if test "$enable_ddraw_IDirect3DTexture2_Load" -eq 1; then + patch_apply ddraw-IDirect3DTexture2_Load/0001-ddraw-Allow-size-and-format-conversions-in-IDirect3D.patch + patch_apply ddraw-IDirect3DTexture2_Load/0002-ddraw-tests-Add-more-tests-for-IDirect3DTexture2-Loa.patch + ( + echo '+ { "Michael Müller", "ddraw: Allow size and format conversions in IDirect3DTexture2::Load.", 1 },'; + echo '+ { "Michael Müller", "ddraw/tests: Add more tests for IDirect3DTexture2::Load.", 1 },'; + ) >> "$patchlist" +fi + # Patchset ddraw-d3d_execute_buffer # | # | Modified files: