Skip to content

Commit ff06d07

Browse files
committed
Send primary surface address to PresentScene()
1 parent d1f0737 commit ff06d07

File tree

4 files changed

+55
-59
lines changed

4 files changed

+55
-59
lines changed

Dllmain/BuildNo.rc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
#define BUILD_NUMBER 8110
1+
#define BUILD_NUMBER 8111

ddraw/IDirectDrawSurfaceX.cpp

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5515,18 +5515,13 @@ HRESULT m_IDirectDrawSurfaceX::PresentSurface(LPRECT lpDestRect, bool IsSkipScen
55155515
// Check for device interface
55165516
CheckCreateInterface(this, __FUNCTION__, true, true, true);
55175517

5518-
bool ShouldSkipScene = ((IsSkipScene && !SceneReady) || IsPresentRunning);
5519-
5520-
// Check if is not primary surface or if scene should be skipped
5521-
if (ShouldWriteToGDI() || ddrawParent->IsInScene())
5518+
// Check if scene should be skipped
5519+
if ((IsSkipScene && !SceneReady) || IsPresentRunning)
55225520
{
5523-
// Never present when writing to GDI, presenting to a window or using Direct3D and InScene
5524-
if (IsPrimarySurface() && !ShouldSkipScene)
5525-
{
5526-
SceneReady = true;
5527-
}
5521+
Logging::LogDebug() << __FUNCTION__ << " Skipping scene!";
55285522
return DD_OK;
55295523
}
5524+
// Check if is not primary surface
55305525
else if (!IsPrimarySurface())
55315526
{
55325527
if (SceneReady && !IsPresentRunning)
@@ -5537,24 +5532,12 @@ HRESULT m_IDirectDrawSurfaceX::PresentSurface(LPRECT lpDestRect, bool IsSkipScen
55375532
return lpDDSrcSurfaceX->PresentSurface(lpDestRect, IsSkipScene, false);
55385533
}
55395534
}
5540-
return DDERR_GENERIC;
5541-
}
5542-
else if (ShouldSkipScene)
5543-
{
5544-
Logging::LogDebug() << __FUNCTION__ << " Skipping scene!";
5545-
return DDERR_GENERIC;
5535+
return DD_OK;
55465536
}
55475537

55485538
// Set scene ready
55495539
SceneReady = true;
55505540

5551-
// Check if surface is locked or has an open DC
5552-
if (IsSurfaceBusy())
5553-
{
5554-
Logging::LogDebug() << __FUNCTION__ << " Surface is busy!";
5555-
return DDERR_SURFACEBUSY;
5556-
}
5557-
55585541
ScopedCriticalSection ThreadLock(GetCriticalSection(), !SkipCriticalSection);
55595542

