Opened 13 years ago

Closed 8 years ago

#7655 closed bug (duplicate)

Resolution 640x480 the only one available -- driver using own EDID interp. instead of (more complete) common code's EDID interpretation

Reported by: ttcoder Owned by: rudolfc
Priority: low Milestone: Unscheduled
Component: Drivers/Graphics/nVidia Version: R1/Development
Keywords: Cc:
Blocked By: #6716 Blocking:
Platform: All

Description

This is hrev41843 .

The Screen preflet provides only 1 Resolution menu item (instead of 3) when Haiku is run in normal (driver/accelerant) mode, and it provides only 2 items in VESA mode. That latter one at least includes both 640x480 and 800x600, which makes Haiku more usable. Many eons ago, Haiku provided the same as BeOS, i.e. it went up to 1024x768.

I guess the Screen preflet is not the culprit since it just relies on the driver to calculate "proposed modes" ? In fact it seems monitor related; here's a suspicious (?) syslog bit:

KERN: VESA compatible graphics!
KERN: EDID1: 4f
KERN: EDID2: ebx 182
KERN: EDID3: 4f
 ...
KERN: EDID version: 1.0
 ...
KERN: Supported Future Video Modes:
KERN: 640x480@85Hz (id=22833)
KERN: 800x600@85Hz (id=22853)
KERN: Supported VESA Video Modes:
KERN: 720x400@70Hz
KERN: 640x480@60Hz
KERN: 640x480@75Hz
KERN: 800x600@75Hz
KERN: 1024x768@60Hz
KERN: Additional Video Mode (640x480@99Hz):
KERN: clock=44.9 MHz
 ...
KERN: crtc: h 656/712/848, v 487/498/531, pixel clock 44900000, refresh 10085

Above, 85 Hz seems wrong, and 99 is definitely (this sure is not supported by my CRT monitor). And what with the differing lists of proposed modes...

This bug seems to be graphic-card independant -- the same lack of Screen Resolution menu items happens with an ATi Rage Pro, using the same CRT monitor.

Attachments (4)

7655_syslog_640x480_NVidia (71.4 KB ) - added by ttcoder 13 years ago.
7655_only_one_resolution.png (28.4 KB ) - added by ttcoder 13 years ago.
screen-cant-display__nvidia.10de_0181_010000.0.log (36.6 KB ) - added by ttcoder 13 years ago.
nVidia driver log, with "screen can't display 800x600" spurious error message…
patch_nvidia_accel.diff (2.4 KB ) - added by ttcoder 13 years ago.
Do not override create_display_modes() *3-sections* guesstimate with our own (more limited) 1-section EDID guesstimate :-)

Download all attachments as: .zip

Change History (23)

by ttcoder, 13 years ago

Attachment: 7655_syslog_640x480_NVidia added

by ttcoder, 13 years ago

comment:1 by ttcoder, 13 years ago

Here's the screen grab.. I'm not attaching a screenshot of Screen in VESA mode since it looks similar, except it also allows 800x600. As you might guess from the above, I've tried both hrev41843 Screen and the newer hrev41890 Screen preflets, but both revisions behave the same.

Version 0, edited 13 years ago by ttcoder (next)

comment:2 by ttcoder, 13 years ago

While browsing other nVidia tickets I've noticed Rudolf's extensive troubleshooting (I hope he'll see this ticket too!) and the existence of the nvidia.settings config file. I've created it, enabled some logging, and got some info, including these suspicious lines:

PROPOSEMODE: (ENTER) requested virtual_width 800, virtual_height 600
PROPOSEMODE: screen at crtc1 can't display requested resolution, aborted.

This is weird, considering that 800x600 is used in VESA mode successfully (and the monitor is able to go up even to 1024x768). If this rings a bell (Rudolf ?) then any hint would be appreciated, about where I should go from there, otherwise I'll just follow my instinct to decide in what direction to continue digging :-)

Attaching the log in full..

by ttcoder, 13 years ago

nVidia driver log, with "screen can't display 800x600" spurious error message...

comment:3 by ttcoder, 13 years ago

Component: Drivers/GraphicsDrivers/Graphics/nVidia
Owner: changed from nobody to rudolfc

Located the error message, inside add-ons/accelerant/nvidia, over at ProposeDisplayMode.c:196

Will continue digging, looking where these variables that trigger the error message come from. They seem to be global scope, aye.

comment:4 by ttcoder, 13 years ago

Boy, graphics drivers are complex things, took some navigating the code to finally understand who called who, who has the EDID info retrieved and stored in ::si and then passed to ProposeMode ..etc, then hacked that part to accept my monitor's resolution, which makes it much more comfortable to be in Haiku now :-)

Turns out my monitor's EDID does not list its native resolutions in case EDID1_IS_DETAILED_TIMING (the third section) but only in the first 2 sections.. (especially section 2, "Supported VESA Video Modes")... I have recompiled the driver with extra logging, and found out... (could have guessed by reading the log in the first place, but then I didn't know what EDID is, reading the driver taught me that :-)

