Skip to content

Commit d0dd800

Browse files
committed
Addendum #3 to vertex buffer lock fixes (after 5b6530e)
1 parent 5b6530e commit d0dd800

File tree

2 files changed

+38
-9
lines changed

2 files changed

+38
-9
lines changed

Client/core/DXHook/CProxyDirect3DVertexBuffer.cpp

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ HRESULT CProxyDirect3DVertexBuffer::Lock(UINT OffsetToLock, UINT SizeToLock, voi
120120
pBoundingBoxManager->OnVertexBufferRangeInvalidated(m_pOriginal, OffsetToLock, SizeToLock);
121121
}
122122

123+
SharedUtil::CAutoCSLock fallbackGuard(m_fallbackCS);
124+
123125
if (m_bFallbackActive)
124126
{
125127
m_bFallbackActive = false;
@@ -258,10 +260,13 @@ HRESULT CProxyDirect3DVertexBuffer::Lock(UINT OffsetToLock, UINT SizeToLock, voi
258260
/////////////////////////////////////////////////////////////
259261
HRESULT CProxyDirect3DVertexBuffer::Unlock()
260262
{
263+
SharedUtil::CAutoCSLock fallbackGuard(m_fallbackCS);
264+
261265
if (!m_bFallbackActive)
262266
return m_pOriginal->Unlock();
263267

264268
HRESULT copyResult = D3D_OK;
269+
bool bShouldRetryLater = false;
265270

266271
if ((m_fallbackFlags & D3DLOCK_READONLY) == 0 && m_fallbackSize > 0)
267272
{
@@ -282,7 +287,16 @@ HRESULT CProxyDirect3DVertexBuffer::Unlock()
282287

283288
if (SUCCEEDED(lockHr) && pReal != nullptr)
284289
{
285-
memcpy(pReal, m_fallbackStorage.data(), size);
290+
if (size > 0 && size <= m_fallbackStorage.size())
291+
{
292+
memcpy(pReal, m_fallbackStorage.data(), size);
293+
}
294+
else
295+
{
296+
WriteDebugEvent(SString("Unlock VertexBuffer: fallback copy size mismatch (size:%x storage:%x)", size, m_fallbackStorage.size()));
297+
copyResult = D3DERR_INVALIDCALL;
298+
}
299+
286300
HRESULT unlockHr = m_pOriginal->Unlock();
287301
if (FAILED(unlockHr))
288302
copyResult = unlockHr;
@@ -295,17 +309,30 @@ HRESULT CProxyDirect3DVertexBuffer::Unlock()
295309
WriteDebugEvent(SString("Unlock VertexBuffer: failed to copy fallback data (lockHr:%x offset:%x size:%x flags:%08x)", lockHr, offset, size,
296310
writeFlags));
297311
copyResult = FAILED(lockHr) ? lockHr : D3DERR_INVALIDCALL;
312+
bShouldRetryLater = true;
298313
}
299314
}
315+
else
316+
{
317+
bShouldRetryLater = true;
318+
}
319+
}
320+
else if (m_fallbackSize == 0)
321+
{
322+
// No bytes were mapped, keep fallback around in case caller retries
323+
bShouldRetryLater = true;
300324
}
301325

302-
WriteDebugEvent(SString("Unlock VertexBuffer: fallback completed (offset:%x size:%x flags:%08x result:%x)", m_fallbackOffset, m_fallbackSize,
303-
m_fallbackFlags, copyResult));
326+
WriteDebugEvent(SString("Unlock VertexBuffer: fallback completed (offset:%x size:%x flags:%08x retryLater:%u result:%x)", m_fallbackOffset, m_fallbackSize,
327+
m_fallbackFlags, static_cast<uint>(bShouldRetryLater), copyResult));
304328

305-
m_bFallbackActive = false;
306-
m_fallbackOffset = 0;
307-
m_fallbackSize = 0;
308-
m_fallbackFlags = 0;
329+
m_bFallbackActive = bShouldRetryLater ? m_bFallbackActive : false;
330+
if (!m_bFallbackActive)
331+
{
332+
m_fallbackOffset = 0;
333+
m_fallbackSize = 0;
334+
m_fallbackFlags = 0;
335+
}
309336

310337
return copyResult;
311338
}

Client/core/DXHook/CProxyDirect3DVertexBuffer.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <d3d9.h>
1515
#include <cstdint>
1616
#include <vector>
17+
#include "SharedUtil.Misc.h"
1718
#include "CProxyDirect3DDevice9.h" // Include full definition for SResourceMemory
1819

1920
DEFINE_GUID(CProxyDirect3DVertexBuffer_GUID, 0x128A025E, 0x0100, 0x04F1, 0x40, 0x60, 0x53, 0x19, 0x44, 0x56, 0x59, 0x42);
@@ -40,8 +41,8 @@ class CProxyDirect3DVertexBuffer : public IDirect3DVertexBuffer9
4041
D3DRESOURCETYPE __stdcall GetType() { return m_pOriginal->GetType(); }
4142

4243
/*** IDirect3DVertexBuffer9 methods ***/
43-
HRESULT __stdcall Lock(UINT OffsetToLock, UINT SizeToLock, void** ppbData, DWORD Flags);
44-
HRESULT __stdcall Unlock();
44+
HRESULT __stdcall Lock(UINT OffsetToLock, UINT SizeToLock, void** ppbData, DWORD Flags) override;
45+
HRESULT __stdcall Unlock() override;
4546
HRESULT __stdcall GetDesc(D3DVERTEXBUFFER_DESC* pDesc) { return m_pOriginal->GetDesc(pDesc); }
4647

4748
// CProxyDirect3DVertexBuffer
@@ -64,4 +65,5 @@ class CProxyDirect3DVertexBuffer : public IDirect3DVertexBuffer9
6465
UINT m_fallbackSize;
6566
DWORD m_fallbackFlags;
6667
std::vector<uint8_t> m_fallbackStorage;
68+
SharedUtil::CCriticalSection m_fallbackCS;
6769
};

0 commit comments

Comments
 (0)