55605543
// Set present flag
@@ -5563,8 +5546,22 @@ HRESULT m_IDirectDrawSurfaceX::PresentSurface(LPRECT lpDestRect, bool IsSkipScen
55635546
// Check interface after critical section
55645547
CheckOnlyInterfaceSafty(this, __FUNCTION__, false);
55655548

5549+
// Check if surface is locked or has an open DC
5550+
if (IsSurfaceBusy())
5551+
{
5552+
Logging::LogDebug() << __FUNCTION__ << " Surface is busy!";
5553+
return DDERR_SURFACEBUSY;
5554+
}
5555+
5556+
// Check if device is inscene
5557+
if (ddrawParent->IsInScene())
5558+
{
5559+
LOG_LIMIT(100, __FUNCTION__ << " Error: is in Direct3D scene already! PresentToWindow: " << ShouldPresentToWindow(true));
5560+
return DDERR_GENERIC;
5561+
}
5562+
55665563
// Present to d3d9
5567-
HRESULT hr = ddrawParent->PresentScene(lpDestRect);
5564+
HRESULT hr = ddrawParent->PresentScene(this, lpDestRect);
55685565
if (FAILED(hr))
55695566
{
55705567
LOG_LIMIT(100, __FUNCTION__ << " Error: failed to present 2D scene!");
@@ -6005,7 +6002,7 @@ bool m_IDirectDrawSurfaceX::CheckRectforSkipScene(RECT& DestRect)
60056002
void m_IDirectDrawSurfaceX::BeginWritePresent(bool IsSkipScene)
60066003
{
60076004
// Check if data needs to be presented before write
6008-
if (dirtyFlag)
6005+
if (dirtyFlag && !ShouldWriteToGDI())
60096006
{
60106007
if (FAILED(PresentSurface(nullptr, IsSkipScene, false)))
60116008
{

ddraw/IDirectDrawX.cpp

Lines changed: 30 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4956,29 +4956,29 @@ void m_IDirectDrawX::RestoreState(DRAWSTATEBACKUP& DrawStates)
49564956
d3d9Device->SetTransform(D3DTS_PROJECTION, &DrawStates.ProjectionMatrix);
49574957
}
49584958

4959-
HRESULT m_IDirectDrawX::DrawPrimarySurface(LPDIRECT3DTEXTURE9 pDisplayTexture)
4959+
HRESULT m_IDirectDrawX::DrawPrimarySurface(m_IDirectDrawSurfaceX* pPrimarySurface, LPDIRECT3DTEXTURE9 pDisplayTexture)
49604960
{
49614961
Logging::LogDebug() << __FUNCTION__ << " (" << this << ")";
49624962

4963+
if (!pPrimarySurface)
4964+
{
4965+
LOG_LIMIT(100, __FUNCTION__ << " Error: no primary surface!");
4966+
return DDERR_GENERIC;
4967+
}
4968+
49634969
bool IsUsingPalette = false;
49644970
if (!pDisplayTexture)
49654971
{
4966-
if (!PrimarySurface)
4967-
{
4968-
LOG_LIMIT(100, __FUNCTION__ << " Error: no primary surface!");
4969-
return DDERR_GENERIC;
4970-
}
4971-
49724972
// Get surface texture
4973-
pDisplayTexture = PrimarySurface->GetD3d9Texture(false);
4973+
pDisplayTexture = pPrimarySurface->GetD3d9Texture(false);
49744974
if (!pDisplayTexture)
49754975
{
49764976
LOG_LIMIT(100, __FUNCTION__ << " Error: failed to get surface texture!");
49774977
return DDERR_GENERIC;
49784978
}
49794979

49804980
// Check palette
4981-
IsUsingPalette = PrimarySurface->IsPalette();
4981+
IsUsingPalette = pPrimarySurface->IsPalette();
49824982
}
49834983

49844984
// Get texture desc
@@ -5001,13 +5001,13 @@ HRESULT m_IDirectDrawX::DrawPrimarySurface(LPDIRECT3DTEXTURE9 pDisplayTexture)
50015001
if (IsUsingPalette)
50025002
{
50035003
// Get palette texture
5004-
LPDIRECT3DTEXTURE9 PaletteTexture = PrimarySurface->GetD3d9PaletteTexture();
5004+
LPDIRECT3DTEXTURE9 PaletteTexture = pPrimarySurface->GetD3d9PaletteTexture();
50055005

50065006
// Set palette texture
50075007
if (PaletteTexture && CreatePalettePixelShader())
50085008
{
50095009
// Set palette texture
5010-
PrimarySurface->UpdatePaletteData();
5010+
pPrimarySurface->UpdatePaletteData();
50115011
d3d9Device->SetTexture(1, PaletteTexture);
50125012

50135013
// Set pixel shader
@@ -5068,7 +5068,7 @@ HRESULT m_IDirectDrawX::DrawPrimarySurface(LPDIRECT3DTEXTURE9 pDisplayTexture)
50685068
// Reset dirty flags
50695069
if (SUCCEEDED(hr))
50705070
{
5071-
PrimarySurface->ClearDirtyFlags();
5071+
pPrimarySurface->ClearDirtyFlags();
50725072
}
50735073
else
50745074
{
@@ -5088,18 +5088,18 @@ HRESULT m_IDirectDrawX::DrawPrimarySurface(LPDIRECT3DTEXTURE9 pDisplayTexture)
50885088
return hr;
50895089
}
50905090

5091-
HRESULT m_IDirectDrawX::CopyPrimarySurface(LPDIRECT3DSURFACE9 pDestBuffer)
5091+
HRESULT m_IDirectDrawX::CopyPrimarySurface(m_IDirectDrawSurfaceX* pPrimarySurface, LPDIRECT3DSURFACE9 pDestBuffer)
50925092
{
50935093
Logging::LogDebug() << __FUNCTION__ << " (" << this << ")";
50945094

5095-
if (!PrimarySurface)
5095+
if (!pPrimarySurface)
50965096
{
50975097
LOG_LIMIT(100, __FUNCTION__ << " Error: no primary surface!");
50985098
return DDERR_GENERIC;
50995099
}
51005100

51015101
// Get backbuffer render target
5102-
IDirect3DSurface9* pRenderTarget = PrimarySurface->GetD3d9Surface();
5102+
IDirect3DSurface9* pRenderTarget = pPrimarySurface->GetD3d9Surface();
51035103
if (!pRenderTarget)
51045104
{
51055105
LOG_LIMIT(100, __FUNCTION__ << " Error: no render target on primary surface!");
@@ -5121,7 +5121,7 @@ HRESULT m_IDirectDrawX::CopyPrimarySurface(LPDIRECT3DSURFACE9 pDestBuffer)
51215121

51225122
// Get source rect
51235123
RECT* pSrcRect = nullptr;
5124-
RECT SrcRect = { 0, 0, (LONG)PrimarySurface->GetD3d9Width(), (LONG)PrimarySurface->GetD3d9Height() };
5124+
RECT SrcRect = { 0, 0, (LONG)pPrimarySurface->GetD3d9Width(), (LONG)pPrimarySurface->GetD3d9Height() };
51255125
if (!ExclusiveMode && hWnd && !IsIconic(hWnd))
51265126
{
51275127
// Clip rect
@@ -5162,14 +5162,14 @@ HRESULT m_IDirectDrawX::CopyPrimarySurface(LPDIRECT3DSURFACE9 pDestBuffer)
51625162
{
51635163
if (SUCCEEDED(hr))
51645164
{
5165-
PrimarySurface->ClearDirtyFlags();
5165+
pPrimarySurface->ClearDirtyFlags();
51665166
}
51675167
}
51685168

51695169
return hr;
51705170
}
51715171

5172-
HRESULT m_IDirectDrawX::PresentScene(RECT* pRect)
5172+
HRESULT m_IDirectDrawX::PresentScene(m_IDirectDrawSurfaceX* pPrimarySurface, RECT* pRect)
51735173
{
51745174
Logging::LogDebug() << __FUNCTION__ << " (" << this << ")";
51755175

@@ -5180,30 +5180,29 @@ HRESULT m_IDirectDrawX::PresentScene(RECT* pRect)
51805180
return DD_OK;
51815181
}
51825182

5183-
if (!PrimarySurface)
5183+
if (!pPrimarySurface)
51845184
{
51855185
LOG_LIMIT(100, __FUNCTION__ << " Error: no primary surface!");
51865186
return DDERR_GENERIC;
51875187
}
51885188

5189-
if (IsInScene())
5189+
if (PrimarySurface != pPrimarySurface)
51905190
{
5191-
LOG_LIMIT(100, __FUNCTION__ << " Error: is in Direct3D scene already! PresentToWindow: " << PrimarySurface->ShouldPresentToWindow(true));
5192-
return DDERR_GENERIC;
5191+
LOG_LIMIT(100, __FUNCTION__ << " Warning: primary surface doesn't match: " << PrimarySurface << " -> " << pPrimarySurface);
51935192
}
51945193

51955194
#ifdef ENABLE_PROFILING
51965195
auto startTime = std::chrono::high_resolution_clock::now();
51975196
#endif
51985197

51995198
// Prepare primary surface render target before presenting
5200-
PrimarySurface->PrepareRenderTarget();
5199+
pPrimarySurface->PrepareRenderTarget();
52015200

52025201
LPRECT pDestRect = nullptr;
52035202
RECT DestRect = {};
5204-
if (PrimarySurface->ShouldPresentToWindow(true))
5203+
if (pPrimarySurface->ShouldPresentToWindow(true))
52055204
{
5206-
if (FAILED(PrimarySurface->GetPresentWindowRect(pRect, DestRect)))
5205+
if (FAILED(pPrimarySurface->GetPresentWindowRect(pRect, DestRect)))
52075206
{
52085207
LOG_LIMIT(100, __FUNCTION__ << " Error: failed to get present rect!");
52095208
return DDERR_GENERIC;
@@ -5218,7 +5217,7 @@ HRESULT m_IDirectDrawX::PresentScene(RECT* pRect)
52185217
d3d9Device->BeginScene();
52195218

52205219
// Copy or draw primary surface before presenting
5221-
if (IsPrimaryRenderTarget() && !PrimarySurface->GetD3d9Texture(false))
5220+
if (IsPrimaryRenderTarget() && !pPrimarySurface->GetD3d9Texture(false))
52225221
{
52235222
if (IsGammaSet && GammaControlInterface)
52245223
{
@@ -5242,22 +5241,22 @@ HRESULT m_IDirectDrawX::PresentScene(RECT* pRect)
52425241
ComPtr<IDirect3DSurface9> pCopySurface;
52435242
if (SUCCEEDED(ScreenCopyTexture->GetSurfaceLevel(0, pCopySurface.GetAddressOf())))
52445243
{
5245-
hr = CopyPrimarySurface(pCopySurface.Get());
5244+
hr = CopyPrimarySurface(pPrimarySurface, pCopySurface.Get());
52465245
}
52475246

52485247
// Draw surface
5249-
hr = DrawPrimarySurface(ScreenCopyTexture);
5248+
hr = DrawPrimarySurface(pPrimarySurface, ScreenCopyTexture);
52505249
}
52515250
}
52525251
}
52535252
else
52545253
{
5255-
hr = CopyPrimarySurface(nullptr);
5254+
hr = CopyPrimarySurface(pPrimarySurface, nullptr);
52565255
}
52575256
}
52585257
else
52595258
{
5260-
hr = DrawPrimarySurface(nullptr);
5259+
hr = DrawPrimarySurface(pPrimarySurface, nullptr);
52615260
}
52625261
if (FAILED(hr))
52635262
{
@@ -5365,7 +5364,7 @@ DWORD WINAPI m_IDirectDrawX::PresentThreadFunction(LPVOID)
53655364
d3d9Device->BeginScene();
53665365

53675366
// Draw surface before presenting
5368-
pDDraw->DrawPrimarySurface(nullptr);
5367+
pDDraw->DrawPrimarySurface(pPrimarySurface, nullptr);
53695368

53705369
// End scene
53715370
d3d9Device->EndScene();

ddraw/IDirectDrawX.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ class m_IDirectDrawX : public IUnknown, public AddressLookupTableDdrawObject
7676
HRESULT CreateD9Object();
7777
void BackupAndResetState(DRAWSTATEBACKUP& DrawStates, DWORD Width, DWORD Height);
7878
void RestoreState(DRAWSTATEBACKUP& DrawStates);
79-
HRESULT CopyPrimarySurface(LPDIRECT3DSURFACE9 pDestBuffer);
80-
HRESULT DrawPrimarySurface(LPDIRECT3DTEXTURE9 pDisplayTexture);
79+
HRESULT CopyPrimarySurface(m_IDirectDrawSurfaceX* pPrimarySurface, LPDIRECT3DSURFACE9 pDestBuffer);
80+
HRESULT DrawPrimarySurface(m_IDirectDrawSurfaceX* pPrimarySurface, LPDIRECT3DTEXTURE9 pDisplayTexture);
8181
static DWORD WINAPI PresentThreadFunction(LPVOID);
8282
HRESULT Present(RECT* pSourceRect, RECT* pDestRect);
8383
void RestoreD3DDeviceState();
@@ -306,7 +306,7 @@ class m_IDirectDrawX : public IUnknown, public AddressLookupTableDdrawObject
306306
HRESULT GetD9Gamma(DWORD dwFlags, LPDDGAMMARAMP lpRampData);
307307
HRESULT SetD9Gamma(DWORD dwFlags, LPDDGAMMARAMP lpRampData);
308308
bool IsUsingThreadPresent();
309-
HRESULT PresentScene(RECT* pRect);
309+
HRESULT PresentScene(m_IDirectDrawSurfaceX* pPrimarySurface, RECT* pRect);
310310

311311
// External static functions
312312
static bool CheckDirectDrawXInterface(void* pInterface);

0 commit comments

Comments
 (0)