1
0
mirror of https://github.com/narzoul/DDrawCompat synced 2024-12-30 08:55:36 +01:00

Always wait for flip before Blt/Lock

Returning DDERR_WASSTILLDRAWING interferes with rendering in Lego Island.
Viewport clear should wait for flip, but it's internally buffered by ddraw
and flushed during Blt, which didn't happen because of Blt failing early.
This commit is contained in:
narzoul 2021-11-01 16:14:07 +01:00
parent 67f38479b7
commit b878028748
6 changed files with 8 additions and 81 deletions

View File

@ -58,10 +58,8 @@ namespace
SET_COMPAT_METHOD(Blt);
SET_COMPAT_METHOD(BltFast);
SET_COMPAT_METHOD(Flip);
SET_COMPAT_METHOD(GetBltStatus);
SET_COMPAT_METHOD(GetCaps);
SET_COMPAT_METHOD(GetDC);
SET_COMPAT_METHOD(GetFlipStatus);
SET_COMPAT_METHOD(GetSurfaceDesc);
SET_COMPAT_METHOD(IsLost);
SET_COMPAT_METHOD(Lock);

View File

@ -317,7 +317,6 @@ namespace DDraw
updateNow(PrimarySurface::getPrimary(), flipInterval);
}
g_flipEndVsyncCount = D3dDdi::KernelModeThunks::getVsyncCounter() + flipInterval;
g_presentEndVsyncCount = g_flipEndVsyncCount;
if (0 != flipInterval)
{
@ -424,7 +423,7 @@ namespace DDraw
}
}
bool RealPrimarySurface::waitForFlip(Surface* surface, bool wait)
bool RealPrimarySurface::waitForFlip(Surface* surface)
{
auto primary(DDraw::PrimarySurface::getPrimary());
if (!surface || !primary ||
@ -434,11 +433,6 @@ namespace DDraw
return true;
}
if (!wait)
{
return !isFlipPending();
}
D3dDdi::KernelModeThunks::waitForVsyncCounter(g_flipEndVsyncCount);
return true;
}

View File

@ -28,6 +28,6 @@ namespace DDraw
static void scheduleUpdate();
static HRESULT setGammaRamp(DDGAMMARAMP* rampData);
static void update();
static bool waitForFlip(Surface* surface, bool wait = true);
static bool waitForFlip(Surface* surface);
};
}

View File

