https://git.reactos.org/?p=reactos.git;a=commitdiff;h=67559215608eaf7338cbc…
commit 67559215608eaf7338cbc7002ba3b74bf972a3a4
Author: Simone Mario Lombardo <simonelombardo(a)dismail.de>
AuthorDate: Wed Nov 9 18:44:30 2022 +0100
Commit: GitHub <noreply(a)github.com>
CommitDate: Wed Nov 9 20:44:30 2022 +0300
[DDRAW] Sync the fix for swap_interval from Wine (#4831)
Sync the barebone fix from Wine (wine-7.19-557-g13cc08e32d6):
https://source.winehq.org/git/wine.git/?a=search&h=HEAD&st=grep&…
and
https://source.winehq.org/git/wine.git/blob/13cc08e32d6c04f8f915d07cda39638…
- Added "swap_interval" argument to ddraw_surface_update_frontbuffer()
- Added ddraw_swap_interval_from_flags() function for dispatching
the integer type of required swap interval
- Updated ddraw_surface_update_frontbuffer() function for managing the
swap interval between backbuffer and frontbuffer (and relative flipping)
- Updated the ddraw_surface7_Flip() function for relaying the swap interval
to ddraw_surface_update_frontbuffer() function.
- Added 0 value (as Wine) when the swap interval is not required
This fixes empty white screen issue on rendering because of lacking
swap interval for the software / games that use ddraw.
CORE-18547
---
dll/directx/wine/ddraw/ddraw_private.h | 2 +-
dll/directx/wine/ddraw/palette.c | 2 +-
dll/directx/wine/ddraw/surface.c | 59 +++++++++++++++++++++++++---------
media/doc/WINESYNC.txt | 2 +-
4 files changed, 47 insertions(+), 18 deletions(-)
diff --git a/dll/directx/wine/ddraw/ddraw_private.h
b/dll/directx/wine/ddraw/ddraw_private.h
index cac38c57e92..433bcd34a3d 100644
--- a/dll/directx/wine/ddraw/ddraw_private.h
+++ b/dll/directx/wine/ddraw/ddraw_private.h
@@ -218,7 +218,7 @@ void ddraw_surface_init(struct ddraw_surface *surface, struct ddraw
*ddraw,
struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN;
HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface,
- const RECT *rect, BOOL read) DECLSPEC_HIDDEN;
+ const RECT *rect, BOOL read, unsigned int swap_interval) DECLSPEC_HIDDEN;
static inline struct ddraw_surface *impl_from_IDirect3DTexture(IDirect3DTexture *iface)
{
diff --git a/dll/directx/wine/ddraw/palette.c b/dll/directx/wine/ddraw/palette.c
index 5148832cab6..87aec96443a 100644
--- a/dll/directx/wine/ddraw/palette.c
+++ b/dll/directx/wine/ddraw/palette.c
@@ -176,7 +176,7 @@ static HRESULT WINAPI ddraw_palette_SetEntries(IDirectDrawPalette
*iface,
hr = wined3d_palette_set_entries(palette->wined3d_palette, flags, start, count,
entries);
if (SUCCEEDED(hr) && palette->flags & DDPCAPS_PRIMARYSURFACE)
- ddraw_surface_update_frontbuffer(palette->ddraw->primary, NULL, FALSE);
+ ddraw_surface_update_frontbuffer(palette->ddraw->primary, NULL, FALSE, 0);
wined3d_mutex_unlock();
diff --git a/dll/directx/wine/ddraw/surface.c b/dll/directx/wine/ddraw/surface.c
index 11a0e6ba8db..c26cc76baab 100644
--- a/dll/directx/wine/ddraw/surface.c
+++ b/dll/directx/wine/ddraw/surface.c
@@ -40,8 +40,9 @@ static inline struct ddraw_surface
*impl_from_IDirectDrawGammaControl(IDirectDra
* applications from drawing to the screen while we've locked the frontbuffer.
* We'd like to do this in wined3d instead, but for that to work wined3d needs
* to support windowless rendering first. */
-HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, const RECT *rect,
BOOL read)
+HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, const RECT *rect,
BOOL read, unsigned int swap_interval)
{
+ struct wined3d_texture *dst_texture;
struct ddraw *ddraw = surface->ddraw;
HDC surface_dc, screen_dc;
int x, y, w, h;
@@ -70,8 +71,18 @@ HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface,
const RE
if (read)
return DD_OK;
- return wined3d_texture_blt(ddraw->wined3d_frontbuffer, 0, rect,
- surface->wined3d_texture, surface->sub_resource_idx, rect, 0, NULL,
WINED3D_TEXF_POINT);
+ if (swap_interval)
+ dst_texture = wined3d_swapchain_get_back_buffer(ddraw->wined3d_swapchain,
0);
+ else
+ dst_texture = ddraw->wined3d_frontbuffer;
+
+ if (SUCCEEDED(hr = wined3d_texture_blt(dst_texture, 0, rect,
+ surface->wined3d_texture, surface->sub_resource_idx, rect, 0, NULL,
WINED3D_TEXF_POINT))){
+ hr = wined3d_swapchain_present(ddraw->wined3d_swapchain, rect, rect, NULL,
swap_interval, 0);
+ ddraw->flags |= DDRAW_GDI_FLIP;
+ }
+
+ return hr;
}
if (FAILED(hr = wined3d_texture_get_dc(surface->wined3d_texture,
surface->sub_resource_idx, &surface_dc)))
@@ -474,7 +485,7 @@ static HRESULT ddraw_surface_set_palette(struct ddraw_surface
*surface, IDirectD
palette_impl->flags |= DDPCAPS_PRIMARYSURFACE;
wined3d_swapchain_set_palette(surface->ddraw->wined3d_swapchain,
palette_impl ? palette_impl->wined3d_palette : NULL);
- ddraw_surface_update_frontbuffer(surface, NULL, FALSE);
+ ddraw_surface_update_frontbuffer(surface, NULL, FALSE, 0);
}
if (palette_impl)
IDirectDrawPalette_AddRef(&palette_impl->IDirectDrawPalette_iface);
@@ -990,7 +1001,7 @@ static HRESULT surface_lock(struct ddraw_surface *surface,
}
if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
- hr = ddraw_surface_update_frontbuffer(surface, rect, TRUE);
+ hr = ddraw_surface_update_frontbuffer(surface, rect, TRUE, 0);
if (SUCCEEDED(hr))
hr =
wined3d_resource_map(wined3d_texture_get_resource(surface->wined3d_texture),
surface->sub_resource_idx, &map_desc, rect ? &box : NULL,
@@ -1179,7 +1190,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH
ddraw_surface7_Unlock(IDirectDrawSurface
wined3d_mutex_lock();
hr =
wined3d_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture),
surface->sub_resource_idx);
if (SUCCEEDED(hr) && surface->surface_desc.ddsCaps.dwCaps &
DDSCAPS_PRIMARYSURFACE)
- hr = ddraw_surface_update_frontbuffer(surface,
&surface->ddraw->primary_lock, FALSE);
+ hr = ddraw_surface_update_frontbuffer(surface,
&surface->ddraw->primary_lock, FALSE, 0);
wined3d_mutex_unlock();
return hr;
@@ -1224,6 +1235,24 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH
ddraw_surface1_Unlock(IDirectDrawSurface
return ddraw_surface7_Unlock(&surface->IDirectDrawSurface7_iface, NULL);
}
+static unsigned int ddraw_swap_interval_from_flags(DWORD flags)
+{
+ if (flags & DDFLIP_NOVSYNC)
+ return 0;
+
+ switch (flags & (DDFLIP_INTERVAL2 | DDFLIP_INTERVAL3 | DDFLIP_INTERVAL4))
+ {
+ case DDFLIP_INTERVAL2:
+ return 2;
+ case DDFLIP_INTERVAL3:
+ return 3;
+ case DDFLIP_INTERVAL4:
+ return 4;
+ default:
+ return 1;
+ }
+}
+
static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Flip(IDirectDrawSurface7 *iface,
IDirectDrawSurface7 *src, DWORD flags)
{
@@ -1347,7 +1376,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH
ddraw_surface7_Flip(IDirectDrawSurface7
}
if (dst_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
- hr = ddraw_surface_update_frontbuffer(dst_impl, NULL, FALSE);
+ hr = ddraw_surface_update_frontbuffer(dst_impl, NULL,
FALSE,ddraw_swap_interval_from_flags(flags));
else
hr = DD_OK;
@@ -1488,11 +1517,11 @@ static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface
*dst_surface, cons
if (!dst_surface->clipper)
{
if (src_surface && src_surface->surface_desc.ddsCaps.dwCaps &
DDSCAPS_PRIMARYSURFACE)
- hr = ddraw_surface_update_frontbuffer(src_surface, &src_rect, TRUE);
+ hr = ddraw_surface_update_frontbuffer(src_surface, &src_rect, TRUE, 0);
if (SUCCEEDED(hr))
hr = ddraw_surface_blt(dst_surface, &dst_rect, src_surface,
&src_rect, flags, fill_colour, fx, filter);
if (SUCCEEDED(hr) && (dst_surface->surface_desc.ddsCaps.dwCaps &
DDSCAPS_PRIMARYSURFACE))
- hr = ddraw_surface_update_frontbuffer(dst_surface, &dst_rect, FALSE);
+ hr = ddraw_surface_update_frontbuffer(dst_surface, &dst_rect, FALSE, 0);
return hr;
}
@@ -1535,7 +1564,7 @@ static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface
*dst_surface, cons
if (src_surface->surface_desc.ddsCaps.dwCaps &
DDSCAPS_PRIMARYSURFACE)
{
- if (FAILED(hr = ddraw_surface_update_frontbuffer(src_surface,
&src_rect_clipped, TRUE)))
+ if (FAILED(hr = ddraw_surface_update_frontbuffer(src_surface,
&src_rect_clipped, TRUE, 0)))
break;
}
}
@@ -1546,7 +1575,7 @@ static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface
*dst_surface, cons
if (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
{
- if (FAILED(hr = ddraw_surface_update_frontbuffer(dst_surface,
&clip_rect[i], FALSE)))
+ if (FAILED(hr = ddraw_surface_update_frontbuffer(dst_surface,
&clip_rect[i], FALSE, 0)))
break;
}
}
@@ -2219,7 +2248,7 @@ static HRESULT WINAPI ddraw_surface7_GetDC(IDirectDrawSurface7
*iface, HDC *dc)
if (surface->dc)
hr = DDERR_DCALREADYCREATED;
else if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
- hr = ddraw_surface_update_frontbuffer(surface, NULL, TRUE);
+ hr = ddraw_surface_update_frontbuffer(surface, NULL, TRUE, 0);
if (SUCCEEDED(hr))
hr = wined3d_texture_get_dc(surface->wined3d_texture,
surface->sub_resource_idx, dc);
@@ -2323,7 +2352,7 @@ static HRESULT WINAPI ddraw_surface7_ReleaseDC(IDirectDrawSurface7
*iface, HDC h
{
surface->dc = NULL;
if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
- hr = ddraw_surface_update_frontbuffer(surface, NULL, FALSE);
+ hr = ddraw_surface_update_frontbuffer(surface, NULL, FALSE, 0);
}
wined3d_mutex_unlock();
@@ -4291,12 +4320,12 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH
ddraw_surface7_BltFast(IDirectDrawSurfac
}
if (src_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
- hr = ddraw_surface_update_frontbuffer(src_impl, src_rect, TRUE);
+ hr = ddraw_surface_update_frontbuffer(src_impl, src_rect, TRUE, 0);
if (SUCCEEDED(hr))
hr = wined3d_texture_blt(dst_impl->wined3d_texture,
dst_impl->sub_resource_idx, &dst_rect,
src_impl->wined3d_texture, src_impl->sub_resource_idx, src_rect,
flags, NULL, WINED3D_TEXF_POINT);
if (SUCCEEDED(hr) && (dst_impl->surface_desc.ddsCaps.dwCaps &
DDSCAPS_PRIMARYSURFACE))
- hr = ddraw_surface_update_frontbuffer(dst_impl, &dst_rect, FALSE);
+ hr = ddraw_surface_update_frontbuffer(dst_impl, &dst_rect, FALSE, 0);
wined3d_mutex_unlock();
switch(hr)
diff --git a/media/doc/WINESYNC.txt b/media/doc/WINESYNC.txt
index 43def4ebffe..cb460336c0d 100644
--- a/media/doc/WINESYNC.txt
+++ b/media/doc/WINESYNC.txt
@@ -28,7 +28,7 @@ dll/directx/wine/d3dcompiler_43 # Synced to WineStaging-4.18
dll/directx/wine/d3drm # Synced to WineStaging-4.18
dll/directx/wine/d3dx9_24 => 43 # Synced to WineStaging-6.0-rc5
dll/directx/wine/d3dxof # Synced to WineStaging-4.18
-dll/directx/wine/ddraw # Synced to WineStaging-3.3
+dll/directx/wine/ddraw # Synced to WineStaging-3.3 (+ partial sync of
ddraw_private.h, palette.c, and surface.c to wine-7.19-557-g13cc08e32d6)
dll/directx/wine/devenum # Synced to WineStaging-4.18
dll/directx/wine/dinput # Synced to WineStaging-4.18
dll/directx/wine/dinput8 # Synced to WineStaging-4.18