narzoul / DDrawCompat

DirectDraw and Direct3D 1-7 compatibility, performance and visual enhancements for Windows Vista, 7, 8, 10 and 11
BSD Zero Clause License
880 stars 67 forks source link

Query on D3DDI and driver models #267

Closed BEENNath58 closed 7 months ago

BEENNath58 commented 7 months ago

I was looking for information on D3DDI that DDrawCompat uses to fix many (which type?) of bugs.

Unfortunately my search only lead to 1 useful result at:

https://learn.microsoft.com/en-us/windows-hardware/drivers/display/direct3d

The information is inadequate that raised a few doubts:

1) I originally assumed DDC didn't work on XP because D3DDI was some DXGI/DX10+ feature. However the document mentions that D3DDI is supported since Win2K. Where did I get it wrong? Is it that XPDM and WDDM DDIs are different, and DDC only touches WDDM DDIs?

2) DDC doesn't work on VMs. What's the limitation there, is it interlinked to my previous point?

3) I saw DDC uses only ddraw.dll. Why is that? Is it because all the problems are all related to DDraw implementation and DDI, both of which are only linked to ddraw.dll?

3.a) If the above is true, then dgV2 has a d3dim.dll as well, is that file responsible for something completely different that DDC doesn't do (example could be the D3DRM demos that run fine with dgV2 files but DDC needs an old d3dim.dll file).

4) What is a good source to study on D3DDI? The Windows DDK? Both the new and older ones?

1.a) If the last point in 1 was true, will older DDKs be useful for WDDM based DDIs on newer OS? Similarly does the new one contain stuff for XPDM based DDI?

Thank you.

narzoul commented 7 months ago

I originally assumed DDC didn't work on XP because D3DDI was some DXGI/DX10+ feature. However the document mentions that D3DDI is supported since Win2K. Where did I get it wrong? Is it that XPDM and WDDM DDIs are different, and DDC only touches WDDM DDIs?

Yes, XPDM and WDDM are very different. WDDM is the new driver model developed for Vista. XPDM was still supported up to Windows 7, mainly for compatibility with legacy hardware that never received any WDDM drivers. Windows 8+ only supports WDDM. I haven't looked at the old driver model much and I have no plans to add support for it.

DDC doesn't work on VMs. What's the limitation there, is it interlinked to my previous point?

It might work, if WDDM is properly supported by the VM, but most WDDM drivers in VMs are still quite buggy, if they're available at all. I don't support VMs mainly for that reason. I had better luck with VMware than VirtualBox drivers when I was last experimenting with this, but support isn't perfect there either.

I saw DDC uses only ddraw.dll. Why is that? Is it because all the problems are all related to DDraw implementation and DDI, both of which are only linked to ddraw.dll?

ddraw.dll dynamically loads d3dim.dll or d3dim700.dll when Direct3D objects are created through DirectDraw. There is no need to replace the files, since the needed hooks can be installed from the ddraw.dll hooks. They mostly just implement a bunch of additional COM interfaces, so vtable hooks are enough.

If the above is true, then dgV2 has a d3dim.dll as well, is that file responsible for something completely different that DDC doesn't do (example could be the D3DRM demos that run fine with dgV2 files but DDC needs an old d3dim.dll file).

There is no d3dim.dll in dgVoodoo, you're probably referring to d3dimm.dll. I have no idea what's in it, you'd have to ask the author. Apps surely won't load it directly (as they don't with d3dim.dll either), it must be loaded and used by the ddraw.dll wrapper of dgVoodoo itself.

I don't know what demos you're referring to. If you need old d3dim.dll files for them, it's probably because of the broken Ramp device implementation in the Win 10+ d3dim.dll?

What is a good source to study on D3DDI? The Windows DDK? Both the new and older ones?

I usually just browse the references for the user-mode display driver functions here: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/d3dumddi/ns-d3dumddi-_d3dddi_devicefuncs

There is of course no tutorial or anything like that that I'm aware of. The reference is also quite spotty in places. I sometimes wonder if there is some additional private documentation or guides that driver vendors receive, because the information I could find in the public docs doesn't seem enough to implement a solid driver.

You can take a look at driver call traces of some apps to study how it fits together, which is also what I did. There is no logger for driver calls that I'm aware of other than DDrawCompat's debug logs though.

If the last point in 1 was true, will older DDKs be useful for WDDM based DDIs on newer OS? Similarly does the new one contain stuff for XPDM based DDI?

I don't recall reading any DDK docs specifically, either for XPDM or WDDM, so I've no idea what you'll find in different DDKs. I thought most information nowadays is found online, like the XPDM and WDDM related links already posted here. Is there something else in older downloadable DDKs which is not available in the online docs? I imagine the older DDKs would only contain information related to XPDM anyway.

BEENNath58 commented 7 months ago

ddraw.dll dynamically loads d3dim.dll or d3dim700.dll when Direct3D objects are created through DirectDraw. There is no need to replace the files, since the needed hooks can be installed from the ddraw.dll hooks. They mostly just implement a bunch of additional COM interfaces, so vtable hooks are enough.

I don't know what demos you're referring to. If you need old d3dim.dll files for them, it's probably because of the broken Ramp device implementation in the Win 10+ d3dim.dll?

These 2 questions stemmed from the Ramp problem. I originally assumed that, since the new Windows d3dim.dll is "stripped" in some sort, dgV2 has restored the function in d3dimM.dll (I will ask him what it does).

And that it was impossible for DDC to do it because it doesn't have a Direct3d separate module.

Now that you say a COM hook is enough, would that be enough to fix the Ramp issue.

(Not that I need a fix in ddraw now, just the way these things work).

Also assuming that this problem isn't even related to the driver, the fix wouldn't be necessary in DDI, right?

I don't recall reading any DDK docs specifically, either for XPDM or WDDM, so I've no idea what you'll find in different DDKs. I thought most information nowadays is found online, like the XPDM and WDDM related links already posted here. Is there something else in older downloadable DDKs which is not available in the online docs? I imagine the older DDKs would only contain information related to XPDM anyway.

I went and tried the DX7 DDK and found a few permedia files and files for some .c and headers for the reference driver. No useful documentation either.

narzoul commented 7 months ago

These 2 questions stemmed from the Ramp problem. I originally assumed that, since the new Windows d3dim.dll is "stripped" in some sort, dgV2 has restored the function in d3dimM.dll (I will ask him what it does).

dgVoodoo doesn't use or need any of the ddraw-related system dlls. I also don't think it has an actual Ramp or even RGB software device implementation, most likely it only implements the HAL devices and uses them in place of the software devices too. So in essence, it's probably similar to what DDrawCompat does with the SoftwareDevice=hal setting.

Of course, I don't know its actual implementation (since it's closed source), I just assume this based on the fact that people use it to force things like resolution scaling and antialiasing on The Sims, which uses the RGB software device natively. I don't think this would be possible (at least with acceptable performance) on a pure CPU-rendered implementation.