Windows seems to be fine with it -- it proposes 1024x768 so I guess it probably uses the info in "Supported VESA Video Modes" section.

I can imagine 4 ways to resolve and close this ticket now:

  • close a Invalid/Will-not-fix (and I continue using my hacked driver)
  • implement a new setting in nvidia.settings that allows to disable EDID completely, allowing to pick any resolution at all in Screen preflet; close as fixed
  • implement a new setting in nvidia.settings that allows to override the virtual_w/virtual_h used in ProposeMode.cpp; close as fixed
  • try to be nimble and exploit the other two EDID sections (which are currently unused by Haiku apparently), like MS Winders presumably does.. :-). There is more potential for regression if I don't "get it right" with my patch, but it could be worth the extra effort.. Depends if other people are affected by this EDID "scarcity of info" problem or if it's just this one Hyundai CRT dinosaur..

Anyway that's where I'm standing now, I'll stop updating this ticket and stop digging.. Though I did not succeed in finding all the information I wanted: I meant to explore the vesa/accelerant code and find out why that one goes to 800x600 (not lower, nor higher, even, that's odd!) but got blocked in there: couldn't find how it retrieves the EDID info if any; most close thing I found to EDID in vesa was this one , which is a dead-end for me (Trac does not allow to search the source for a symbol name it seems).

Anyhow this is probably a priority=Low ticket, if anyone cares to change that property of it.

UPDATE: turns out that I'm not alone with this symptom, and my conclusions were already reached in http://dev.haiku-os.org/ticket/6716#comment:8

.. where Rudolf says there are several different patches that could be done to solve this (and other similar) tickets..

Shout-out -- any chance the patch could be applied, if I write one ? For instance the "do like winders does" concept?

comment:5 by axeld, 13 years ago

There are no EDID sections ignored. What is missing in Haiku is a function to compute the display timings for an arbitrary mode (ie. a function that implements the Generalized Timing Formula a.k.a. GTF). To work around that, https://dev.haiku-os.org/browser/haiku/trunk/src/add-ons/accelerants/common/create_display_modes.cpp maintains a list of modes that is applied on those extra EDID modes that don't contain the timings itself.

If a mode is not in this list, and does not provide its own timing, it's ignored - even in VESA mode, although this is merely an implementation detail.

in reply to:  5 comment:6 by ttcoder, 13 years ago

Replying to axeld:

(..) What is missing in Haiku is a function to compute the display timings for an arbitrary mode (ie. a function that implements the Generalized Timing Formula a.k.a. GTF). To work around that, https://dev.haiku-os.org/browser/haiku/trunk/src/add-ons/accelerants/common/create_display_modes.cpp maintains a list of modes that is applied on those extra EDID modes that don't contain the timings itself. (..)

Thanks for the pointers, appreciated, now I think I understand what happens in all 3 pieces of code:

  • create_display_mode.cpp creates 2 of the 3 resolutions I need (the third is missing because as you said it only hardcodes (a few) resolutions and would need GTF implemented instead)
  • the VESA driver correctly exploits these 2 resolutions!
  • the nVidia driver does not, on the other hand (and judging from similar tickets, some other drivers as well) -- it applies a "veto" on resolution 2 instead of exploiting it, leaving me with only resolution 1. And given the code's flow, it could even veto 640x480 itself (if my Hyndai monitor was even less verbose), refusing to boot in native driver mode at all and leaving me with only VESA graphics, oops! :-o .. I've seen a few tickets hinting at this while searching the database... Anyway in my case it's not that bad I can boot in non-vesa mode, but the native driver definitely is more restricted than the VESA one:

To wit, my syslog's "VESA" (?) paragraph mentions both the first and second resolutions:

