Monday, January 16, 2012

The Problem with Refresh Rate

A very productive time fooling around with video modes - I know that I said I wasn't going to work any more on DirectQ's video code until I moved to D3D11, but I decided to put in some prep-work on restructuring in advance of this.

Historically, DirectQ hasn't supported refresh rate changes (aside from a brief time when I had it in but it crashed horribly). The reasons for this are a combination of two main factors: an initial desire on my part to keep the video mode list as close to ID Quake's as I could, and an inability to map the mode list returned by Direct3D to this.

Something had to go in order to enable this, and refresh rate was the chosen victim.

Most of the time when you see refresh rate offered as an option along with resolution, you'll see them as two separate options - first you pick your resolution, then you pick your refresh rate, then you hit an "Apply" option and away you go.

That's not actually the way things work at all.

Refresh rate is, in fact, quite closely tied to your chosen resolution. An example, I hear you cry. OK, here's the mode list from one of my machines:

ModeWidthHeightRefresh Rate
064048060
164048059
264048067
364048072
464048075
572048056
672048060
772048072
872048075
972057656
1072057660
1172057672
1272057675
1380060056
1480060060
1580060072
1680060075
17102476860
18102476870
19102476875
20115286460
21115286475
22128072060
23128072059
24128076860
25128080060
26128096060
27128096075
281280102460
291280102475
30136076860
31136076875
32136676860
33136676875
34144090060
35144090075

A few things should be obvious from this, including the fact that no matter how much you may want a 320x200 mode for nostalgia's sake, if D3D don't report it then you ain't getting it.

The important one for this discussion is that not all refresh rates are available with all modes. Look at those ones available with 640x480 - where'd that 59 come from? And 720x480, 720x576 and 800x600 have a 56hz rate available that's nowhere else. 800x600 has 72 but not 70 whereas 1024x768 is the other way around.

So, what this comes down to is - when selecting a resolution, you also must select a refresh rate to run at as well, otherwise your mode selection is incomplete, and if you fall back on some kind of "default refresh rate" (like the one your desktop is running at) you risk crashing.

So when this finishes up I'm going to have perfect mode changing, perfect refresh rate selection and everything running clean and neat (I've been able to get rid of nearly 600 lines of disgusting code).

A few final notes.

I've begun to suspect that this might lie behind some of the problems that some people are having with trying to start up DirectQ. They may be running their desktop at a certain display mode and attempting to force a fullscreen mode for which their desktop's refresh rate is unavailable. If so - it's always worth trying to start up in a windowed mode instead. Windowed modes are safe, and if nothing else will confirm that the cause of the crash is in the transition to fullscreen.

Direct3D 11 enforces this even tighter. It won't even let you initially start in a fullscreen mode (well, it will, but the documentation issues dire warnings not to) - instead you must start windowed always - irrespective of the user preferences - and then switch to fullscreen if the user wants to. It also enforces that a fullscreen mode must be a properly enumerated mode, so there's going to be no "trying things out and seeing if they work".

Alt-tabbing and transitions between fullscreen and windowed modes have been made safer by placing the resetting/resizing of the window frame after the device reset. It's previous placement had actually caused a second device reset.

The video mode list is going to change again. To protect people from any unwanted consequences of this I'm going to change the cvar names, so your initial startup will be 640x480 windowed.

No comments: