tak pani (a hlavne Ren a jeho Esoteria), prvy krat v historii tu mame kompletnu, o nic neukratenu emulaciu glide cez dx10.1/dx11. vyhody - obrovska kompatibilita (kedze wrapper de fakto vytvara virtualnu v1/v2/rush/banshee na gpu), nevyhoda - vyzaduje velmi slusnu grafiku (autor uvadza gtx560ti alebo ekvivalentne ako optimum).
Kód: Vybrat vše
dgVoodoo 2.13: Glide to Direct3D11 Wrapper
Released: March 7, 2013
I wanted to get experience in Direct3D11 and its Shader Model 4/5.
I was thinking about what to code and felt that small primitive example
applications would not be enough. I wanted some other bigger project
because there is no other way to truly learn something.
Since I like reverse engineering, emulation and cool API implementations I
began to ponder on whether Glide and its pipeline could be implemented
perfectly and easily using the new shader model(s) and apparate. I got to
the answer "yes" so decided to quickly rewrite dgVoodoo from the ground.
It is a good project to start with.
(*So, it is not an update, it does not have anything to do with the old 1.x
versions. Completely brand new code architecture, new approach of implementation,
etc. The setup looks like its predecessor but that's all. I was even thinking
on not to name it dgVoodoo.)
(No, I do not want to get back into the Glide-businness. It is just a
learning project and I share the result to the public like other things
ShaderModel 4.1 with its structured buffers, integer types and operations
makes it possible to emulate Glide perfectly. Ok, it needs a thousand of
horsepowers so a strong hardware is required to use it with good framerates.
In fact, this version runs the complete (chip) emulation on the GPU with
minimal CPU interaction.
There are no "supported" and "unsupported" applications. If something shows
graphical glitches or defects then that must be because of a programming
bug and not a limitation of the underlying implementation.
But of course, there are tested and untested applications, hehe. :)
- Operating system: Windows Vista/7/8 with DirectX11 installed.
- Hardware: GPU supporting DirectX feature level 10.1.
4. Tested on
- Windows 7
- Intel HD 2000: Seemed to work OK but with low framerates, not
- GeForce 8600 GT: I used a special build for this one since it
does not support feature level 10.1. It worked
OK as well (apart from lack of mipmapping) but
with low framerates too.
- ATI Radeon HD 6450: Works OK and usable with low resolutions.
- GeForce GTS 450: Works OK and usable. Larger resolutions like
1280x1024 or larger can cause performance drop
in specific applications. (I'm hearing the howl:
is 1280x1024 large resolution?? Haha.. But do not
forget, it uses a lot power for exact emulation.)
- GeForce GTX Ti560: Works like a charm.
There is no installer for dgVoodoo beacuse you can copy its dlls anywhere
you want (to use). If u like it and want to use as the only global Glide
wrapper on your machine then copy them to the system folder.
A Glide wrapped application can start up either in windowed or full screen
mode (it is controlled by setup, see later). Also, you can switch between
them during the gameplay by Alt-Enter. See 'Known issues' for more.
As different options might wanted to be used for particular applications,
I kept the concept of local/global configurations.
The configuration data is not stored in the dlls themself anymore.
It is in a separate file named 'dgVoodoo.conf'. All of the glide dlls
(glide 2.11, glide 2.43, glide 3.0) uses this file.
When the glide wrapped application starts, dgVoodoo tries to read
config data from the same folder where the application (exe) resides.
If it is not found then it looks for the file in the user's application
data folder. If none found then the default config is used.
In dgVoodooSetup you can choose a folder where you can save the current
configuration. After you chose a folder, it remains in the list permanently.
By default the user's application data folder is selected.
*New in 2.1: if an application tolerates losing focus without closing/minimizing
itself, you can configure it dynamically: when the setup starts up it builds
a list of detected running Glide wrapped applications and insert it into
the folder selector combobox. When you select such a running instance then
the current state of the application is read as config and most of the options
can also be changed. So, you can set resolution, msaa, brightness, etc on
the spot without restarting the application. When an option changes, it
takes effect at once. If the dialog gets cancelled or an other config
folder/instance is selected, all the changes gets cancelled as well.
Important to note:
- If the Glide wrapped app and the setup runs on different privilege levels
(admin/nonadmin) then the app won't appear in the instance list or they
cannot communicate to each other. Sorry for the inconvenience.
- Switching resolution or MSAA can only be performed perfectly if the
application re-renders everything on each frame. If it uses or keeps
previously (once-)rendered things like cockpits or similars then they will
be missing as will not get re-rendered.
(Why still need a setup at all? Well, now it's not for choosing from
millions of techical options due to weak glide implementation but for
fancy things, see the next chapter.)
6. Setup options
I did not wanted to have a lot of setup options like in the old version.
It is confusing and now needless, I removed all that crap.
I explain it below what ones I kept after all and why other useful
ones disappeared and what the new ones are:
- API: OK, since the only rendering API is Direct3D11 right
now, this one is pointless.
- Video card (adapter): In case you have more than one, let you choose
which one to use for rendering.
- Monitor (output): If you have multiple monitors then you can choose
which one to use for fullscreen mode.
"Default" means the primary monitor. Also, if default
is selected then switching from windowed to fullscreen
during playing a game selects the monitor containing
the largest part of the game window.
- Full Screen / Windowed: See section "Usage".
- Preferring centered/scaled full screen:
If the current resolution the Glide app using does not
match any natural resolution your adapter supports
then the display can be strethed out to fit all the
screen or its size can be left unchanged but centered.
- Color adjustments: Brightness and color intensity can be finetuned here.
The defaults are good in general so treat this as a
cool extra. (I'm using it in some cases for making colors
more vital to get a bit cartoon-like effect.)
- Keep window aspect ratio:
In windowed mode, when sizing the window, you can keep
the aspect ratio of the current resolution.
- 3Dfx card: Don't think of anything serious here. It only limits your
choice possibilities in respect of 'Onboard RAM',
'Texture memory' and 'Number of TMUs' according to the
card type. Some applications (like the miniGL driver)
may check for those values and won't work if one of them
is too high. So it is more handy to select a card type
to limit those values alltogether than configuring
one-by-one by heart.
*New in 2.1: Selected card type affects some exposed
capabilites. See techical info for more. List of different
card caps/behaviors may be extended in the future,
according to 3dfx specs.
- Onboard RAM: Videomemory without texture memory. Some application
compute by this value that what resolutions are supported.
- Resolution/MSAA: Since forcing them proved to be a good thing in practice,
I kept the possibility in this version too. Antialiasing
is new of course. Note that you can set your own custom
resolution: if you want, say 128x128, then just type this
string here and it gets saved when you OK the dialog.
- Number of TMUs: This version can emulate more than one Texture
- Texture mem size: Not much to say.
- Force bilinear filter: Not much to say.
- Disable mipmapping: I liked it in some games that looked nicer without
- Enable Glide-gamma ramp:
See section "Gamma Correction".
- Force VSync: Forces at least one vertical retrace before buffer swapping.
Use this option if something gets too fast.
- Force Emulating True PCI Access:
see section 'Some techincal info'
- 16 bit depth buffer: see section 'Tips'
- 3Dfx Watermark: Enables displaying the 3Dfx logo during the app animation.
You need the 3Dfx splash dlls for this. If they are
missing, no logo will be displayed.
- 3Dfx Splash screen: Enables splash screen at game/app startup.
You need the 3Dfx splash dlls for this. If they are
missing, no splash screen will be rendered.
- Pointcast Palette Driver Build:
see section 'Some techincal info'
Removed but (maybe) useful options:
- Screenshots: Did not have time&mood to code it, but you can capture
the screen easily in other ways, I think. :)
- Force trilinear mipmapping:
- Autogenerate mipmaps:
Since no real texturing takes place in the emulation,
there is no way to generate mipmaps for a particular
texture. It would have to be done on-the-fly which is
impossible. Also, trilinear filtering would end up in
more complex shader code which is complex enough right
- Texmem scaling to 4MB: It was specific to Red Baron 3D to be able to cache
more textures than with 4MB (to avoid texture corruption).
However uploading textures to the Voodoo TMUs are very
quick and virtually free now so I do not see the point
of scaling. No texture caching.
- Triple buffering: Did not work well with some games. Also, it would not
fit well into the current implementation. Glide has
3 buffers of which one may be an auxiliary buffer.
7. Gamma correction
A gamma correction curve can be set through the Glide interface. Since Glide
uses a linear curve by default it might not match the default or one's taste
and can look ugly (at least in the old days, I remember it looked ugly on CRTs).
For the standard see sRGB on google.
That's why the setup has the 'Enable Glide gammaramp' option: you can disable
the curve coming from Glide and let your monitor use the default.
*As taking a closer look into this, I realized that a linear curve is used by
the nowadays adapters by default but they probably post-calibrate it according
to the sRGB standard. So Glide's linear curve won't change anything to wrong.
I'm little confused about this. Back in the old days my real problem could be
that either brightness of my CRT was too high by default or sRGB was not
followed by the adapters therefore some gamma-adjusting game had really bad (pale
and really bright) look. I do not know it by now but won't remove the possibility
of disabling Glide gamma ramp. Test it on your monitor.
Color adjustments are supported in both fullscreen and windowed mode however
brightness is always calculated into the gamma ramp curve in fullscreen so
it has effect only if your adapter supports setting up gamma curves.
8. Some technical info
Unfortunately Glide cannot be implemented in practice as a standalone API which
is completely independent on the underlying hardware. If someone looks through
the Glide SDK then it is clear that this API is suited for the 3Dfx Voodoo
hardware and its registers. However there are rules even in Glide (as in other
APIs too) that must be observed in respect of driving the API. An application
should never assume anything about the hardware being driven even if it knows
what hardware it is driving. The application should get all the info from the
API and keep the driving rules.
However in practice there are some application violating those rules very hard.
Since Glide provides free direct access to the frame buffer it is typical to
utilize the properties of a real 3Dfx hardware connected to the PCI bus. For
example, writing to the frame buffer while it was requested to lock for reading,
swapping buffers while one/some of the buffers are locked and assuming that the
mapped pointers of buffers remains unchanged, using 2048 bytes as frame buffer
stride, or drawing simultaneously by the 3D hardware and LFB writes through the
PCI bus even when a buffer was locked with idle 3D hardware mode.
Most of them can be workarounded easily but there is one case which can cause
performance drop if emulated perfectly. This case is the mentioned simultaneous
writing. dgVoodoo can emulate this usecase but you must enable it explicitly so
I reluctantly inserted an option into the setup, named
'Force emulating true PCI access'. This is the only technical option related to
the quality of the implementation. The only application I know it must be used
for is Carmageddon, so it would be a pity to have it pointlessly enabled for
There is another strange option in the setup, namely 'Pointcast Palette driver
build'. Well, early 3Dfx hardware allowed separate texture palettes/ncc tables
for each TMU so this possibility was reflected in Glide 2.11 and 2.43. However,
latter 3Dfx hardware used a unified memory model meaning that only one global
palette/ncc could be set for all the TMUs. Glide3 don't even allow to set them
in any other way. The funny thing is that original Glide2 drivers internally
also forced the global palette/ncc thing despite the API allowed separate ones.
It was because of pushing the programmers towards the future hardware. But, maybe
there were drivers built for custom vendors with the capability of separate
tables. So if this option is enabled in the setup then such a driver build is
emulated. I don't think that any Glide application in the world requests such a
driver build so always keep this option disabled. It just makes the appearance
wrong if more than one TMU are used. This option is only for the sake of fullness.
dgVoodoo exposes the following capabilities according to the selected card
Card type FBI revision TMU revision Glide3 extensions
? (unexposable via dgVoodoo) 1 0 none
Voodoo Graphics (SST-1) 2 1 none
Voodoo Rush (SST-96) 2 1 CHROMARANGE
Voodoo2 2 1 CHROMARANGE, TEXMIRROR,
Voodoo Banshee 2 1 CHROMARANGE, TEXMIRROR,
Other (greater) 3 2 CHROMARANGE, TEXMIRROR,
9. Tips and known issues
- Forcing things (like resolution, antialiasing, texture filtering, etc) is
not a healthy thing. If an application or game uses low resolution or point
sampled textures or anything dissonant to the eye then it has reasons for
that. It is not because the programmers were so lame but of avoiding artifacts
that would otherwise get brought in (typical example is a bilinear filtered
texture with colorkey based transparency). If you force anything then
potentially get one of those artifacts. If you can live with it then it is ok,
use the wrapper in forced mode. If not then disable all forcings and use the
particular game or application in the mode it was designed for, because no
general method exists to fix such type of artifacts.
- Forced trilinear texture filtering is not available in this wrapper version
but an application can implement it by 2 drawing passes if one TMU is used.
If more than one TMU are enabled then it can be done by one pass. Since
more TMUs are generally used for drawing the same as with one TMU but with
less passes, enabling multiple TMUs can be useful even if the gpu is loaded
with heavier shader code. It depends. Try out both cases.
- Keep in mind that not all Glide application are usable in windowed mode. Some
of them behave very well while others may not at all. Since they were
designed for an environment with one monitor and exclusive fullscreen display,
an application can get minimized or simply quits when its window loses the
focus. Also, they may capture the mouse into a fix area and you cannot even
move the game window. Or worse: if this fix area is hardcoded and (so) is on
the primary monitor then you can play the game only on the primary monitor even
in fullscreen mode. dgVoodoo tries to workaround these cases by hiding some
events from the application but generally it is not enough.
- Controlling antialiasing cannot be done on per-primitive basis in Direct3D 11
when feature set larger than 10.0 is used. That is why antialiased drawing
is not emulated automatically in this version in any way (per-primitive or
per-edge). It can only be forced globally in the setup.
- Fullscreen gamma ramp may not be supported by your card. nVidia and ATI seem
to handle it as expected but (e.g.) Intel does not.
- When an application is being run in compatibility mode (Win98/XP etc) then
the user's application data folder is different than the OS default.
Therefore dgVoodoo cannot read the global config file and the default
config gets applied if no local config file is present. The preferred way
is creating a local config for such cases if other than the default needed.
(Perhaps using the user's appdata folder is not a too good idea after all,
I might change it later.)
- DosBox issue: if I got it right, Gulikoza's solution (which is great! Finally
I could play Tomb Raider with my own wrapper :), but I use Ykhwong's build)
cannot handle embedded frame buffer locks and assumes something about the lock
stride. If dgVoodoo uses 2048 bytes as stride (it should because a real voodoo
also uses 2048 for 16 bit locks and 4096 for 32 bit ones) then roughly only the
upper half of the screen is visible. That is the only reason of that this build
of dgVoodoo does not use 2048 bytes stride (in Glide2x).
Extreme Assault both applies embedded buffer locks and hard-utilize 2048
byte stride so this game does not work right.
- Emulating PCI access is optimized for applications locking and accessing the
LFB very frequently (per frame). Altough it provides faster lfb data access than
doing the normal way, I cannot recommend to use it in general for all apps.
Due to nature of the technique used it can cause slowdown in applications
that access the lfb "regularly", so that once or twice per frame.
Carmageddon 1 and Pyl are the only cases where it has to be used, afaik.
- A strange case: when I tried to run a Glide based scene-demo, TBC,
it always crashed at a certain point due to stack overflow. I had to
manually grow the reserved stack size of the exe file to get it to run.
Probably a real 3Dfx driver required smaller stack than a Direct3D11
- I run into a problem with NFS 3 Hot Pursuit: ugly z-fighting which is most
noticable with projected headlights. This game does not use depth bias
but utilize the inaccuracy of the 16 bit voodoo depth buffer when rendering
polygons onto each other (I'm not sure if it was intentional or just a bug).
If an app uses z-buffering then using a 16 bit depth buffer in the emulation
provides the correct and exact mapping of the z values, like on a real Voodoo.
And so NFS3 HP also works well with a 16 bit depth buffer. I was thinking on
how to workaround this problem or automate this mechanism but found no way.
So, reluctantly again, I exposed this into an option in the setup...
This is the second option related to the quality of the implementation,
10. Closing words
As for a completely new version of any piece of software, there are always
bugs in that, no matter how carefully it was coded. So, of course I'm sure
there are bugs in this version of dgVoodoo as well. They are intended to be
fixed in some new dgVoodoo releases until the wrapper does not get mature
(I didn't do extensive tests, especially on Glide3).
Despite the fast coding (recent 4 months or so because I wanted to finish before
the end of the world (epic failed) meanwhile still drink a lot of beer
(epic succeeded)) I was careful: I applied the DX11 debug layer all the time
to trace down any bug or API-misdriving and did not use any card-specific
feature but the ones feature level 10.1 guarantees.
11. Change list
2.13: - Improved PCI emulation for LFB access: heavy lfb-lockers like Carma1 or Pyl
SHOULD run much smoother now (see Tips for more)
- Glide3 fixings: bad color order with packed RGBA, uninitialized texchroma state
- General glide fixings: bug in glide setstate and clip rectangle
- Missing feature "fog with iterated z" is implemented along with minor shader
- Support for splash screen and shameless plug: dgVoodoo needs the 3Dfx splash
dlls to get it working (3DfxSpl2.dll, 3DfxSpl3.dll, all with version 22.214.171.124),
however I did not include them in the core dgVoodoo pack
- Minor modification for DosBox
- TMUnum selector combobox is fixed, I fcked it down last time
2.12: - More shader optimizations: most critical ones are reduced to 90% in size again
(So, by now, their size are 65% of the original. I hope I have not messed up
anything with them.)
- Optional 16 bit depth buffer (see Tips for why is that)
- Some fixings in Glide3 thanks to some unexpected API-driving (scene demo Virhe)
- Some bugs related to maintaining/switching/handling windowed/fullscreen state
- Voodoo2 with 1 TMU is no longer selectable in the setup; A Voodoo2 always have
2 TMUs and it is the default now because shaders are optimal enough now to
handle 2 TMUs
2.11: - Refactoring GPU querying to get it to work with ATI drivers
(ATI does not seem to handle them correctly, my code was always fooled into
infinite loop at a certain point)
- Further shader optimizations: most critical ones are reduced to 90% in size
- Minor cursor-issue related to losing window focus, fixed
2.1: - Potential stalling rendering (even on fast GPUs) when switching screen modes, fixed
- Shader optimizations: most critical ones are reduced to ~80% in size
- Ability to configure running Glide wrapped applications dynamically
(see section 'Configuring')
- Different exposed capabilities according to the selected card type
- More Dosbox compatibility
- Bug in gammaramp handling, fixed
- Bug in fogtable generating code, fixed
- Bug in PCI access emulation, fixed
- Forced vSync is enabled by default to avoid overkilling the GPU with
2.01: - Undrawn polygons when updating TMU memory, fixed
- Potentially bad drawing of strip-primitives in Glide3, fixed
- Malfunctioning LFB lock with 32bit formats when PCI emulation is
- Fullscreen/Windowed state was not always remembered between
2.0: The original version
edit: ale ta esoteria stale nic.