KERN: VESA version = 3.0, capabilities 1
KERN: OEM string: NVIDIA
KERN:  0x100: 640 x 400 x 8 (a = 927, mem = 4, phy = c8000000, p = 1, b = 1)
...
KERN:  0x115: 800 x 600 x 32 (a = 927, mem = 6, phy = c8000000, p = 1, b = 1)

Whereas the /boot/home/nvidia... logfile mentions a veto on the second resolution:

PROPOSEMODE: (ENTER) requested virtual_width 640, virtual_height 480
PROPOSEMODE: validated virtual_width 640, virtual_height 480 pixels
...
PROPOSEMODE: (ENTER) requested virtual_width 800, virtual_height 600
PROPOSEMODE: screen at crtc1 can't display requested resolution, **aborted.** <--

.. and thus only the first resolution (640x480) shows up in the Screen preferences..

So I guess this is the first thing to fix: make the nVidia driver play nice in ProposeMode, to allow more resolutions (and maybe even for some people allow to boot Haiku at all)... And then later on implement GTF to allow the full range of resolutions) ?

Patch to be attached here soon (more a proof of concept than a ready-to-be-applied diff, clearly...)

P.S. There's still one thing I've noticed, probably not important: the mode list in create_display_mode.cpp goes up to

B_CMAP8, 1920, 1200

Whereas the Screen preflet with my "disabled EDID" hack goes up to 2048x1536... Maybe there is another -- slightly different -- copy of this mode-list somewhere in the source tree.

by ttcoder, 13 years ago

Attachment: patch_nvidia_accel.diff added

Do not override create_display_modes() *3-sections* guesstimate with our own (more limited) 1-section EDID guesstimate :-)

comment:7 by ttcoder, 13 years ago

patch: 01

comment:8 by axeld, 13 years ago

I am not sure if the nvidia driver is using create_display_mode() at all. Older drivers tend to implement this bit on their own with their own mode list. That would be the first thing to test.

As you can see in your syslog, the nvidia VESA mode does not contain anything above 800x600, and therefore, you won't find it when using VESA. That looks like a pretty poor BIOS implementation, or maybe the EDID information from your monitor are just broken (more likely).

