apitrace/apitrace — pull request #290 by PIlin (2014-10-12 15:05:07+00:00)
Title: Fix tracing and retracing of recursive IDirect3DTexture9::LockRect/UnlockRect

I've found that apitrace fails to trace and retrace Final Fantasy XIV Official Benchmark (http://na.finalfantasyxiv.com/benchmark/). d3dretrace.exe shows many "dest buffer overflow" warnings and the resulting picture is completely broken.
FF XIV benchmark uses the next texture uploading pattern (taken from my fixed trace):
```
58 IDirect3DTexture9::LockRect(this = 0xa1ccf20, Level = 0, pLockedRect = &{Pitch = 8, pBits = 0x8d5ea40}, pRect = NULL, Flags = 0x0) = D3D_OK
59 IDirect3DTexture9::LockRect(this = 0xa1ccf20, Level = 1, pLockedRect = &{Pitch = 8, pBits = 0x8d5ea48}, pRect = NULL, Flags = 0x0) = D3D_OK
60 IDirect3DTexture9::LockRect(this = 0xa1ccf20, Level = 2, pLockedRect = &{Pitch = 8, pBits = 0x8d5ea50}, pRect = NULL, Flags = 0x0) = D3D_OK
61 memcpy(dest = 0x8d5ea40, src = blob(8), n = 8)
62 IDirect3DTexture9::UnlockRect(this = 0xa1ccf20, Level = 0) = D3D_OK
63 memcpy(dest = 0x8d5ea48, src = blob(8), n = 8)
64 IDirect3DTexture9::UnlockRect(this = 0xa1ccf20, Level = 1) = D3D_OK
65 memcpy(dest = 0x8d5ea50, src = blob(8), n = 8)
66 IDirect3DTexture9::UnlockRect(this = 0xa1ccf20, Level = 2) = D3D_OK
```
Benchmark locks all mip-map levels together and then unlocks them. This pattern creates problems both in `d3d9trace` and `d3d9retrace`.
`d3dtrace` holds info only about last LockRect in the variables `_MappedSize` and `m_pbData`. Those variables are used in UnlockRect to issue a fake `memcpy` command. But it doesn't check the level being unlocked, thus it produces a trace with `memcpy` for the unlocked level.
`d3d9retrace` uses global varaible `_maps` to hold active mappings. But it doesn't check `Level`, so it unlocks wrong rectangle (and then warns about "dest buffer overflow" again).

My fixes use `Level` information to produce correct traces and unlock correct rectangle during the retrace.