VOGONS


dgVoodoo 2 for DirectX 11

Topic actions

  • This topic is locked. You cannot reply or edit posts.

Reply 3740 of 3949, by KainXVIII

User metadata
Rank Member
Rank
Member

Minor flickering in foggy distance in Enclave on 8 level, also some minor texture flickering on models, not very serious 😊
PS - forcemin24bit does not help

20180828205422_1.jpg
Filename
20180828205422_1.jpg
File size
760.46 KiB
Views
1107 views
File license
Fair use/fair dealing exception

Reply 3741 of 3949, by UCyborg

User metadata
Rank Member
Rank
Member

I recently stumbled upon an interesting problem that can be observed natively with AMD drivers (since at least somewhere around 2016 as far as I'm aware). Even though IDIrect3D3::EnumZBufferFormats reports 32-bit z-buffer with depth mask 0x00ffffff (so effectively 24-bit with the remaining 8 bits reserved for stencil buffer), trying to read the buffer reveals you've actually got full blown 32-bit buffer containing float values. dgVoodoo also supports this exact format; it reports all supported formats correctly, so you get exactly what you ask for. 😀

I updated Drakan to support 32-bit floating point depth buffer and added option to force reporting 32-bit depth mask to depth value reading function, so lens flares can work natively with AMD drivers. Though today's drivers bring another problem; just locking the z-buffer causes graphical corruption. Oddly, forcing 4x MSAA gets rid of corruption. I haven't tried higher values, but 2x MSAA didn't do it.

Anyway, back to dgVoodoo specifics. If you force Drakan to run at higher resolution, then reading depth buffer produces different results; lens flares are always visible, even when obscured by very thick level geometry, when they normally wouldn't be. Is this a limitation of resolution forcing or something that could be fixed?

Arthur Schopenhauer wrote:

A man can be himself only so long as he is alone; and if he does not love solitude, he will not love freedom; for it is only when he is alone that he is really free.

Reply 3742 of 3949, by Dege

User metadata
Rank Oldbie
Rank
Oldbie
taeir wrote:
I also debugged the problem with DebugView++ and the debug version of dgVoodoo 2.55.3 […]
Show full quote
Cyrem wrote:
Like Jessietail a few pages back, I have a similar issue with LEGO Rock Raiders. v2.53 was the last working version(with some li […]
Show full quote

Like Jessietail a few pages back, I have a similar issue with LEGO Rock Raiders. v2.53 was the last working version(with some lighting issues) of voodoo before the newer versions caused problems running the game. I have a GTX 970, tried the latest version 2.55.3 and the game locks up a few seconds into a level after the mission briefing disappears.

Not sure if it this helps but this is the last error it x32dbg logs. Tried different levels in case it was particular, same error every time.

EXCEPTION_DEBUG_INFO:
dwFirstChance: 1
ExceptionCode: E06D7363 (CPP_EH_EXCEPTION)
ExceptionFlags: 00000001
ExceptionAddress: 75E4DDC2 kernelbase.75E4DDC2
NumberParameters: 3
ExceptionInformation[00]: 19930520
ExceptionInformation[01]: 0019E3AC
ExceptionInformation[02]: 6F8F0570 d3d11.6F8F0570
First chance exception on 75E4DDC2 (E06D7363, CPP_EH_EXCEPTION)!

In the leadup to that (other than Guard page exeptions, the last debug string from voodoo was

DebugString: "[dgVoodoo] INFO: DirectDrawSurface (09881510)::QueryInterface: Aggregated Direct3DTexture (17B65AD8) object is created and initialized.\n"

Thanks mate!

I also debugged the problem with DebugView++ and the debug version of dgVoodoo 2.55.3

It (sometimes) reports the (game) error

C:\Dev\SourceSafe\gods98_dx6\gods98\src\Files.c(330) : Error in call to File_Open

(Though this might just be the game trying to load a sound file for the item)

But the problems start after the message.

D3D11: Removing Device

Then the following warning is spammed:

[dgVoodoo] WARNING: DirectDrawSurface (09E21B40)::Lock: Failed, HRESULT: DDERR_GENERIC

From that point onwards, all rendering stops (the game looks frozen). However, the game continues to run and you can still perform actions in the game (indicated by the sounds). The game remains fully operational aside from not showing anything.

There are still a lot of DirectDraw calls that do seem to succeed (don't show signs of failing), but these are not reported as dgVoodoo messages.

As Cyrem stated, this error did not occur under version 2.53
(After a while of gameplay (~15 minutes) I do get this same problem. This might have a different cause however)

Last time when I tried this game I did that on an AMD card so everything was working fine.
However I could reproduce the same freezing on nVidia. I found a small bug in dgVoodoo, feeding D3D11 with invalid parameters which causes D3D11 device to be removed with nVidia drivers.
Anyway, I fixed it and now it runs fine. At least, no freeze but I'm not sure about lighting issues.

UCyborg wrote:

Anyway, back to dgVoodoo specifics. If you force Drakan to run at higher resolution, then reading depth buffer produces different results; lens flares are always visible, even when obscured by very thick level geometry, when they normally wouldn't be. Is this a limitation of resolution forcing or something that could be fixed?

dgVoodoo's 32 bit depth buffer is actually float (R32), not integer (D32) because that's what modern cards support. It's a problem in theory because DDraw defines only unorm integer formats, so D32 is expected for a 32bit Z-buffer when locking for CPU-access.
Are you comparing float to float values in Drakan for lens flare?

Reply 3743 of 3949, by UCyborg

User metadata
Rank Member
Rank
Member
Dege wrote:

dgVoodoo's 32 bit depth buffer is actually float (R32), not integer (D32) because that's what modern cards support. It's a problem in theory because DDraw defines only unorm integer formats, so D32 is expected for a 32bit Z-buffer when locking for CPU-access.
Are you comparing float to float values in Drakan for lens flare?

Yes, I modified that function to treat values in depth buffer as float if the mask is 0xFFFFFFFF. At first I didn't actually modify the EnumZBufferFormats callback function to prefer the buffer with mask 0xFFFFFFFF, I only did it afterwards after seeing the 32-bit buffer with dgVoodooo and thought: Hey, those values are definitely float, that means I can skip the code converting the original 32-bit float value to compare against down to integer 24-bit or 16-bit format and use it directly for comparisons.

So the changes I did in the lens flare function in Dragon.rfl are the following:

  • Got rid of the loop that constructs the mask from the bitness value. This is the part you modified to correct the mask. I figured it was entirely unnecessary since the helper function in Drakan.exe that actually calls IDIrectDrawSurface4::Lock could be easily modified to return the mask instead of the bitness value through the pointer passed to it.
  • If we got 0xFFFFFFFF mask, treat the values in the depth buffer as float, otherwise as integer.
  • Added an optional setting that makes the helper function i mentioned earlier return 0xFFFFFFFF mask instead of what DirectDraw returned.

Everything still works correctly with dgVoodoo, except when resolution forcing is involved, then the lens flares are rendered when they normally wouldn't be. At least that's what happens on my end. This doesn't have anything to do with the changes I mentioned, it's a separate issue that occurred before I implemented said changes.

You bring a good point about DirectDraw not defining anything bur pure integer depth buffers. This is something I wasn't sure about myself. I have a hard time finding accurate information regarding these things. So with this mind, in the case you ran the game on some older card that actually exposes 32-bit depth buffer with mask 0xFFFFFFFF and behaves accordingly to DIrectDraw spec, my code would fail since it assumes pure 32-bit depth buffers are in float format. The impression I got is that 32-bit z-buffer with 8 bits reserved for stencil was the norm. So the odd case of getting pure 32-bit integer buffer would happen...when...? With some professional grade card?

I can easily change the callback function back like how it was, then depth buffer will only be interpreted as float when explicitly requested by the user. It doesn't make practical difference with dgVoodoo either way, I'm cool with that and there's still an option if you want to run on AMD cards without dgVoodoo for some reason... Or maybe instead of having that option, just check if any of the most significant bits are set when reading depth buffer and if they are plus if the buffer is known to be 32-bit, assume the buffer is 32-bit float? Sounds like another hack to me that isn't guaranteed to work universally.

There's this guy over on Arokh's Lair forums that made an automated installer for Drakan that updates it with unofficial patch and a bunch of player created levels. He believes things should be made as easy as possible and that also means the game should run 100% correctly out-of-the-box WITHOUT dgVoodoo and WITHOUT the user needing to tweak any or at least most settings. So it has an option to install dgVoodoo, but apparently the installer's target audience tends to choose not to install it. Maybe they would if he didn't describe dgVoodoo just as a fancy way to get anti-aliasing and anisotropic filtering.

Personally, I see no point in spending too much time ensuring native compatibility. dgVoodoo is a great piece of software and not using it with old games with modern graphics cards is just plain ignorance. Some tricks just don't work as advertised anymore natively and there are other advantages to using it.

Edit: OK, so it's not that hard to connect the dots. Looking at D3DFORMAT enums from DirectX 8.1 SDK and comparing it to the list here and it's clear that there's no such thing as floating point depth format in Direct3D 8.1 and earlier.

Arthur Schopenhauer wrote:

A man can be himself only so long as he is alone; and if he does not love solitude, he will not love freedom; for it is only when he is alone that he is really free.

Reply 3744 of 3949, by Dege

User metadata
Rank Oldbie
Rank
Oldbie

I tried your latest patch for Drakan and indeed, 32 bit z doesn't work. For me, even with unforced res/msaa.
I can't see problems on dgVoodoo side, but, checking out the code reading z-values back, I don't understand something. It seems to me that the code always reads z-values from the beginning of the sun scanline:

Drakan32bitz.png

UCyborg wrote:

The impression I got is that 32-bit z-buffer with 8 bits reserved for stencil was the norm. So the odd case of getting pure 32-bit integer buffer would happen...when...? With some professional grade card?

Format descriptor is a bit misleading in DDraw: D24S8 is a 32 bit buffer since each pixel takes 4 bytes, but the z-mask is 0x00FFFFFF and the stencil mask is 0xFF000000, indicating that z-values are only 24 bit.
D32 is also a 32bit buffer with z-mask 0xFFFFFFFF and stencil mask 0x0. Luckily, in later API's the formats are named constants without bitmasks and fixed rgb (or whatever) component order.
The problem with float z-buffer is that D32 isn't D32 as expected but R32 😀. And yes, float component types appeared after DX8.

UCyborg wrote:

Personally, I see no point in spending too much time ensuring native compatibility. dgVoodoo is a great piece of software and not using it with old games with modern graphics cards is just plain ignorance. Some tricks just don't work as advertised anymore natively and there are other advantages to using it.

Yep, that's why I didn't bother with an R32 to D32 conversion. Old apps typically don't use 32 bit z-buffers or they do that in a buggy way, and locking depth buffers is even less common.

Reply 3745 of 3949, by UCyborg

User metadata
Rank Member
Rank
Member
Dege wrote:

I can't see problems on dgVoodoo side, but, checking out the code reading z-values back, I don't understand something. It seems to me that the code always reads z-values from the beginning of the sun scanline:

Wow, thanks for pointing that out! I'm an idiot...I purged part of the code that I shouldn't...No wonder lens flares were visible through the tree in one particular spot.

I have some quick questions about some parts of the code (here's the stable version without broken additions):

CPU Disasm
Address Hex dump Command Comments
687A3D3C |. 8B4424 20 MOV EAX,DWORD PTR SS:[ESP+20] ; Get buffer bitness value
687A3D40 |. 33ED XOR EBP,EBP ; Very important
687A3D42 |. 99 CDQ ; Accidentally deleted this whole part
687A3D43 |. 83E2 07 AND EDX,00000007
687A3D46 |. 896C24 14 MOV DWORD PTR SS:[ESP+14],EBP
687A3D4A |. 03C2 ADD EAX,EDX
687A3D4C |. C1F8 03 SAR EAX,3 ; We got the size of individual value in the buffer now, correct?
687A3D4F |. 25 FFFF0000 AND EAX,0000FFFF ; What's the purpose of this?
687A3D54 |. 7E 33 JLE SHORT 687A3D89 ; Skip constructing the mask if something strange happened?
687A3D56 |. 33C9 XOR ECX,ECX
687A3D58 |. 894424 14 MOV DWORD PTR SS:[ESP+14],EAX
687A3D5C |. 894C24 18 MOV DWORD PTR SS:[ESP+18],ECX
687A3D60 |> BA FF000000 /MOV EDX,0FF ; Constructing the mask from the buffer bitness
687A3D65 |. D3E2 |SHL EDX,CL
687A3D67 |. 8B4C24 18 |MOV ECX,DWORD PTR SS:[ESP+18]
687A3D6B |. 83C1 08 |ADD ECX,8
687A3D6E |. 894C24 18 |MOV DWORD PTR SS:[ESP+18],ECX
687A3D72 |. 0BEA |OR EBP,EDX
687A3D74 |. 8B5424 14 |MOV EDX,DWORD PTR SS:[ESP+14]
687A3D78 |. 4A |DEC EDX
687A3D79 |. 895424 14 |MOV DWORD PTR SS:[ESP+14],EDX
687A3D7D |.^ 75 E1 \JNZ SHORT 687A3D60
687A3D7F |. 81E5 FFFFFF00 AND EBP,00FFFFFF ; Correcting the constructed mask for 32 bit buffer with only 24 bits used for depth

So yeah, can't wrap my head around the part that conditionally skips constructing the mask. Maybe this one's redundant?

And then this chunk in the loop that compares the actual values in the depth buffer:

CPU Disasm
Address Hex dump Command Comments
687A3DFD |> /8B01 |/MOV EAX,DWORD PTR DS:[ECX]
687A3DFF |. |23C5 ||AND EAX,EBP
687A3E01 |. |8B6C24 2C ||MOV EBP,DWORD PTR SS:[ESP+2C]
687A3E05 |. |3BC5 ||CMP EAX,EBP
687A3E07 |. |72 04 ||JB SHORT 687A3E0D ; Is this OK or would JBE make more sense?
687A3E09 |. |FF4424 18 ||INC DWORD PTR SS:[ESP+18]
687A3E0D |> |8B6C24 14 ||MOV EBP,DWORD PTR SS:[ESP+14]
687A3E11 |. |8D04B6 ||LEA EAX,[ESI*4+ESI]
687A3E14 |. |03C8 ||ADD ECX,EAX
687A3E16 |. |4A ||DEC EDX
687A3E17 |.^\75 E4 |\JNZ SHORT 687A3DFD

Welp, time to fix that mess. I hope at least the float value at [ESP+4C] really is what I think it is.

Edit: OK, this is better. No more oddities with or without resolution forcing, lens flare visibility checking works as expected. That missing code was the problem. Also restored previous code for selecting z-buffer format, so it'll always aim for 32-bit with mask 0x00ffffff. But the mask reported to lens flare function can still be overridden in Arokh.ini file to serve as a signal to load values in depth buffer as float to workaround issues when running natively. Seems good enough workaround for otherwise obscure feature.

I've been told some Drakan players have problems with dgVoodoo's anti-aliasing feature; the text gets blurred, but it doesn't happen when running natively and forcing anti-aliasing through drivers. I have been unable to reproduce the issue; it's clear on all machines I could try it with different GPUs (NVIDA, AMD and Intel). Odd...considering it's a standard feature of the API, hard for anything to go wrong I think.

Arthur Schopenhauer wrote:

A man can be himself only so long as he is alone; and if he does not love solitude, he will not love freedom; for it is only when he is alone that he is really free.

Reply 3746 of 3949, by Dege

User metadata
Rank Oldbie
Rank
Oldbie

Yes, it's working again. When Force32BitDepthMask is set to 1, then shouldn't the game create a float z-buffer? Now, when this option is enabled, my depth buffer is still D24S8 but the lansflare code expects floats.

687A3D3C  |.  8B4424 20     MOV EAX,DWORD PTR SS:[ESP+20]            ; Get buffer bitness value
687A3D42 |. 99 CDQ ; Accidentally deleted this whole part
687A3D43 |. 83E2 07 AND EDX,00000007
687A3D46 |. 896C24 14 MOV DWORD PTR SS:[ESP+14],EBP
687A3D4A |. 03C2 ADD EAX,EDX
687A3D4C |. C1F8 03 SAR EAX,3 ; We got the size of individual value in the buffer now, correct?
687A3D4F |. 25 FFFF0000 AND EAX,0000FFFF ; What's the purpose of this?
687A3D54 |. 7E 33 JLE SHORT 687A3D89 ; Skip constructing the mask if something strange happened?

Honestly, to me it doesn't make any sense. Bitness value is expectedly always <=32, so CDQ does nothing but zeroes EDX.

I think

687A3D3C  |.  8B4424 20     MOV EAX,DWORD PTR SS:[ESP+20]            ; Get buffer bitness value
687A3D4C |. C1F8 03 SAR EAX,3 ; /8
687A3D54 |. 7E 33 JLE SHORT 687A3D89 ; Skip lansflare testing if bitcount is less than 8, or trivially not divisable by 8

would be enough. Except if [ESP+20] can store some 'special' values like bitcount in its negative form, or sg like that, and the code is for handling that.

Reply 3747 of 3949, by UCyborg

User metadata
Rank Member
Rank
Member
Dege wrote:

When Force32BitDepthMask is set to 1, then shouldn't the game create a float z-buffer? Now, when this option is enabled, my depth buffer is still D24S8 but the lansflare code expects floats.

The idea was to keep things simple and only provide this option as a workaround if someone wants to run natively where AMD's drivers (or any other vendor's future drivers really) only ever report mask 0x00ffffff through EnumZBufferFormats callback function, even though you actually get full blown 32-bit floats in the buffer. Not meant to be used with dgVoodoo. You can still verify handling of floating point code with dgVoodoo if you start the game with debugger, navigate to address 0x478522 and correct the mask there (there's your snippet that's part of EnumZBufferFormats callback).

Dege wrote:

Honestly, to me it doesn't make any sense. Bitness value is expectedly always <=32, so CDQ does nothing but zeroes EDX.

So I suspected. There also used to be FPU instruction that loads the mask value that was written like FILD QWORD PTR SS:[...]. Right before it, upper 32 bits of QWORD were zeroed.

Dege wrote:
I think […]
Show full quote

I think

687A3D3C  |.  8B4424 20     MOV EAX,DWORD PTR SS:[ESP+20]            ; Get buffer bitness value
687A3D4C |. C1F8 03 SAR EAX,3 ; /8
687A3D54 |. 7E 33 JLE SHORT 687A3D89 ; Skip lansflare testing if bitcount is less than 8, or trivially not divisable by 8

would be enough. Except if [ESP+20] can store some 'special' values like bitcount in its negative form, or sg like that, and the code is for handling that.

Got it. [ESP+20] is actually straight copy of a DWORD dwZBufferBitDepth coming from DDSURFACEDESC2.DDPIXELFORMAT struct filled by IDirectDrawSurface4::Lock. Normally, nothing odd should ever come from there, just what we already except. If some bits were triggered by faulty hardware, then you already have bigger problems. 😉

There's also a check right after IDirectDrawSurface4::Lock that verifies if obtained pointer is non-zero and if it's zero, unlocks the surface and bails out. No reason for the call to return DD_OK while filling the pointer variable with a zero. I guess it's all just extra defensive programming.

Edit:

UCyborg wrote:

I've been told some Drakan players have problems with dgVoodoo's anti-aliasing feature; the text gets blurred

As suspected, it was the user error. Actual cause was forcing anisotropic filtering. Forcing that doesn't work natively, but it does with dgVoodoo. Either way, it was never promised to be compatible.

Arthur Schopenhauer wrote:

A man can be himself only so long as he is alone; and if he does not love solitude, he will not love freedom; for it is only when he is alone that he is really free.

Reply 3749 of 3949, by Cyrem

User metadata
Rank Newbie
Rank
Newbie
Dege wrote:

Last time when I tried this game I did that on an AMD card so everything was working fine.
However I could reproduce the same freezing on nVidia. I found a small bug in dgVoodoo, feeding D3D11 with invalid parameters which causes D3D11 device to be removed with nVidia drivers.
Anyway, I fixed it and now it runs fine. At least, no freeze but I'm not sure about lighting issues.

Excellent, looking forward to trying the next version. The lighting issues aren't as much an issue since 2.54... there are a few oddities here and there, I'll post them some other time. Main thing was just getting the game working again on nVidia. 😀

Reply 3750 of 3949, by David_OSU

User metadata
Rank Newbie
Rank
Newbie

Tested Carmageddon 2 with dgVoodoo2 in both Glide and D3D modes. The glide emulation is providing 70% higher frame rate than D3D, with rendering settings identical between the two. Is this typical for dgVoodoo2? I expected the performance to be about the same with either mode.

Reply 3751 of 3949, by Dege

User metadata
Rank Oldbie
Rank
Oldbie
Cyrem wrote:

Excellent, looking forward to trying the next version. The lighting issues aren't as much an issue since 2.54... there are a few oddities here and there, I'll post them some other time. Main thing was just getting the game working again on nVidia. 😀

You can already test it with WIP50:
WIP versions

David_OSU wrote:

Tested Carmageddon 2 with dgVoodoo2 in both Glide and D3D modes. The glide emulation is providing 70% higher frame rate than D3D, with rendering settings identical between the two. Is this typical for dgVoodoo2? I expected the performance to be about the same with either mode.

I don't know. Even Carma2 DX backend can do much more work than its 3dfx one. Just for curiosity, what were the FPS's for them?

Reply 3752 of 3949, by David_OSU

User metadata
Rank Newbie
Rank
Newbie

On Carma2, worst-case FPS is at the start of the race when the camera flies down to the starting line with all cars visible. On D3D it would drop down to 15 FPS, while on Glide it would drop to 25 FPS. This is a heavily modified install of Carma2 loaded up with a bunch of high-poly cars and the draw distance is maxed out. During gameplay with only 1 other car on screen, the FPS was around 35-50, with Glide about 5 FPS faster.

Reply 3754 of 3949, by FANTOMAS

User metadata
Rank Newbie
Rank
Newbie
David_OSU wrote:

On Carma2, worst-case FPS is at the start of the race when the camera flies down to the starting line with all cars visible. On D3D it would drop down to 15 FPS, while on Glide it would drop to 25 FPS. This is a heavily modified install of Carma2 loaded up with a bunch of high-poly cars and the draw distance is maxed out. During gameplay with only 1 other car on screen, the FPS was around 35-50, with Glide about 5 FPS faster.

I installed C2 yesterday : NGLIDE 2.0 : @3840X2160 (DSR 4X) + 4X4 supersampling(nvidia inspector) = 16 K interpolation ==== 0 problem. (no frame drop @60 hz)

Config : ASUS PRIME H270 PRO / CORE i7-7700/ 16 GB DDR2400 / MSI GTX1060 6GT OCV1 @391.01/ Moniteur @1080p ...WINDOWS 10 64 bits V1803 @17134.285

Reply 3755 of 3949, by Dege

User metadata
Rank Oldbie
Rank
Oldbie
FulValBot wrote:

Serious Sam The First/Second Encounter still got a black screen if i try to copy d3d8.dll in bin folder

This with Direct3d

Yes, AFAIR I could only run it in forced windowed mode. It's still subject to fix.

FANTOMAS wrote:

I installed C2 yesterday : NGLIDE 2.0 : @3840X2160 (DSR 4X) + 4X4 supersampling(nvidia inspector) = 16 K interpolation ==== 0 problem. (no frame drop @60 hz)

I get the same 60fps with the vanilla game installation with 8x msaa, dsr4x 5120x2880.

Reply 3756 of 3949, by David_OSU

User metadata
Rank Newbie
Rank
Newbie
Dege wrote:

I get the same 60fps with the vanilla game installation with 8x msaa, dsr4x 5120x2880.

Either my system is too slow (3GHz Pentium D and GT430) or something must be hosed with my Carma2 installation or config. Seems like I should get 60 FPS at 1080p. Thanks for the info (Dege & Fantomas).

Reply 3757 of 3949, by Cyrem

User metadata
Rank Newbie
Rank
Newbie
Dege wrote:
Cyrem wrote:

Excellent, looking forward to trying the next version. The lighting issues aren't as much an issue since 2.54... there are a few oddities here and there, I'll post them some other time. Main thing was just getting the game working again on nVidia. 😀

You can already test it with WIP50:
WIP versions

Tested it and it no-longer freezes! perfect.... but then found another issue that I'm hoping you could test.

I was just playing the level "Driller Night!" upon discovering a new cavern after drilling northward the game camera seems to fly go way out of bounds and the map goes black. Everything else works though.

This is what happens after opening a new cavern: http://prntscr.com/kuaq7y

Thanks mate!

Reply 3758 of 3949, by ZellSF

User metadata
Rank Oldbie
Rank
Oldbie

Jeff Wayne's War of the Worlds mouse issues was fixed in the latest dgVoodoo2 version. Still crashes when changing resolution, but not sure that is dgVoodoo2's fault (other wrappers don't like it either). Figured out the crash in options menu was because I only gave it one supported resolution. As long as dgVoodoo2 enumerates at least two supported resolutions it will work fine. Which is a bit weird, since at the time the game was released it was possible someone would have a computer that only supported 640x480. Very unlikely, but possible.