@@ -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// ///////////////////////////////////////////////////////////
259261HRESULT 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}
0 commit comments