14
14
#include " CAdditionalVertexStreamManager.h"
15
15
#include " CVertexStreamBoundingBoxManager.h"
16
16
17
- #include < algorithm>
18
- #include < array>
19
- #include < cstring>
20
- #include < new>
21
-
22
17
// ///////////////////////////////////////////////////////////
23
18
//
24
19
// CProxyDirect3DVertexBuffer::CProxyDirect3DVertexBuffer
@@ -114,50 +109,40 @@ HRESULT CProxyDirect3DVertexBuffer::Lock(UINT OffsetToLock, UINT SizeToLock, voi
114
109
CVertexStreamBoundingBoxManager::GetSingleton ()->OnVertexBufferRangeInvalidated (m_pOriginal, OffsetToLock, SizeToLock);
115
110
}
116
111
117
- ClearFallbackLock ();
118
-
119
112
*ppbData = NULL ;
113
+ HRESULT hr = DoLock (OffsetToLock, SizeToLock, ppbData, Flags);
114
+ HRESULT originalHr = hr;
120
115
121
- const UINT clampedSize = ClampLockSize (OffsetToLock, SizeToLock);
122
-
123
- HRESULT hr = DoLock (OffsetToLock, clampedSize, ppbData, Flags);
124
- if (SUCCEEDED (hr) && *ppbData != NULL )
125
- return hr;
126
-
127
- HRESULT recoveryHr = TryRecoverLock (OffsetToLock, clampedSize, ppbData, Flags, hr);
128
- if (SUCCEEDED (recoveryHr) && *ppbData != NULL )
129
- return recoveryHr;
130
-
131
- HRESULT finalHr = FAILED (recoveryHr) ? recoveryHr : hr;
132
- HRESULT fallbackHr = ActivateFallbackLock (OffsetToLock, clampedSize, ppbData, Flags, finalHr);
133
- if (SUCCEEDED (fallbackHr) && *ppbData != NULL )
134
- return fallbackHr;
135
-
136
- if (FAILED (fallbackHr))
137
- finalHr = fallbackHr;
138
-
139
- struct
116
+ if (SUCCEEDED (hr) && *ppbData == NULL )
140
117
{
141
- const char * szText;
142
- uint uiReportId;
143
- uint uiLogEventId;
144
- } info;
145
- if (finalHr == D3D_OK)
146
- info = {" result NULL" , 8621 , 621 };
147
- else if (finalHr == STATUS_ARRAY_BOUNDS_EXCEEDED)
148
- info = {" offset out of range" , 8622 , 622 };
149
- else if (finalHr == STATUS_ACCESS_VIOLATION)
150
- info = {" access violation" , 8623 , 623 };
151
- else
152
- info = {" fail" , 8620 , 620 };
118
+ hr = D3DERR_INVALIDCALL;
119
+ }
153
120
154
- SString strMessage (" Lock VertexBuffer [%s] hr:%x Length:%x Usage:%x FVF:%x Pool:%x OffsetToLock:%x SizeToLock:%x Flags:%x" , info.szText , finalHr, m_iMemUsed,
155
- m_dwUsage, m_dwFVF, m_pool, OffsetToLock, clampedSize, Flags);
156
- WriteDebugEvent (strMessage);
157
- AddReportLog (info.uiReportId , strMessage);
158
- CCore::GetSingleton ().LogEvent (info.uiLogEventId , " Lock VertexBuffer" , " " , strMessage);
121
+ // Report problems
122
+ if (FAILED (hr))
123
+ {
124
+ struct
125
+ {
126
+ const char * szText;
127
+ uint uiReportId;
128
+ uint uiLogEventId;
129
+ } info;
130
+ if (hr == D3DERR_INVALIDCALL && originalHr == D3D_OK)
131
+ info = {" result NULL" , 8621 , 621 };
132
+ else if (hr == STATUS_ARRAY_BOUNDS_EXCEEDED)
133
+ info = {" offset out of range" , 8622 , 622 };
134
+ else if (hr == STATUS_ACCESS_VIOLATION)
135
+ info = {" access violation" , 8623 , 623 };
136
+ else
137
+ info = {" fail" , 8620 , 620 };
159
138
160
- return finalHr;
139
+ SString strMessage (" Lock VertexBuffer [%s] hr:%x origHr:%x Length:%x Usage:%x FVF:%x Pool:%x OffsetToLock:%x SizeToLock:%x Flags:%x" , info.szText , hr,
140
+ originalHr, m_iMemUsed, m_dwUsage, m_dwFVF, m_pool, OffsetToLock, SizeToLock, Flags);
141
+ WriteDebugEvent (strMessage);
142
+ AddReportLog (info.uiReportId , strMessage);
143
+ CCore::GetSingleton ().LogEvent (info.uiLogEventId , " Lock VertexBuffer" , " " , strMessage);
144
+ }
145
+ return hr;
161
146
}
162
147
163
148
// ///////////////////////////////////////////////////////////
@@ -169,197 +154,22 @@ HRESULT CProxyDirect3DVertexBuffer::Lock(UINT OffsetToLock, UINT SizeToLock, voi
169
154
// ///////////////////////////////////////////////////////////
170
155
HRESULT CProxyDirect3DVertexBuffer::DoLock (UINT OffsetToLock, UINT SizeToLock, void ** ppbData, DWORD Flags)
171
156
{
172
- if (OffsetToLock >= m_iMemUsed)
173
- return STATUS_ARRAY_BOUNDS_EXCEEDED;
174
-
175
- UINT adjustedSize = ClampLockSize (OffsetToLock, SizeToLock);
176
- if (adjustedSize == 0 )
177
- return STATUS_ARRAY_BOUNDS_EXCEEDED;
178
-
179
- return LockInternal (OffsetToLock, adjustedSize, ppbData, Flags);
180
- }
181
-
182
- HRESULT CProxyDirect3DVertexBuffer::Unlock ()
183
- {
184
- if (!m_fallbackLock.active )
185
- return m_pOriginal->Unlock ();
186
-
187
- HRESULT copyHr = D3D_OK;
188
-
189
- if ((m_fallbackLock.flags & D3DLOCK_READONLY) == 0 && m_fallbackLock.size > 0 && !m_fallbackLock.buffer .empty ())
157
+ // Validate sizes because gta can give invalid values (reason unknown)
158
+ if (OffsetToLock + SizeToLock > m_iMemUsed)
190
159
{
191
- void * pDestination = NULL ;
192
- copyHr = LockInternal (m_fallbackLock.offset , m_fallbackLock.size , &pDestination, 0 );
193
- if (SUCCEEDED (copyHr) && pDestination != NULL )
160
+ if (OffsetToLock > m_iMemUsed)
194
161
{
195
- std::memcpy (pDestination, m_fallbackLock.buffer .data (), m_fallbackLock.size );
196
- HRESULT unlockHr = m_pOriginal->Unlock ();
197
- if (FAILED (unlockHr))
198
- {
199
- copyHr = unlockHr;
200
- SString strMessage (" Unlock VertexBuffer [fallback unlock failed] hr:%x Length:%x Usage:%x FVF:%x Pool:%x Offset:%x Size:%x" , unlockHr, m_iMemUsed,
201
- m_dwUsage, m_dwFVF, m_pool, m_fallbackLock.offset , m_fallbackLock.size );
202
- WriteDebugEvent (strMessage);
203
- AddReportLog (8627 , strMessage);
204
- CCore::GetSingleton ().LogEvent (627 , " Unlock VertexBuffer" , " " , strMessage);
205
- }
206
- }
207
- else
208
- {
209
- if (SUCCEEDED (copyHr) && pDestination == NULL )
210
- copyHr = D3DERR_INVALIDCALL;
211
-
212
- SString strMessage (" Unlock VertexBuffer [fallback copy failed] hr:%x Length:%x Usage:%x FVF:%x Pool:%x Offset:%x Size:%x" , copyHr, m_iMemUsed, m_dwUsage,
213
- m_dwFVF, m_pool, m_fallbackLock.offset , m_fallbackLock.size );
214
- WriteDebugEvent (strMessage);
215
- AddReportLog (8626 , strMessage);
216
- CCore::GetSingleton ().LogEvent (626 , " Unlock VertexBuffer" , " " , strMessage);
162
+ return STATUS_ARRAY_BOUNDS_EXCEEDED;
217
163
}
164
+ SizeToLock = m_iMemUsed - OffsetToLock;
218
165
}
219
166
220
- ClearFallbackLock ();
221
- return D3D_OK;
222
- }
223
-
224
- UINT CProxyDirect3DVertexBuffer::ClampLockSize (UINT OffsetToLock, UINT SizeToLock) const
225
- {
226
- if (OffsetToLock >= m_iMemUsed)
227
- return 0 ;
228
-
229
- const UINT available = static_cast <UINT>(m_iMemUsed - OffsetToLock);
230
- if (available == 0 )
231
- return 0 ;
232
-
233
- if (SizeToLock == 0 )
234
- return available;
235
-
236
- return std::min (SizeToLock, available);
237
- }
238
-
239
- HRESULT CProxyDirect3DVertexBuffer::LockInternal (UINT OffsetToLock, UINT SizeToLock, void ** ppbData, DWORD Flags)
240
- {
241
- if (ppbData == NULL )
242
- return E_INVALIDARG;
243
-
244
- *ppbData = NULL ;
245
-
246
167
__try
247
168
{
248
169
return m_pOriginal->Lock (OffsetToLock, SizeToLock, ppbData, Flags);
249
170
}
250
171
__except (GetExceptionCode () == EXCEPTION_ACCESS_VIOLATION)
251
172
{
252
- *ppbData = NULL ;
253
173
return STATUS_ACCESS_VIOLATION;
254
174
}
255
175
}
256
-
257
- HRESULT CProxyDirect3DVertexBuffer::TryRecoverLock (UINT OffsetToLock, UINT SizeToLock, void ** ppbData, DWORD Flags, HRESULT originalHr)
258
- {
259
- HRESULT lastHr = originalHr;
260
-
261
- struct SLockAttempt
262
- {
263
- DWORD flags;
264
- UINT offset;
265
- UINT size;
266
- bool adjustPointer;
267
- };
268
-
269
- std::array<SLockAttempt, 7 > attempts = {
270
- SLockAttempt{Flags & ~D3DLOCK_DONOTWAIT, OffsetToLock, SizeToLock, false },
271
- SLockAttempt{Flags & ~D3DLOCK_NOOVERWRITE, OffsetToLock, SizeToLock, false },
272
- SLockAttempt{Flags & ~D3DLOCK_DISCARD, OffsetToLock, SizeToLock, false },
273
- SLockAttempt{Flags & ~(D3DLOCK_DONOTWAIT | D3DLOCK_NOOVERWRITE), OffsetToLock, SizeToLock, false },
274
- SLockAttempt{Flags & ~(D3DLOCK_DONOTWAIT | D3DLOCK_NOOVERWRITE | D3DLOCK_NO_DIRTY_UPDATE), OffsetToLock, SizeToLock, false },
275
- SLockAttempt{0u , OffsetToLock, SizeToLock, false },
276
- SLockAttempt{0u , 0u , static_cast <UINT>(m_iMemUsed), true },
277
- };
278
-
279
- for (const SLockAttempt& attempt : attempts)
280
- {
281
- if (attempt.flags == Flags && attempt.offset == OffsetToLock && attempt.size == SizeToLock)
282
- continue ;
283
-
284
- if (attempt.size > m_iMemUsed)
285
- continue ;
286
-
287
- UINT clampedSize = ClampLockSize (attempt.offset , attempt.size );
288
- if (clampedSize == 0 )
289
- continue ;
290
-
291
- void * pRecovered = NULL ;
292
- HRESULT hr = LockInternal (attempt.offset , clampedSize, &pRecovered, attempt.flags );
293
- if (SUCCEEDED (hr) && pRecovered != NULL )
294
- {
295
- if (attempt.adjustPointer )
296
- {
297
- UINT pointerOffset = 0 ;
298
- if (OffsetToLock > attempt.offset )
299
- pointerOffset = OffsetToLock - attempt.offset ;
300
- if (pointerOffset >= clampedSize)
301
- {
302
- lastHr = hr;
303
- continue ;
304
- }
305
- pRecovered = static_cast <void *>(static_cast <std::uint8_t *>(pRecovered) + pointerOffset);
306
- }
307
-
308
- *ppbData = pRecovered;
309
-
310
- SString strMessage (" Lock VertexBuffer [retry] hr:%x->%x Length:%x Usage:%x FVF:%x Pool:%x Offset:%x Size:%x Flags:%x->%x" , originalHr, hr, m_iMemUsed,
311
- m_dwUsage, m_dwFVF, m_pool, OffsetToLock, SizeToLock, Flags, attempt.flags );
312
- WriteDebugEvent (strMessage);
313
- AddReportLog (8625 , strMessage);
314
- CCore::GetSingleton ().LogEvent (625 , " Lock VertexBuffer" , " " , strMessage);
315
-
316
- return hr;
317
- }
318
-
319
- lastHr = hr;
320
- }
321
-
322
- return lastHr;
323
- }
324
-
325
- HRESULT CProxyDirect3DVertexBuffer::ActivateFallbackLock (UINT OffsetToLock, UINT SizeToLock, void ** ppbData, DWORD Flags, HRESULT originalHr)
326
- {
327
- if (ppbData == NULL )
328
- return originalHr;
329
-
330
- UINT clampedSize = ClampLockSize (OffsetToLock, SizeToLock);
331
- if (clampedSize == 0 )
332
- return originalHr;
333
-
334
- try
335
- {
336
- m_fallbackLock.buffer .resize (clampedSize);
337
- }
338
- catch (const std::bad_alloc&)
339
- {
340
- return E_OUTOFMEMORY;
341
- }
342
-
343
- m_fallbackLock.active = true ;
344
- m_fallbackLock.offset = OffsetToLock;
345
- m_fallbackLock.size = clampedSize;
346
- m_fallbackLock.flags = Flags;
347
-
348
- *ppbData = m_fallbackLock.buffer .data ();
349
-
350
- SString strMessage (" Lock VertexBuffer [fallback] hr:%x Length:%x Usage:%x FVF:%x Pool:%x OffsetToLock:%x SizeToLock:%x Flags:%x" , originalHr, m_iMemUsed,
351
- m_dwUsage, m_dwFVF, m_pool, OffsetToLock, clampedSize, Flags);
352
- WriteDebugEvent (strMessage);
353
- AddReportLog (8624 , strMessage);
354
- CCore::GetSingleton ().LogEvent (624 , " Lock VertexBuffer" , " " , strMessage);
355
-
356
- return D3D_OK;
357
- }
358
-
359
- void CProxyDirect3DVertexBuffer::ClearFallbackLock ()
360
- {
361
- m_fallbackLock.active = false ;
362
- m_fallbackLock.offset = 0 ;
363
- m_fallbackLock.size = 0 ;
364
- m_fallbackLock.flags = 0 ;
365
- }
0 commit comments