Cxbx-Reloaded / Cxbx-Reloaded

Xbox (Original) Emulator
https://cxbx-reloaded.co.uk
GNU General Public License v2.0
2.13k stars 256 forks source link

HLE : Centrally convert D3D resources #193

Open PatrickvL opened 7 years ago

PatrickvL commented 7 years ago

The current method to associate D3D resources to emulated resources (or the other way around) sucks. We'd be much better off with a mapping that associates Xbox D3D resources to the host counterpart.

Doesn't matter much which implementation we choose, let's first get the rendering correct. Perhaps std::map is already good enough.

The trick there would be to get a reference to all active resources. D3D stores them in a structure somewhere, but it could have changed between xdk versions. This needs to be investigated.

Each type requires a type-specific conversion. Most conversions are already present in Cxbx.

For this issue, all required conversions must be called from one central function, which just needs to be called from the actual drawing patches.

Drawing patches are about the only D3D patches that we should keep. Most of the other D3D patches can be removed, especially those that don't access hardware and just call into our kernel. These can run just fine as they are, without a patch.

Before the conversion of any Xbox D3D resource, a fast hash can be calculated over the Xbox resource and it's associate data, to determine if a conversion is needed, by comparing it to the hash of a previous conversion.

To speed it up, we could skip the hash check when no changes are detected in a configurable number of prior checks. After a configurable number of skips, the hash must forcibly be checked, in order to detect sudden changes in a resource.

Currently, the vertex buffer stream conversion code in Cxbx already contains such a check. This code must be generalized into a cache for all resource types.

Additionally, all host-resources must be time-stamped per use, so resources not used for a while can be (and must be!) removed. (Otherwise, lingering host resources would form a memory leak.) If a host resource is pruned, but the corresponding Xbox resource still exists and becomes activated again, we can just as easy re-convert it to a host resource.

Another way to prevent stale resources, is to detect the deletion of Xbox resources by checking all calls to MmFreeContiguousMemory and see if it concerns a resource. This would avoid the need to patch all D3D Delete methods, but it may not be possible to detect all removals this way, as some resources might use static buffers that will never be allocated nor freeed.

PatrickvL commented 7 years ago

As a fast hash, xxhash32 could be a well-suited candidate, I've changed to this with this commit : https://github.com/PatrickvL/Cxbx-Reloaded/commit/1585b75445f503682aa62760fd968c31ac4bfc7c

Please test before cherry-picking this!

PatrickvL commented 7 years ago

Eventually most functions handling D3D resources must be left unpatched, so they will work just as the original. This requires a bit more work in the kernel. Especially MmAllocateContiguousMemory should allocate from the same address range as the Xbox does. Once that's realized, both HLE and LLE graphics emulation must take into account that each Data-pointer inside a D3D resource, is stored as a GPU-address, not a physical address. (Converting back and forth is just a matter of xor-ring with 0xF800000)

PatrickvL commented 7 years ago

Another step into this direction is done with this commit (which also mentions the steps Dxbx did) : https://github.com/PatrickvL/Cxbx-Reloaded/commit/d326db68d5ca4cf41b8fcec5397a56f702c0dbfa.

Again: test well before cherry-picking this in!

PatrickvL commented 7 years ago

We've reached a new milestone with this, now that we copy index buffers correctly when drawing from them. Also, I'm working on the same approach for textures, which is also coming along nicely - stay tuned for more news on this subject!

PatrickvL commented 6 years ago

Yet another milestone on this issue : https://github.com/Cxbx-Reloaded/Cxbx-Reloaded/pull/1058