The driver should not ignore the EDID information per se (ie. I wouldn't want to see your solution in trunk), but should either try harder to detect broken EDIDs (preferred), and/or have a setting that achieves this.

in reply to:  8 comment:9 by ttcoder, 13 years ago

Summary: Resolution 640x480 the only one availableResolution 640x480 the only one available -- driver using own EDID interp. instead of (more complete) common code's EDID interpretation

Replying to axeld:

I am not sure if the nvidia driver is using create_display_mode() at all. Older drivers tend to implement this bit on their own with their own mode list. That would be the first thing to test.

Indeed:

~/develop_haikusrc/accelerants/nvidia> grep create_display_modes *  
acc_std.h://#include <create_display_modes.h>
Binary file libaccelerantscommon.a matches
~/develop_haikusrc/accelerants/nvidia> grep create_display_modes */*
engine/nv_std.h://#include <create_display_modes.h>

In fact InitAccelerant.c's INIT_ACCELERANT() calls ProposeDisplayMode.c's custom function create_mode_list(), which itself calls PROPOSE_DISPLAY_MODE() with its own local list of hardcoded modes..

And that latter function makes its decisions based on the restricted (incomplete) EDID "native specs" previously calculated by engine/nv_i2c.c's i2c_ExtractSpecsEDID() (that's the one which interprets only section 3 of EDID and ignores section 1 and section 2).

So IIUC instead it should be like this:

INIT_ACCELERANT() should call common/'s create_display_modes() : That one includes its own routine to interpret EDID Specs from all 3 EDID raw sections, and thus fill out correctly the si->ps.crtc1_screen.timing.h/v_display fields whatever section their value comes from, and thus the enforcing of these fields would not need to be commented out any more (as I proposed they be in my, quote, unquote, "patch" :-).

What's more, ProposeDisplayMode.c indeed has its own copy of modes:

/* Standard VESA modes,
 * plus panel specific resolution modes which are internally modified during run-time depending on the requirements of the actual
 * panel connected. The modes as listed here, should timing-wise be as compatible with analog (CRT) monitors as can be... */
//fixme: if EDID monitor found create list via common EDID code...
static const display_mode mode_list[] = {
...

and this one does have the 2048x1536 I see in Screen prefs indeed.

So, I'm glad I picked your brain to find out exactly where the problem is :-)

That driver needs to indeed call create_display_modes() (from common/) to make sure EDID data is interpreted correctly in all cases.

I don't have enough time to work on such a significant change myself, but at least if others pick up this ticket later they'll know where to start from.

P.S. I cannot uncheck the "has Patch" box, it's grayed out, need someone with edit privileges to do it.

comment:10 by ttcoder, 13 years ago

I'm back in Haiku with a new drive after my HDD troubles, and went directly to Alpha3... But I'm being punished for it as there are regressions since 41384: VESA mode now plays "hard to get", and in native nVidia mode I'm now locked out of even 800x600 (even hacking the driver does not work any more, using either the exact same binary build as before, which I had backed up, or rebuilding my hack from source!)

Investigating since yesterday evening.. First thought there had been a commit to trunk just before 42211 that changed the behavior of the app_server and/or graphics drivers, but didn't find such a change.. Now searching for a Plan B...

comment:11 by ttcoder, 13 years ago

Turns out I have to do some voodoo hoodoo to boot now: I have to change the VESA resolution in the boot menu safe options, in order to get a good monitor sync from the nVidia accelerant..

Behavior if I fail to choose the 800x600 VESA resolution (or if I pick any other resolution):

  • VESA does not work (strange... VESA worked in 41834, regardless of whether or not I chose a specific resolution)
  • nVidia does not work (even stranger! how can nVidia be affected by the boot menu resolution selection ??): it tries to setup 640x480 at 1900 (!) MHz pixel-clock

Behavior if I select 800x600 VESA resolution:

  • VESA indeed works in 800x600
  • nVidia is able to display both 640x480 at a correct 30.5 MHz pixel clock, and 800x600

This could be linked to our above discussion (i.e. the nVidia accelerant does not play nice with create_display_modes()) but I don't think so, since the VESA accelerant is also affected.

So I'll file a distinct ticket soon, insisting on the VESA side of the equation as this should be easier to reproduce and debug. (i.e. the fact that VESA requires a specific resolution to be picked otherwise it fails, whereas it was smart enough to pick a resolution on its own in 41834). And when that gets fixed it will probably also fix the nVidia problem, allowing me to boot this PC without trouble.

comment:12 by rudolfc, 13 years ago

Hi there ttcoder,

Sorry you had to go to all this trouble to get a better picture.. I'll update the driver first thing, asap to have a setting to let through all modes if you select a setting for that in nvidia.settings.

Hope that will do for you (and these other cases).

Bye!

Rudolf.

comment:13 by ttcoder, 13 years ago

Hi Rudolf,
I'm glad you have seen this ticket. I wouldn't consider this an emergency unless someone else needs the fix too, as I have the means to tweak and recompile your driver from source to improve my situation -- I can wait for the 'trunk' workaround and/or fix. My (somewhat pressing) issue now is the regression I've outlined in #7787, which clearly cannot be fixed in the nVidia driver itself.

When #7787 is fixed I'll get back to this one (EDID issue), maybe even try to contribute what Axel advised, but I might be out of my depth for implementing that, we'll see. I also lack the motivation since implementing the workaround is much easier :-)

Cedric (an otherwise happy user of the driver!)

comment:14 by Charlie_X, 12 years ago

patch: 10

comment:15 by ttcoder, 10 years ago

Priority: normallow

(low: not using this any more, and noone else made noise about it)

comment:16 by ttcoder, 9 years ago

Milestone: R1Unscheduled

comment:17 by rudolfc, 8 years ago

Hi,

From what I am reading here is that indeed it's a poor BIOS implementation of the monitor connected, as the driver uses the common code to read EDID with only lowlevel hardware line control plugged in from the driver.

The monitor only reports 640x480 via EDID, so that's why the driver doesn't work above that. I don't remember by heart if there's a setting in the driver to disable use of EDID (I expect so?), but anyhow I'd say this is not an error in the driver, but in the monitor.

Should be rare this kind of trouble... especially nowadays. Close as won't fix?

Bye!

Rudolf.

in reply to:  17 comment:18 by ttcoder, 8 years ago

Replying to rudolfc:

Should be rare this kind of trouble... especially nowadays. Close as won't fix?

Please do I'm no longer using that 15" CRT monitor (good riddance :-) so this ticket is no longer useful... Your NVidia driver ..etc got me going with Haiku years ago BTW, grateful for that!

comment:19 by pulkomandy, 8 years ago

Blocked By: 6716 added
Resolution: duplicate
Status: newclosed
Note: See TracTickets for help on using tickets.