Gfx modes always listed from smallest to largest?

BlitzMax Forums/BlitzMax Programming/Gfx modes always listed from smallest to largest?

Russell(Posted 2011) [#1]
When using GraphicsModes(), are the returned elements in the TGraphicsMode array always from smallest to largest, regardless of OS and/or gfx card driver? I know on some older graphics cards, certain modes are only available in, say 16 bit depth or at a lower refresh rate. I guess because of this, it's probably a good idea to go through the whole list, eh?

Russell


col(Posted 2011) [#2]
Hiya.
They are added to the array depending on how the hardware gives them to bmax, however it is generally from smallest to largest but I wouldn't rely on it. So yes, its best to check the whole array.

Edit:- I'm not sure if its still the case ( away from pc at the mo ) but bmax used to just check for 32 bit modes only. There are some minor modifications that have posted in the past to include 16 bits modes if BRL still haven't included them yet.

Last edited 2011


Russell(Posted 2011) [#3]
Another question/problem: Is there a way to figure out which modes are supported by the user's monitor? If I use GraphicsModes() to get an array of all of the available modes, I get just that: every single mode that the graphics card can display. But if I go into the display settings through Windows it only displays the modes that are displayable on my monitor (via the monitor driver), which for my laptop is only 1600 x 900, 1280 x 720 and 800 x 600 (I guess this is the fallback mode that they all support, even if it will be a stretched display).

How can I get just those three modes to be returned?

Russell

p.s. Is there a cross-platform way to get the information, perhaps via a tweaked BRL module?


Russell(Posted 2011) [#4]
I did find some info on this here: http://www.winvistatips.com/read-monitors-edid-information-t181727.html but it is windows only and is still not quite what I need (The information is totally raw, unformatted data).

Anyway, maybe I'll just stick with using the user's desktop mode, although this would be pretty limiting... There must be a better way!

Apparently, modern monitors send EDID information to the computer which includes information about what it can display (among other things). This freeware program can get exactly the information I need from EDID, but AFAIK the source code is not available: http://www.nirsoft.net/utils/monitor_info_view.html

Anyway, I'll bet this sort of module could be pretty useful to some people?

Russell


col(Posted 2011) [#5]
Hmm.

I understand what you mean. MS have a timeout fallback when you set the desktop and monitor modes manually, just in case something plays up. You could easily do something similar.


Russell(Posted 2011) [#6]
One big problem (and I'm really surprised this was overlooked by the graphics card & monitor industries), is that there doesn't seem to be any widescreen "minimum" standards like there are in the 4:3 world.
For example, before widescreen (16:9) or pseudo-widescreen (16:10 and the like), you could pretty much guarantee that a user's system could handle 640 x 480 without even checking. Even 800 x 600 is probably supported by 99.9% of the systems out there that are less than 20 years old. But since the widescreen came on the scene, it seems like there are no widescreen modes that ALL of the monitors cab handle (especially laptops, which tend to support fewer overall display choices).

If there was a BMax module that could read the EDID information, that would be VERY helpful, as we could cross-check its capabilities with the capabilities of the video card (returned by GraphicsModes()) and find a mode that suits our needs. I guess you're right, though: I'll have to let the user decide and timeout after 10 or 15 seconds if they don't click 'Ok' or something similar, in case they select a mode that their monitor can not actually display. EDID method would look more professional, though.

Anyway, would someone like to have a look at the example code from the winvistatips.com website (see link above) and see if they can make heads or tales out of it? Since the information is sent through the VGA port (or DVI) I would imagine that it should be platform neutral. I didn't know you could even receive non-raster information from the VGA port!

Russell


Russell(Posted 2011) [#7]
Here's the actual EDID structure: http://en.wikipedia.org/wiki/Extended_display_identification_data#EDID_1.3_data_format

Russell


col(Posted 2011) [#8]
I had a quick stab at porting that program to BMax last night, but it got too late to finish it :-)
I need to change some of the logic because if there is an error returned from one of the funtions then it exits too early. I'm not really sure how good it will be as I'm on a 16:9 laptop display and it just uses a 'Generic PnP Monitor' driver, which doesnt actually show result. However I can get it to list all drivers and also get the registry info for those drivers.

I have this code so far which will output ALL devices that has a driver.
On line 103:63 if you change DIGF_ALLCLASSES to DIGF_PRESENT it will list all monitor only drivers. On my system it doesnt return any value when using DIGF_PRESENT ( maybe because it uses a generic driver, I'm too early into it at this stage ). See what result you get...

This is of course Windows only so far, tested on Win7 and Vista, same results.




Russell(Posted 2011) [#9]
Thanks, I'll give this a shot! I am also on a laptop primarily, so I may have a similar result. I guess since a laptop's display is already known for certain (unless it has an external monitor attached through an external port) there's no need for it to return any EDID information.

I did some digging last night and discovered that a lot of monitor makers apparently either don't return correct EDID values, or they are incomplete (It is not a requirement, although Plug-n-play is not possible otherwise), so the usefulness of the EDID information may be questionable, unfortunately.

Still, if there was at least ONE widescreen mode that was pretty much guaranteed to be available, that would be very helpful. I can't imagine why they didn't think of this!

I thought of just using the SetVirtualResolution(), but that can sometimes lead to other issues, such as a not as crisp display.

Anyway, I'm going to try your code right now, and thanks!
Russell


Russell(Posted 2011) [#10]
Yep, I made the change to line 103 and it returned nothing (although it's actually DIGCF_xxx, not DIGF_xxx). So there seems to be an issue with laptop displays. :(

Thanks, Dave, for getting this to work.

What is everyone else doing to determine the correct fullscreen display dimensions? Are you using a standard 800 x 600 with pillar boxing on widescreens? Letting the user choose from a list that you provide?

Russell


xlsior(Posted 2011) [#11]
One fairly foolproof way of obtaining at least one most-likely-to-be-desirable resolution that is also supported by the hardware, would be to look at the resolution used by the actual OS desktop itself.

Although a catch there is that if it is a high resolution, there is a chance that low-end videocards may not have enough memory to open a second screen with the same specs.


xlsior(Posted 2011) [#12]
Oh, one more thought about EDID (I did some playing around with this myself in the past) is that it's possible to make an educated guess about whether or not the user is using LCD or CRT: if the EDID info has an overscan value declared, it's most likely a CRT. If the overscan value is zero, it's most likely an LCD.

It's really too bad that so many devices flat out LIE about their capabilities, though -- why on earth would the manufacturer want to set themselves up for failure?


col(Posted 2011) [#13]
I'm making more progress on the code with getting EDID info from the 'Generic PnP Monitor' registry entry. How useful will it be? we won't know until it's put out for trials. But it's interesting anyway :D

I also read about false EDID return results, kind of pointless returning a result if the data isn't accurate, but there you go. However, the source I read from was primarily referring to HDMI TVs.

I read an article on gamedev.net recently regarding resolutions etc but I'll be damned as I can't find it.

*DIGCFxxx typo. my apologies, as a way of an excuse :- late night coding :/

Last edited 2011


col(Posted 2011) [#14]
Thanks for the EDID format :P
I can get this to output the data into human readable form. Maybe knock up a GUI for looks.

EDIT - Thanks for the heads up there xlsior. I'm in the middle of making the gui output now to make things readable.

Last edited 2011


col(Posted 2011) [#15]
I didn't bother putting it together into a GUI, but here is the code that will put all monitors that have EDID data into an array of TMonitors which contains a monitor name and all resolutions the monitor can support. Again as we've discussed this may or may be erroneous data anyway :P

This could do with some more testing as I've left some validation checks, for eg it assumes the EDID data is in EDID1.3 format. If its worth updating this code and maybe putting into a module then I'd do all the sanity checks, but it is how it is just for now.

The data gets stored in these Types


To use in your own code you call:

EnumMonitors(CheckAllMonitors = False)

The default is to check just the monitors connected but if you pass in a value of True as the optional parameter then it will spit out all monitors listed that have EDID data along with all resolutions supported ( or I should say reported ) :-


The complete code including the example code :-


Last edited 2011


Russell(Posted 2011) [#16]
Thanks again, Dave! Now this is really getting somewhere! Looks good!

@xlsior: Another problem with using the user's desktop resolution is that it's pretty likely that it is one of the gfx cards higher resolutions, say 1920 x 1080 or such, and if your game is considerably lower then there might be issues. But, that being said, I just did some tests, and even though my Windows 'set resolution' dialog only lists 3 resolutions (800 x 600, 1280 x 720 and 1600 x 900) it had no problems with any resolution I threw at it that was returned by GraphicsModes(). And the neat thing is, none of the resolutions were visibly stretched: They were automatically pillar-boxed! Even 640 x 480, to my surprise, looked fine. Interestingly, none of the modes were letter-boxed, not even the ones with lower vertical resolutions: All of them took up the entire screen vertically without any apparent stretching.

Is this the case with anyone else's laptop? Mine has integrated Intel Extreme 3000 HD graphics. This would be great news if this is standard behavior for laptops (a growing segment of the PC world)!

Russell


col(Posted 2011) [#17]
I think that could be a driver issue, as mine also defaults to a pillar/letter box mode when needed. When I installed Win7 and using the Dx11 driver I made up, in full screen it definitely wasn't right, for eg the screen would be at max resolution with a smaller centred square representing a smaller resolution that I requested. When I installed the correct driver, the problem was gone.

However there are a couple of 'letterbox/pillarbox' adjustment functions in the 'Archives Section', so there has been some issues in the past.

Shall I build out the code some more or just leave it as it is? :P


Russell(Posted 2011) [#18]

When I installed the correct driver, the problem was gone


So even that behavior is inconsistent from driver to driver...Geez!


Shall I build out the code some more or just leave it as it is? :P


I think as-is it provides more than enough information to be useful. Thanks for knocking that together so fast! But, of course the problem is that there is a huge amount of inconsistency between various display manufacturers and the quality of the information they return through EDID (not to mention the problem with slightly older displays using an older version of EDID...). It's a royal pain!

Russell


col(Posted 2011) [#19]
Just to add to the pain........

In Dx11 ( I've worked extensively with this in these past 6 months or so ), the full screen will display any resolution you want it too!! Even obscure ones that 'should' only be available in a 'window' mode, something like 850x650!! This will still work giving a pillar/letter box style. But.... and the next part is the real crunch! The displays backbuffer is only copied to the front screen buffer by the gpu instead of using a hardware swap!! This then causes it to run a lot slower in full screen modes, and then only evidence of the problem is the speed issue. Of course checking for the correct modes and setting things up properly from the start removes these issues and its not possible to set an incorrect mode in BMax as the checks are taken care of, but it is food for thought :P

I'm not sure on the other APIs that PCs can use as I've not dived so deep into the previous Dx APIs or OpenGL as I have into Dx11.

BTW. Its easy to make the code compatible with older versions of EDID if its really needed. Its just a case of using the correct data format. There is tons of information in the EDID data, as long as its provided - which is the whole dilemma really :( I guess there must a 'minimum' amount provided to allow PnP to function correctly.


col(Posted 2011) [#20]

and its not possible to set an incorrect mode in BMax as the checks are taken care of



I'm sure they are :D *scurries off to check*


Russell(Posted 2011) [#21]
Do you mean with your DX11 driver it's not possible to set an incorrect mode in BMax, or just with Bmax in general? That's great if that's true, as we can just check to make sure Graphics() returns a non-Null object.

Every single mode that I tried on my laptop, except totally weird ones like 300 x 300, etc, worked. The ones I tried were like 320 x 200, 320 x 240, 640 x 400, 640 x 480... In other words, VESA modes. One strange thing about this is that the lowest mode that gets listed either from "list all modes" via the set-resolution dialog or from modes returned by GraphicsMode() is 800 x 600, yet those lower resolution modes worked anyway. I guess the driver does the best it can if it's a "standard" VESA type mode. Otherwise Graphics() returns a null object and the execution terminates. DX11, it seems, is going to make it better in some ways but worse in others...

I'm gonna have to give this a think and figure out what the best way to handle it is that works on various drivers and DX versions. :(

Russell


xlsior(Posted 2011) [#22]
The pillarbox / letterbox feature has three places it can be introduced:
1) The application
2) The windows video driver
1) The display itself

I know that on my Samsung 24" LCD there is an option in the on-screen settings to keep the aspect ratio, and it will automatically pillar/letterbox it.

If I disable that setting, I can also go into the ATI Catalyst program and enable the feature there

If the aspect ratio setting is disabled both in the driver AND in the monitor, it will stretch the screen to try to fill the entire display.

On a laptop you don't have the on-screen navigation buttons for the display, but there may (or may not) be some configuration options regarding the display in the computer BIOS settings.


Russell(Posted 2011) [#23]
Ack! When will it end! LOL

In a perfect world:
- the EDID information would always be reliable,
- All widescreen monitors would support the same resolutions (and be 16:9, not 16:10, etc),
- Bmax would read this EDID information and only return values that are compatible with the users monitor,
- I would be married to Beyonce' ;)

Until then, I'll let the user choose a full screen mode (from a list returned by GraphicsModes()) and time out in 10 seconds if they don't click 'Ok'....and I'll keep Beyonce' in my dreams...

Russell


skidracer(Posted 2011) [#24]
IMHO this is only relevant for CRT monitors.

For LCD you should always use the native resolution of the panel and use virtual resolutions to fit your games requirements.


col(Posted 2011) [#25]
Try setting a full screen of 800x700x32 and it will return as Null :-


Local gc:TGraphics = Graphics(800,700,32)
If Not gc End

Print "Graphics succeeded"


I need to fix this in the D3D11 driver :-) as it will create a full screen of 800x700 :P This SHOULD NOT be happening :P Although its in the Max2D drivers that it takes place, its a general BMax feature that it returns a Null object for non standard full screen displays. So I need to fix this :-)


Anyway.... Yes, I'd let the user choose what looks ok for them.