Even though Dxbx is progressing almost every day, I think we’re still nowhere near good emulation (not by a long shot)!
One of the reasons for that is, that we’ve inherited all those patches from Cxbx, which are nice and all, but are a pain in the neck sometimes to get right.
Since I’ve been working in this code for the better part of 3 years already, I think I’m allowed to make a fairly bold statement here : We’re just doing it wrong.
Sure, having a good map of the symbols present in an XBE helps, but I’m not convinced anymore that we need to patch up all drawing code. Please, let me explain :
The thing is, that most of the Direct3D functions we currently patch could run unpatched just fine, just as long as they don’t interact with the NV2A (the graphics chip present in the Xbox1).
Instead, IMHO we should intervene only where the NV2A comes into play : when handling the actual drawing commands.
The NV2A, like many other graphics chips, has the concept of a ‘pushbuffer’, in which the drawing commands are placed that need to be executed. After much researching the Direct3D8 implementation that Microsoft made for the Xbox, it appears to me that the API does no much more than ‘just’ place instructions in the pushbuffer, ready for the NV2A to execute.
The NV2A has some unique features when compared to Direct3D8 on the PC side; It supports quite a few formats more, it has 5 a powerfull “4 input, 3 output” pixel shader instructions and a few extra’s on the vertex-shader side.
So what *I* think we should do, is emulate the NV2A at the pushbuffer level. This would allow us to disable most of our patches, which will improve the stability & predictability of the running xbe by a big margin.
I intend to prove this using my pixel-shader work; Right now this code hooks into the various pixel-shader related functions, like CreatePixelShader/SetPixelShader and others. What I’m going to attempt, is disable all those patches, and resurrect enough of the pushbuffer filling code to make these functions run in Dxbx without crashing. Once that works, I want to insert my pixel shader recompiler into the current drawing-patches. For this, I will need to add a cache, so that the pixel shader is not recompiled on every frame. But once that’s in place, it will automatically give us dynamic pixel shader support(!)
I’m 98% convinced that I can get this to work – there will be lots of problems, I’m sure, but I think this is nice goal to reach for a 0.5 release, don’t you agree?!
After this, I might attempt to do the same to all other resources : vertex shaders, vertex buffers, index buffers, textures, etc. The thing with these is much the same : we currently patch all code related to those resources, but ultimately it’s just the rendering that we want to do ourselves! So what we probably should do, is pick up the entire push-buffer as-is and try to execute as much of the commands in it as we possibly can. I’ve already started collecting push-buffer command codes, but all help is welcome – is anyone interested in helping us out?! Please holler if you are. Cheers!