@ -120,11 +120,7 @@ namespace DDraw
template <typename TSurface>
HRESULT PrimarySurfaceImpl<TSurface>::Flip(TSurface* This, TSurface* lpDDSurfaceTargetOverride, DWORD dwFlags)
{
if (!waitForFlip(This, dwFlags, DDFLIP_WAIT, DDFLIP_DONOTWAIT))
{
return DDERR_WASSTILLDRAWING;
}
DDraw::RealPrimarySurface::waitForFlip(m_data);
auto surfaceTargetOverride(CompatPtr<TSurface>::from(lpDDSurfaceTargetOverride));
const bool isFlipEmulated = 0 != (PrimarySurface::getOrigCaps() & DDSCAPS_SYSTEMMEMORY);
if (isFlipEmulated)

View File

@ -9,15 +9,6 @@
#include <DDraw/Surfaces/SurfaceImpl.h>
#include <Dll/Dll.h>
namespace
{
void* getSurface7VtablePtr(IUnknown* surface)
{
static void* vtable = CompatPtr<IDirectDrawSurface7>::from(surface).get()->lpVtbl;
return vtable;
}
}
namespace DDraw
{
template <typename TSurface>
@ -36,10 +27,7 @@ namespace DDraw
TSurface* This, LPRECT lpDestRect, TSurface* lpDDSrcSurface, LPRECT lpSrcRect,
DWORD dwFlags, LPDDBLTFX lpDDBltFx)
{
if (!waitForFlip(This, dwFlags, DDBLT_WAIT, DDBLT_DONOTWAIT))
{
return DDERR_WASSTILLDRAWING;
}
RealPrimarySurface::waitForFlip(m_data);
DirectDrawClipper::update();
return getOrigVtable(This).Blt(This, lpDestRect, lpDDSrcSurface, lpSrcRect, dwFlags, lpDDBltFx);
}
@ -48,10 +36,7 @@ namespace DDraw
HRESULT SurfaceImpl<TSurface>::BltFast(
TSurface* This, DWORD dwX, DWORD dwY, TSurface* lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans)
{
if (!waitForFlip(This, dwTrans, DDBLTFAST_WAIT, DDBLTFAST_DONOTWAIT))
{
return DDERR_WASSTILLDRAWING;
}
RealPrimarySurface::waitForFlip(m_data);
return getOrigVtable(This).BltFast(This, dwX, dwY, lpDDSrcSurface, lpSrcRect, dwTrans);
}
@ -61,21 +46,6 @@ namespace DDraw
return getOrigVtable(This).Flip(This, lpDDSurfaceTargetOverride, dwFlags);
}
template <typename TSurface>
HRESULT SurfaceImpl<TSurface>::GetBltStatus(TSurface* This, DWORD dwFlags)
{
HRESULT result = getOrigVtable(This).GetBltStatus(This, dwFlags);
if (SUCCEEDED(result) && (dwFlags & DDGBS_CANBLT))
{
const bool wait = false;
if (!RealPrimarySurface::waitForFlip(m_data, wait))
{
return DDERR_WASSTILLDRAWING;
}
}
return result;
}
template <typename TSurface>
HRESULT SurfaceImpl<TSurface>::GetCaps(TSurface* This, TDdsCaps* lpDDSCaps)
{
@ -90,30 +60,15 @@ namespace DDraw
template <typename TSurface>
HRESULT SurfaceImpl<TSurface>::GetDC(TSurface* This, HDC* lphDC)
{
RealPrimarySurface::waitForFlip(m_data);
HRESULT result = getOrigVtable(This).GetDC(This, lphDC);
if (SUCCEEDED(result))
{
RealPrimarySurface::waitForFlip(m_data);
Dll::g_origProcs.ReleaseDDThreadLock();
}
return result;
}
template <typename TSurface>
HRESULT SurfaceImpl<TSurface>::GetFlipStatus(TSurface* This, DWORD dwFlags)
{
HRESULT result = getOrigVtable(This).GetFlipStatus(This, dwFlags);
if (SUCCEEDED(result))
{
const bool wait = false;
if (!RealPrimarySurface::waitForFlip(m_data, wait))
{
return DDERR_WASSTILLDRAWING;
}
}
return result;
}
template <typename TSurface>
HRESULT SurfaceImpl<TSurface>::GetSurfaceDesc(TSurface* This, TSurfaceDesc* lpDDSurfaceDesc)
{
@ -142,11 +97,7 @@ namespace DDraw
TSurface* This, LPRECT lpDestRect, TSurfaceDesc* lpDDSurfaceDesc,
DWORD dwFlags, HANDLE hEvent)
{
if (!waitForFlip(This, dwFlags, DDLOCK_WAIT, DDLOCK_DONOTWAIT))
{
return DDERR_WASSTILLDRAWING;
}
RealPrimarySurface::waitForFlip(m_data);
HRESULT result = getOrigVtable(This).Lock(This, lpDestRect, lpDDSurfaceDesc, dwFlags, hEvent);
if (SUCCEEDED(result))
{
@ -235,14 +186,6 @@ namespace DDraw
}
}
template <typename TSurface>
bool SurfaceImpl<TSurface>::waitForFlip(TSurface* This, DWORD flags, DWORD waitFlag, DWORD doNotWaitFlag)
{
const bool wait = (flags & waitFlag) || !(flags & doNotWaitFlag) &&
getSurface7VtablePtr(reinterpret_cast<IUnknown*>(This)) == This->lpVtbl;
return DDraw::RealPrimarySurface::waitForFlip(m_data, wait);
}
template SurfaceImpl<IDirectDrawSurface>;
template SurfaceImpl<IDirectDrawSurface2>;
template SurfaceImpl<IDirectDrawSurface3>;

View File

@ -27,10 +27,8 @@ namespace DDraw
virtual HRESULT BltFast(TSurface* This, DWORD dwX, DWORD dwY,
TSurface* lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans);
virtual HRESULT Flip(TSurface* This, TSurface* lpDDSurfaceTargetOverride, DWORD dwFlags);
virtual HRESULT GetBltStatus(TSurface* This, DWORD dwFlags);
virtual HRESULT GetCaps(TSurface* This, TDdsCaps* lpDDSCaps);
virtual HRESULT GetDC(TSurface* This, HDC* lphDC);
virtual HRESULT GetFlipStatus(TSurface* This, DWORD dwFlags);
virtual HRESULT GetSurfaceDesc(TSurface* This, TSurfaceDesc* lpDDSurfaceDesc);
virtual HRESULT IsLost(TSurface* This);
virtual HRESULT Lock(TSurface* This, LPRECT lpDestRect, TSurfaceDesc* lpDDSurfaceDesc,
@ -43,11 +41,9 @@ namespace DDraw
virtual HRESULT Unlock(TSurface* This, TUnlockParam lpRect);
protected:
bool waitForFlip(TSurface* This, DWORD flags, DWORD waitFlag, DWORD doNotWaitFlag);
Surface* m_data;
private:
void restoreOrigCaps(DWORD& caps);
Surface* m_data;
};
}