Didn't notice that it was failing until I did the same for winemac with https://gitlab.winehq.org/wine/wine/-/merge_requests/5798. It was silently falling back to copies while winemac can't do that.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/bitblt.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c index 8a001606420..d7d5c93ea64 100644 --- a/dlls/winex11.drv/bitblt.c +++ b/dlls/winex11.drv/bitblt.c @@ -1887,10 +1887,22 @@ static UINT get_dib_d3dddifmt( const BITMAPINFO *info ) if (info->bmiHeader.biCompression == BI_BITFIELDS) { DWORD *colors = (DWORD *)info->bmiColors; - if (info->bmiHeader.biBitCount != 16) return D3DDDIFMT_UNKNOWN; - if (colors[0] == 0x0000f800 && colors[1] == 0x000007e0 && colors[2] == 0x0000001f) return D3DDDIFMT_R5G6B5; - if (colors[0] == 0x00007c00 && colors[1] == 0x000003e0 && colors[2] == 0x0000001f) return D3DDDIFMT_A1R5G5B5; - if (colors[0] == 0x00000f00 && colors[1] == 0x000000f0 && colors[2] == 0x0000000f) return D3DDDIFMT_A4R4G4B4; + + if (info->bmiHeader.biBitCount == 16) + { + if (colors[0] == 0x0000f800 && colors[1] == 0x000007e0 && colors[2] == 0x0000001f) return D3DDDIFMT_R5G6B5; + if (colors[0] == 0x00007c00 && colors[1] == 0x000003e0 && colors[2] == 0x0000001f) return D3DDDIFMT_A1R5G5B5; + if (colors[0] == 0x00000f00 && colors[1] == 0x000000f0 && colors[2] == 0x0000000f) return D3DDDIFMT_A4R4G4B4; + } + else if (info->bmiHeader.biBitCount == 24) + { + if (colors[0] == 0x00ff0000 && colors[1] == 0x0000ff00 && colors[2] == 0x000000ff) return D3DDDIFMT_R8G8B8; + } + else if (info->bmiHeader.biBitCount == 32) + { + if (colors[0] == 0x00ff0000 && colors[1] == 0x0000ff00 && colors[2] == 0x000000ff) return D3DDDIFMT_X8R8G8B8; + } + return D3DDDIFMT_UNKNOWN; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/bitblt.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c index d7d5c93ea64..25193d46bb0 100644 --- a/dlls/winex11.drv/bitblt.c +++ b/dlls/winex11.drv/bitblt.c @@ -2088,10 +2088,11 @@ struct window_surface *create_surface( HWND hwnd, Window window, const XVisualIn D3DKMT_CREATEDCFROMMEMORY desc = { .Width = info->bmiHeader.biWidth, - .Height = info->bmiHeader.biHeight, - .Pitch = info->bmiHeader.biWidth * info->bmiHeader.biBitCount / 8, + .Height = abs( info->bmiHeader.biHeight ), + .Pitch = info->bmiHeader.biSizeImage / abs( info->bmiHeader.biHeight ), .Format = d3d_format, .pMemory = image->ximage->data, + .hDeviceDc = NtUserGetDCEx( hwnd, 0, DCX_CACHE | DCX_WINDOW ), };
if (!NtGdiDdDDICreateDCFromMemory( &desc )) @@ -2099,6 +2100,7 @@ struct window_surface *create_surface( HWND hwnd, Window window, const XVisualIn bitmap = desc.hBitmap; NtGdiDeleteObjectApp( desc.hDc ); } + if (desc.hDeviceDc) NtUserReleaseDC( hwnd, desc.hDeviceDc ); }
if (!(surface = calloc( 1, size )))
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/gdi.exe16/gdi.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/dlls/gdi.exe16/gdi.c b/dlls/gdi.exe16/gdi.c index c634f0739c7..f4f1868a81b 100644 --- a/dlls/gdi.exe16/gdi.c +++ b/dlls/gdi.exe16/gdi.c @@ -1189,8 +1189,8 @@ HDC16 WINAPI CreateDC16( LPCSTR driver, LPCSTR device, LPCSTR output, D3DKMT_CREATEDCFROMMEMORY desc = { .Width = info->bmiHeader.biWidth, - .Height = info->bmiHeader.biHeight, - .Pitch = info->bmiHeader.biWidth * info->bmiHeader.biBitCount / 8, + .Height = abs( info->bmiHeader.biHeight ), + .Pitch = info->bmiHeader.biSizeImage / abs( info->bmiHeader.biHeight ), }; struct saved_bitmap *bitmap; int color; @@ -1230,7 +1230,13 @@ HDC16 WINAPI CreateDC16( LPCSTR driver, LPCSTR device, LPCSTR output, desc.pMemory = &info->bmiColors[0]; }
- if (NtGdiDdDDICreateDCFromMemory( &desc )) return 0; + if (!(desc.hDeviceDc = NtGdiCreateCompatibleDC( 0 ))) return 0; + if (NtGdiDdDDICreateDCFromMemory( &desc )) + { + NtGdiDeleteObjectApp( desc.hDeviceDc ); + return 0; + } + NtGdiDeleteObjectApp( desc.hDeviceDc );
if ((bitmap = HeapAlloc( GetProcessHeap(), 0, sizeof(*bitmap) ))) {
OOC: Would it make sense to add some TRACE()s when the slow/copy path is hit? Perhaps WARN even, if it happens rather rarely.
On Thu Jun 6 15:51:26 2024 +0000, Emil Velikov wrote:
OOC: Would it make sense to add some TRACE()s when the slow/copy path is hit? Perhaps WARN even, if it happens rather rarely.
I guess it probably deserves something, but a WARN wouldn't have helped me catching it earlier in this case because they are disabled by default.