Wednesday, January 18, 2012

DirectQ Update - 18th January 2012

Another slight code reorganization - recovering default pool resources from a lost device or video restart has moved to the start of a frame rather than happening in place. This was done to prevent an old problem where you'd lose the device, then recover it, then a system event (such as a window resize) might cause you to lose it again immediately afterwards. Now it only recovers these resources once and only when it's been definitively determined that the device is good and we're running again.

This will all go away with D3D11, which much more sensibly has ResizeBuffers and ResizeTarget, allowing an almost complete bypassing of window system events (the only one you really need to handle is a WM_SIZE, and the handling for that is very well-defined, rather than the mix of voodoo incantations required by D3D9).

Mapshots have another small but important improvement. In order to take a mapshot properly it's necessary to go into a special mode in which 2D GUI overlay stuff is not drawn, then redraw the scene (twice because of the buffer swap), then exit the mode. In addition to the second screen redraw (required to put the original back buffer back where it was otherwise we'd be capturing from the former front buffer, which would still have the 2D stuff in it) this caused a momentary flicker on-screen. Simple solution was just to suppress the buffer swap at the end of the first redraw - goodbye second redraw, goodbye flicker, all is nice and solid looking.

That will also go away with D3D11 where I can just call R_RenderScene to overwrite the backbuffer, and will no longer need to fool around with BeginScene/EndScene calls and making sure that they're being called on the correct render target.

TGA screenshots are about 10 times faster than they were. This was inspired by my D3D11 screenshot code, and is mostly the D3D9 equivalent of it. The old code round-tripped through several IDirect3DSurface9s before saving out, which was painful. Screenshot gamma adjustment (scr_screenshotgamma, if I remember correctly) is now effectively free (previously it added a few more IDirect3DSurface9s to the round-trip - sheesh, what was I thinking?) PNG, JPG and DDS screenshots remain slow because of needing to compress, BMP screenshots are as fast as TGA, and I really recommend that nobody uses PCX (scr_screenshotformat). Only TGA has gamma adjustment right now, and is the recommended format. I'll very likely drop the other formats and go TGA only when I move to D3D11.

Not sure if I'm going to add multisampling to the video options menu after all; this would be nice to do but is complicated by the fact that available multisampling modes are dependent on the current video mode, and also the fact that it would be hugely stretching the capabilities of my current menu code to deal with that.

With hindsight I should have been passing a \0 delimited string (terminated with a second \0) to spin control types, but I'm not willing to do such an overhaul right now. Maybe another time.

Until then, the cvar is d3d_multisample, 0 (default) will disable it, values of 1 or up enable, the limit is hardware and video mode dependent, and be aware that some hardware can't support multisampling in windowed modes. It's name will be changing to vid_multisample in the next release, by the way (now that I have robust detection of when the mode list changes I want to go back to standardizing on "vid_" for all of these cvars - this will be the last time that happens; promise).

When exiting DirectQ from a fullscreen mode it will temporarily switch back to windowed before shutting down. This isn't for some cutesy reason like I think it looks cool or anything; it's a requirement of D3D11 and will be the behaviour once I port.

11 comments:

Anonymous said...

So pleased to see how hard you're hitting this, thanks for all your awesome work.

I do have one feature request and I only make it because doing so should be very, very easy, I'm not trying to ruin an afternoon. You can probably get it done over the course of a can of pepsi.

Portal 2 has Fullscreen, Windowed, and Windowed-With-No-Borders-At-All modes. For users of multiple monitors, the latter is awesome. I can play Portal 2 in a 1920x1080p windowless display on one screen, and still handle everything else on my other monitors, without having to alt-tab or wait for a refresh.

I don't think it would be tough to add and trick fullscreen is the best fullscreen for multimonitor users. =3

Thanks for reading this.

mhquake said...

Windowed with no borders should be easy enough. Technically it's just sending a different window style to the main window, and I'm already well set-up to make this quite painless. There is a certain amount of supporting infrastructure it needs: cvars, menu options, etc, but they should be OK.

=peg= said...

since I'm using multiple monitors, I'm all for fullscreen-windowed-mode as well ;)

mhquake said...

It's done.

Only remaining wrinkle is that it doesn't overlap the taskbar. That actually requires me to set the window as absolute foreground, which - as you might guess - causes havoc when you try to Alt-Tab away from it (it doesn't play nice with outh programs on your machine either).

mhquake said...

From what I can figure out, the ability to have a topmost window higher in the Z-order than the taskbar has been removed in Windows 7. Makes sense as the taskbar belongs to the user, not the program.

You'll just need to find something else to remove the taskbar while playing.

This doesn't affect regular fullscreen modes, of course.

Anonymous said...

will it always launch dead on in the center of the screen though?
Incase for example you put its output resolution to something ludicrous your monitor doesn't support.

I had that problem with a quake 2 client once, and it cause only the bottom left half of the main menu to be viewable, I didn't know the correct console commands at the time, so changing resolution was like finding a needle in a haystack in the middle of the night.

Just a consideration.
Also: will 1.9.0 have full compatability with RMQ?

mhquake said...

I force the window to center on launch (and when the mode changes, and when you alt-tab back) because the alternative is worse. I had one machine in work once where a program had somehow contrived to place itself some 5000 pixels off to the right - when running at a 1024x768 resolution. Could never get it back (at the time I didn't know that I could grab it's HWND and do a SetWindowPos from another program).

Code has just recently gone in to play nice with cases where your taskbar may be at the top, left, or right of the desktop when centering.

In DirectQ it's not actually possible to specify a resolution that your monitor won't support. OpenGL is kinda lax about that, but D3D is ultra-strict. It causes a bit of pain for the programmer, but the end result is just far higher quality software.

I've also added a ton of checks at startup and around the vid_mode cvar to ensure that can never happen.

Full RMQ support is unlikely in DirectQ right now. The most I'll ever likely add to it is BSP2 support, meaning that it will be able to run RMQ. This is really in the interests of fairness to the rest of the team - I'm not sure how happy they would be with me if DirectQ suddenly became a better engine for running RMQ than the one I'm working on for them is! (I know I'd be mighty pissed if something like that happened to me.)

Maybe in a coupla years time when the full thing is released and work around it dies down would be a good time to consider it.

Supa said...

Regarding DirectQ becoming a better engine for RMQ than RMQe, I honestly wouldn't mind. All I really care about is whether or not we have an engine that can even run the thing in the first place. :)

I would still use RMQe in such a situation (no D3D support for *nix..) but if there was another engine available that could run say E1M3 even faster, I'd still acknowledge it as nice to have.

mhquake said...

I'd still support RMQe as the preferred engine for running RMQ. DirectQ is very much a general-purpose Quake engine, so it gets to make a different set of compromises.

Anonymous said...

First commenter here, wow thanks. =)

I've long since dragged my Windows 7 taskbar to my 2nd screen. I didn't set it to be my 'primary' monitor so games still fire up on the clean 1080p panel.

So, don't sweat the taskbar thing.

=peg= said...

Yup, same for me ^^ :)