[PATCH 0/1] MR11090: ddraw: Cap reported VRAM size at ~2GB.
From: Paul Gofman <pgofman@codeweavers.com> --- dlls/ddraw/ddraw.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index c4ce81234bc..dabd9ed30d9 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -1973,9 +1973,11 @@ static HRESULT WINAPI ddraw1_GetVerticalBlankStatus(IDirectDraw *iface, BOOL *st static HRESULT WINAPI ddraw7_GetAvailableVidMem(IDirectDraw7 *iface, DDSCAPS2 *caps, DWORD *total, DWORD *free) { - unsigned int framebuffer_size, total_vidmem, free_vidmem; + unsigned int framebuffer_size, total_vidmem = 0, free_vidmem; struct ddraw *ddraw = impl_from_IDirectDraw7(iface); + struct wined3d_adapter_identifier desc = {0}; struct wined3d_display_mode mode; + SIZE_T used_vidmem = 0; HRESULT hr = DD_OK; TRACE("iface %p, caps %p, total %p, free %p.\n", iface, caps, total, free); @@ -2008,19 +2010,28 @@ static HRESULT WINAPI ddraw7_GetAvailableVidMem(IDirectDraw7 *iface, DDSCAPS2 *c mode.format_id, mode.width); framebuffer_size *= mode.height; + if (free || total) + { + if (FAILED(hr = wined3d_adapter_get_identifier(ddraw->wined3d_adapter, 0, &desc))) + { + WARN("wined3d_adapter_get_identifier failed.\n"); + wined3d_mutex_unlock(); + return hr; + } + total_vidmem = min(0x7ffff000, desc.video_memory); + } + if (free) { free_vidmem = wined3d_device_get_available_texture_mem(ddraw->wined3d_device); + used_vidmem = desc.video_memory - free_vidmem; + free_vidmem = total_vidmem > used_vidmem ? total_vidmem - used_vidmem : 0; *free = framebuffer_size > free_vidmem ? 0 : free_vidmem - framebuffer_size; TRACE("Free video memory %#lx.\n", *free); } if (total) { - struct wined3d_adapter_identifier desc = {0}; - - hr = wined3d_adapter_get_identifier(ddraw->wined3d_adapter, 0, &desc); - total_vidmem = min(UINT_MAX, desc.video_memory); *total = framebuffer_size > total_vidmem ? 0 : total_vidmem - framebuffer_size; TRACE("Total video memory %#lx.\n", *total); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11090
That helps Dark Omen (classic) which will use very low resolution textures otherwise on the GPUs where wined3d ends up reporting >2GB of VRAM. It does signed integer comparison on free VRAM size. That previously popped up at least here: https://bugs.winehq.org/show_bug.cgi?id=39878 . There are probably more old ddraw games which could benefit from this. The referenced bug ended up in wined3d workaround but it is only enabled when Windows version is set to XP or older in the prefix. I think doing such a cap in wined3d would be wrong as it is also queried from d3d8 / d3d9 where reporting >2GB of VRAM is beneficial in general. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11090#note_142445
I think this raises two (fairly obvious) questions: - Bug 39878 clearly established that current Windows versions don't do such clamping. Does this application work on current Windows versions? - As you mentioned, we do clamp the reported video memory for older Windows versions. (And IIRC that matches the actual behaviour of those versions.) Why is that not sufficient for this application? -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11090#note_142447
Bug 39878 clearly established that current Windows versions don't do such clamping. Does this application work on current Windows versions?
Yes, current Windows doesn't clamp that. Well, there are few things to this. First, the current Steam release of the game ships dgVoodoo ddraw implementation alongside game which is intentionally broken under Wine (does a stealthy Wine check and then simulates a crash later by adding QPC value to some pointer). Then, with that ddraw.dll removed, the game can still be started on Windows by setting compat option 'start in 640x80 resolution'). The game is basically unplayable this way and exhibits various heavy glitches, while it is still possible to get to the game and observe that the issue concerned here (low textures resolution) is actually not there. That is also affected by D3DDEVCAPS_TEXTURENONLOCALVIDMEM flag in HAL dwDevCaps. When that is set (which happens on Win11 at least on the device it ends up with) it doesn't actually mind GetAvailableVidMem result, even though still queries that. If that is not set (like in our case) >2GB memory gets into signed comparison (and thus is negative) and the game considers there is not enough VRAM for textures of higher resolution.
As you mentioned, we do clamp the reported video memory for older Windows versions. (And IIRC that matches the actual behaviour of those versions.) Why is that not sufficient for this application?
It is not sufficient because obviously the default prefix has newer Windows and the game doesn't work OOTB. Changing it manually is sufficient of course. So yes, WRT this specific game it would be probably possible to explore the life of D3DDEVCAPS_TEXTURENONLOCALVIDMEM, look in more details which device type it ends up with on Windows (it is HAL on Wine), and maybe (not necessarily as it actually might be different for old Windows and present) this specific game can be fixed by sometimes reporting D3DDEVCAPS_TEXTURENONLOCALVIDMEM. If we consider manual tinkering and configuration setting WinXP version also works. I sent this specific patch because I was under impression that we help some range of games in default config this way, while probably nothing benefits from reporting >2GB on ddraw specifically. We preliminary discussed that with Zeb and she wasn't against this approach at once. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11090#note_142448
Then, with that ddraw.dll removed, the game can still be started on Windows by setting compat option 'start in 640x80 resolution'). The game is basically unplayable this way and exhibits various heavy glitches, while it is still possible to get to the game and observe that the issue concerned here (low textures resolution) is actually not there. That is also affected by D3DDEVCAPS_TEXTURENONLOCALVIDMEM flag in HAL dwDevCaps. When that is set (which happens on Win11 at least on the device it ends up with) it doesn't actually mind GetAvailableVidMem result, even though still queries that. If that is not set (like in our case) \>2GB memory gets into signed comparison (and thus is negative) and the game considers there is not enough VRAM for textures of higher resolution.
D3DDEVCAPS_TEXTURENONLOCALVIDMEM seems like something we should be setting, at least for HAL/3D devices. IIRC that's GART/GTT memory.
As you mentioned, we do clamp the reported video memory for older Windows versions. (And IIRC that matches the actual behaviour of those versions.) Why is that not sufficient for this application?
It is not sufficient because obviously the default prefix has newer Windows and the game doesn't work OOTB. Changing it manually is sufficient of course.
Is that something we care about now? Historically we've been happy to put a note in the AppDB along the lines of "Set the Windows version to Windows 98 in winecfg". That's not an uncommon thing to try for games of that era, since those tend to rely on other quirks of Windows 9x as well.
I sent this specific patch because I was under impression that we help some range of games in default config this way, while probably nothing benefits from reporting \>2GB on ddraw specifically. We preliminary discussed that with Zeb and she wasn't against this approach at once.
I'll defer to the maintainer of course, but to me it sounds like this is papering over a different issue. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11090#note_142506
Sure, I understand that this direction might be arguable. There are other ways to help this specific game, I was hoping to help a broader range. The first problem with config option is one first needs to figure out that it is needed for a game, debug it or try every option they are aware of. My reasoning is that in ddraw we stick to old Windows behaviour more often than not as way too many games are broken on up to date Windows now. And AFAIR at times ddraw was strong GPUs with >2GB of VRAM were either non-existent or very rare. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11090#note_142542
participants (3)
-
Henri Verbeet (@hverbeet) -
Paul Gofman -
Paul Gofman (@gofman)