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.
-- v3: gdi.exe16: Fix some incorrect usage of NtGdiDdDDICreateDCFromMemory. winex11: Fix some incorrect usage of NtGdiDdDDICreateDCFromMemory. winex11: Wrap more window surface formats with NtGdiDdDDICreateDCFromMemory.
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 | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c index d7d5c93ea64..e1a05cf612b 100644 --- a/dlls/winex11.drv/bitblt.c +++ b/dlls/winex11.drv/bitblt.c @@ -2067,7 +2067,7 @@ struct window_surface *create_surface( HWND hwnd, Window window, const XVisualIn D3DDDIFORMAT d3d_format; HBITMAP bitmap = 0; BOOL byteswap; - UINT size; + UINT size, status;
memset( info, 0, sizeof(*info) ); info->bmiHeader.biSize = sizeof(info->bmiHeader); @@ -2082,23 +2082,29 @@ struct window_surface *create_surface( HWND hwnd, Window window, const XVisualIn if (!(image = x11drv_image_create( info, vis ))) return NULL;
/* wrap the XImage data in a HBITMAP if we can write to the surface pixels directly */ - if (!(byteswap = image_needs_byteswap( image->ximage, is_r8g8b8( vis ), info->bmiHeader.biBitCount )) && - info->bmiHeader.biBitCount > 8 && (d3d_format = get_dib_d3dddifmt( info ))) + if ((byteswap = image_needs_byteswap( image->ximage, is_r8g8b8( vis ), info->bmiHeader.biBitCount )) || + info->bmiHeader.biBitCount <= 8 || !(d3d_format = get_dib_d3dddifmt( info ))) + WARN( "Cannot use direct rendering, falling back to copies\n" ); + else { 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 )) + if ((status = NtGdiDdDDICreateDCFromMemory( &desc ))) + ERR( "Failed to create HBITMAP falling back to copies, status %#x\n", status ); + else { 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 | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/dlls/gdi.exe16/gdi.c b/dlls/gdi.exe16/gdi.c index c634f0739c7..e81d335f127 100644 --- a/dlls/gdi.exe16/gdi.c +++ b/dlls/gdi.exe16/gdi.c @@ -1189,10 +1189,11 @@ 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; + UINT status; int color;
if (info->bmiHeader.biBitCount <= 8) @@ -1230,7 +1231,14 @@ 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 ((status = NtGdiDdDDICreateDCFromMemory( &desc ))) + { + NtGdiDeleteObjectApp( desc.hDeviceDc ); + ERR( "Failed to create HBITMAP over memory, status %#x\n", status ); + return 0; + } + NtGdiDeleteObjectApp( desc.hDeviceDc );
if ((bitmap = HeapAlloc( GetProcessHeap(), 0, sizeof(*bitmap) ))) {