Now that you say a COM hook is enough, would that be enough to fix the Ramp issue.

Not that simple. The whole Ramp SW renderer would have to be reimplemented from scratch most likely, and I don't think it's worth the effort, not to mention the exact details of its working are not really documented and it might be difficult to replicate precisely. The RGB device can emulate it pretty well anyway, except maybe for the monochromatic lighting. Well, maybe that too with some color manipulations, but I could never entirely figure out how the monochromatic lighting should differ from color lightning exactly, and which colors would need to be changed and how.

In theory, the Ramp device can also generate palette entries as long as the entire palette is not already filled, but I'm not sure if any games actually need that, since most of them seem to supply a complete palette already anyway.

Also assuming that this problem isn't even related to the driver, the fix wouldn't be necessary in DDI, right?

The Ramp device is a pure software rendering device. It doesn't even need a GPU. It is (or was) implemented in the DirectX runtime itself, without any driver involvement.

BEENNath58 commented 7 months ago

So in essence, it's probably similar to what DDrawCompat does with the SoftwareDevice=hal setting.

Good assumption, I think that's correct looking at the way it performs.

A last piece to the puzzle:

Wine has a ddraw directory in the source, but the d3dim and d3dim700 directories are pretty empty. Ddraw directory had connections to d3dlight, d3dviewport and such; but otherwise how the Wine d3d emulation works on Linux?

elishacloud commented 7 months ago

The Ramp device is a pure software rendering device. It doesn't even need a GPU. It is (or was) implemented in the DirectX runtime itself, without any driver involvement.

Does that mean it may be possible to get the ddraw files from an old Windows (XP or 7) installation and then shoehorn them (copy the dll's into the games directly and force the game to use these rather than native Windows' ones) somehow into an application that uses the Ramp device on a modern installation of Windows? This way the game can work like it did in the past.

narzoul commented 7 months ago

Wine has a ddraw directory in the source, but the d3dim and d3dim700 directories are pretty empty. Ddraw directory had connections to d3dlight, d3dviewport and such; but otherwise how the Wine d3d emulation works on Linux?

I'm not really familiar with Wine's implementation, but from a quick look they probably just implemented all the D3D functionality within ddraw.dll. Like I said, no games should actually require a separate d3dim.dll/d3dim700.dll, those are just helper DLLs for ddraw.dll that MS put in separate modules for some reason. It's an implementation detail not required to be followed by any alternative implementation.

Does that mean it may be possible to get the ddraw files from an old Windows (XP or 7) installation and then shoehorn them (copy the dll's into the games directly and force the game to use these rather than native Windows' ones) somehow into an application that uses the Ramp device on a modern installation of Windows? This way the game can work like it did in the past.

Yes, I tested this in the past and it seemed to work. It doesn't have to be that old, see here: https://github.com/narzoul/DDrawCompat/issues/22#issuecomment-616197074

From some more recent testing, I found that some of the very old D3D DLLs actually have worse performance on new systems even for HAL, so it's probably better to use the most recent working version.

narzoul commented 7 months ago

Yes, I tested this in the past and it seemed to work. It doesn't have to be that old, see here: https://github.com/narzoul/DDrawCompat/issues/22#issuecomment-616197074

Just to clarify, you shouldn't use old versions of ddraw.dll itself, since that one may have stricter ties to newer WDDM versions and such, so old versions might not work at all. You should only use d3dim.dll, which is where the Ramp device implementation is.

elishacloud commented 7 months ago

Just to clarify, you shouldn't use old versions of ddraw.dll itself, since that one may have stricter ties to newer WDDM versions and such, so old versions might not work at all. You should only use d3dim.dll, which is where the Ramp device implementation is.

I see. Thank you.

BEENNath58 commented 7 months ago

I'm not really familiar with Wine's implementation, but from a quick look they probably just implemented all the D3D functionality within ddraw.dll. Like I said, no games should actually require a separate d3dim.dll/d3dim700.dll, those are just helper DLLs for ddraw.dll that MS put in separate modules for some reason. It's an implementation detail not required to be followed by any alternative implementation.

Ok I compared stolen MS stuff vs Wine and that seems to be the case. That's all I needed

Also the DDKs (5.0 and 7.0) have a decent documentation for the DX working and the DDI. It is just that Windows 7 decided to install all files except the doc ones 🤦