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:
parent
67f38479b7
commit
b878028748
@ -58,10 +58,8 @@ namespace
|
|||||||
SET_COMPAT_METHOD(Blt);
|
SET_COMPAT_METHOD(Blt);
|
||||||
SET_COMPAT_METHOD(BltFast);
|
SET_COMPAT_METHOD(BltFast);
|
||||||
SET_COMPAT_METHOD(Flip);
|
SET_COMPAT_METHOD(Flip);
|
||||||
SET_COMPAT_METHOD(GetBltStatus);
|
|
||||||
SET_COMPAT_METHOD(GetCaps);
|
SET_COMPAT_METHOD(GetCaps);
|
||||||
SET_COMPAT_METHOD(GetDC);
|
SET_COMPAT_METHOD(GetDC);
|
||||||
SET_COMPAT_METHOD(GetFlipStatus);
|
|
||||||
SET_COMPAT_METHOD(GetSurfaceDesc);
|
SET_COMPAT_METHOD(GetSurfaceDesc);
|
||||||
SET_COMPAT_METHOD(IsLost);
|
SET_COMPAT_METHOD(IsLost);
|
||||||
SET_COMPAT_METHOD(Lock);
|
SET_COMPAT_METHOD(Lock);
|
||||||
|
@ -317,7 +317,6 @@ namespace DDraw
|
|||||||
updateNow(PrimarySurface::getPrimary(), flipInterval);
|
updateNow(PrimarySurface::getPrimary(), flipInterval);
|
||||||
}
|
}
|
||||||
g_flipEndVsyncCount = D3dDdi::KernelModeThunks::getVsyncCounter() + flipInterval;
|
g_flipEndVsyncCount = D3dDdi::KernelModeThunks::getVsyncCounter() + flipInterval;
|
||||||
g_presentEndVsyncCount = g_flipEndVsyncCount;
|
|
||||||
|
|
||||||
if (0 != flipInterval)
|
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());
|
auto primary(DDraw::PrimarySurface::getPrimary());
|
||||||
if (!surface || !primary ||
|
if (!surface || !primary ||
|
||||||
@ -434,11 +433,6 @@ namespace DDraw
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!wait)
|
|
||||||
{
|
|
||||||
return !isFlipPending();
|
|
||||||
}
|
|
||||||
|
|
||||||
D3dDdi::KernelModeThunks::waitForVsyncCounter(g_flipEndVsyncCount);
|
D3dDdi::KernelModeThunks::waitForVsyncCounter(g_flipEndVsyncCount);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,6 @@ namespace DDraw
|
|||||||
static void scheduleUpdate();
|
static void scheduleUpdate();
|
||||||
static HRESULT setGammaRamp(DDGAMMARAMP* rampData);
|
static HRESULT setGammaRamp(DDGAMMARAMP* rampData);
|
||||||
static void update();
|
static void update();
|
||||||
static bool waitForFlip(Surface* surface, bool wait = true);
|
static bool waitForFlip(Surface* surface);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -120,11 +120,7 @@ namespace DDraw
|
|||||||
template <typename TSurface>
|
template <typename TSurface>
|
||||||
HRESULT PrimarySurfaceImpl<TSurface>::Flip(TSurface* This, TSurface* lpDDSurfaceTargetOverride, DWORD dwFlags)
|
HRESULT PrimarySurfaceImpl<TSurface>::Flip(TSurface* This, TSurface* lpDDSurfaceTargetOverride, DWORD dwFlags)
|
||||||
{
|
{
|
||||||
if (!waitForFlip(This, dwFlags, DDFLIP_WAIT, DDFLIP_DONOTWAIT))
|
DDraw::RealPrimarySurface::waitForFlip(m_data);
|
||||||
{
|
|
||||||
return DDERR_WASSTILLDRAWING;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto surfaceTargetOverride(CompatPtr<TSurface>::from(lpDDSurfaceTargetOverride));
|
auto surfaceTargetOverride(CompatPtr<TSurface>::from(lpDDSurfaceTargetOverride));
|
||||||
const bool isFlipEmulated = 0 != (PrimarySurface::getOrigCaps() & DDSCAPS_SYSTEMMEMORY);
|
const bool isFlipEmulated = 0 != (PrimarySurface::getOrigCaps() & DDSCAPS_SYSTEMMEMORY);
|
||||||
if (isFlipEmulated)
|
if (isFlipEmulated)
|
||||||
|
@ -9,15 +9,6 @@
|
|||||||
#include <DDraw/Surfaces/SurfaceImpl.h>
|
#include <DDraw/Surfaces/SurfaceImpl.h>
|
||||||
#include <Dll/Dll.h>
|
#include <Dll/Dll.h>
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
void* getSurface7VtablePtr(IUnknown* surface)
|
|
||||||
{
|
|
||||||
static void* vtable = CompatPtr<IDirectDrawSurface7>::from(surface).get()->lpVtbl;
|
|
||||||
return vtable;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace DDraw
|
namespace DDraw
|
||||||
{
|
{
|
||||||
template <typename TSurface>
|
template <typename TSurface>
|
||||||
@ -36,10 +27,7 @@ namespace DDraw
|
|||||||
TSurface* This, LPRECT lpDestRect, TSurface* lpDDSrcSurface, LPRECT lpSrcRect,
|
TSurface* This, LPRECT lpDestRect, TSurface* lpDDSrcSurface, LPRECT lpSrcRect,
|
||||||
DWORD dwFlags, LPDDBLTFX lpDDBltFx)
|
DWORD dwFlags, LPDDBLTFX lpDDBltFx)
|
||||||
{
|
{
|
||||||
if (!waitForFlip(This, dwFlags, DDBLT_WAIT, DDBLT_DONOTWAIT))
|
RealPrimarySurface::waitForFlip(m_data);
|
||||||
{
|
|
||||||
return DDERR_WASSTILLDRAWING;
|
|
||||||
}
|
|
||||||
DirectDrawClipper::update();
|
DirectDrawClipper::update();
|
||||||
return getOrigVtable(This).Blt(This, lpDestRect, lpDDSrcSurface, lpSrcRect, dwFlags, lpDDBltFx);
|
return getOrigVtable(This).Blt(This, lpDestRect, lpDDSrcSurface, lpSrcRect, dwFlags, lpDDBltFx);
|
||||||
}
|
}
|
||||||
@ -48,10 +36,7 @@ namespace DDraw
|
|||||||
HRESULT SurfaceImpl<TSurface>::BltFast(
|
HRESULT SurfaceImpl<TSurface>::BltFast(
|
||||||
TSurface* This, DWORD dwX, DWORD dwY, TSurface* lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans)
|
TSurface* This, DWORD dwX, DWORD dwY, TSurface* lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans)
|
||||||
{
|
{
|
||||||
if (!waitForFlip(This, dwTrans, DDBLTFAST_WAIT, DDBLTFAST_DONOTWAIT))
|
RealPrimarySurface::waitForFlip(m_data);
|
||||||
{
|
|
||||||
return DDERR_WASSTILLDRAWING;
|
|
||||||
}
|
|
||||||
return getOrigVtable(This).BltFast(This, dwX, dwY, lpDDSrcSurface, lpSrcRect, dwTrans);
|
return getOrigVtable(This).BltFast(This, dwX, dwY, lpDDSrcSurface, lpSrcRect, dwTrans);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,21 +46,6 @@ namespace DDraw
|
|||||||
return getOrigVtable(This).Flip(This, lpDDSurfaceTargetOverride, dwFlags);
|
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>
|
template <typename TSurface>
|
||||||
HRESULT SurfaceImpl<TSurface>::GetCaps(TSurface* This, TDdsCaps* lpDDSCaps)
|
HRESULT SurfaceImpl<TSurface>::GetCaps(TSurface* This, TDdsCaps* lpDDSCaps)
|
||||||
{
|
{
|
||||||
@ -90,30 +60,15 @@ namespace DDraw
|
|||||||
template <typename TSurface>
|
template <typename TSurface>
|
||||||
HRESULT SurfaceImpl<TSurface>::GetDC(TSurface* This, HDC* lphDC)
|
HRESULT SurfaceImpl<TSurface>::GetDC(TSurface* This, HDC* lphDC)
|
||||||
{
|
{
|
||||||
|
RealPrimarySurface::waitForFlip(m_data);
|
||||||
HRESULT result = getOrigVtable(This).GetDC(This, lphDC);
|
HRESULT result = getOrigVtable(This).GetDC(This, lphDC);
|
||||||
if (SUCCEEDED(result))
|
if (SUCCEEDED(result))
|
||||||
{
|
{
|
||||||
RealPrimarySurface::waitForFlip(m_data);
|
|
||||||
Dll::g_origProcs.ReleaseDDThreadLock();
|
Dll::g_origProcs.ReleaseDDThreadLock();
|
||||||
}
|
}
|
||||||
return result;
|
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>
|
template <typename TSurface>
|
||||||
HRESULT SurfaceImpl<TSurface>::GetSurfaceDesc(TSurface* This, TSurfaceDesc* lpDDSurfaceDesc)
|
HRESULT SurfaceImpl<TSurface>::GetSurfaceDesc(TSurface* This, TSurfaceDesc* lpDDSurfaceDesc)
|
||||||
{
|
{
|
||||||
@ -142,11 +97,7 @@ namespace DDraw
|
|||||||
TSurface* This, LPRECT lpDestRect, TSurfaceDesc* lpDDSurfaceDesc,
|
TSurface* This, LPRECT lpDestRect, TSurfaceDesc* lpDDSurfaceDesc,
|
||||||
DWORD dwFlags, HANDLE hEvent)
|
DWORD dwFlags, HANDLE hEvent)
|
||||||
{
|
{
|
||||||
if (!waitForFlip(This, dwFlags, DDLOCK_WAIT, DDLOCK_DONOTWAIT))
|
RealPrimarySurface::waitForFlip(m_data);
|
||||||
{
|
|
||||||
return DDERR_WASSTILLDRAWING;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT result = getOrigVtable(This).Lock(This, lpDestRect, lpDDSurfaceDesc, dwFlags, hEvent);
|
HRESULT result = getOrigVtable(This).Lock(This, lpDestRect, lpDDSurfaceDesc, dwFlags, hEvent);
|
||||||
if (SUCCEEDED(result))
|
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<IDirectDrawSurface>;
|
||||||
template SurfaceImpl<IDirectDrawSurface2>;
|
template SurfaceImpl<IDirectDrawSurface2>;
|
||||||
template SurfaceImpl<IDirectDrawSurface3>;
|
template SurfaceImpl<IDirectDrawSurface3>;
|
||||||
|
@ -27,10 +27,8 @@ namespace DDraw
|
|||||||
virtual HRESULT BltFast(TSurface* This, DWORD dwX, DWORD dwY,
|
virtual HRESULT BltFast(TSurface* This, DWORD dwX, DWORD dwY,
|
||||||
TSurface* lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans);
|
TSurface* lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans);
|
||||||
virtual HRESULT Flip(TSurface* This, TSurface* lpDDSurfaceTargetOverride, DWORD dwFlags);
|
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 GetCaps(TSurface* This, TDdsCaps* lpDDSCaps);
|
||||||
virtual HRESULT GetDC(TSurface* This, HDC* lphDC);
|
virtual HRESULT GetDC(TSurface* This, HDC* lphDC);
|
||||||
virtual HRESULT GetFlipStatus(TSurface* This, DWORD dwFlags);
|
|
||||||
virtual HRESULT GetSurfaceDesc(TSurface* This, TSurfaceDesc* lpDDSurfaceDesc);
|
virtual HRESULT GetSurfaceDesc(TSurface* This, TSurfaceDesc* lpDDSurfaceDesc);
|
||||||
virtual HRESULT IsLost(TSurface* This);
|
virtual HRESULT IsLost(TSurface* This);
|
||||||
virtual HRESULT Lock(TSurface* This, LPRECT lpDestRect, TSurfaceDesc* lpDDSurfaceDesc,
|
virtual HRESULT Lock(TSurface* This, LPRECT lpDestRect, TSurfaceDesc* lpDDSurfaceDesc,
|
||||||
@ -43,11 +41,9 @@ namespace DDraw
|
|||||||
virtual HRESULT Unlock(TSurface* This, TUnlockParam lpRect);
|
virtual HRESULT Unlock(TSurface* This, TUnlockParam lpRect);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool waitForFlip(TSurface* This, DWORD flags, DWORD waitFlag, DWORD doNotWaitFlag);
|
Surface* m_data;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void restoreOrigCaps(DWORD& caps);
|
void restoreOrigCaps(DWORD& caps);
|
||||||
|
|
||||||
Surface* m_data;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user