Mode change behaviour
Pages: 1 2
Richard Walker (2090) 431 posts |
Hi, I’ve updated my Pi B+ to RISC OS 5.27 dated 16th Nov. I have the cmdline/txt file disabling the GPU mode changes functionality, and I use AnyMode. If I do F12, BASIC, MODE 12, then I get an error: screen mode not available. Some modes work (15/13/7) but others don’t (0/1/12). Reverting to my previous RISC OS build (5.25 dated 26 Sep), then it all settles down and all above mentioned modes work. Is there maybe something in the new behaviour which is incompatible with disable_mode_changes and/or AnyMode? Must admit, I have not yet tried switching that off and seeing what happens. Cheers, |
Jon Abbott (1421) 2651 posts |
It looks like translated modes are causing an issue with AnyMode. RMKill AnyMode and they translate to a suitable higher bpp mode. Changing mode outside of the desktop is also altering the desktop resolution, which I don’t think should be happening. Legacy modes aren’t working with ADFFS, from the error (Not enough memory to change to this screen mode) it looks like DA2 isn’t being sized correctly. Setting DA2 prior to a MODE change doesn’t resolve the problem, but I may well have to make changes to the ADFFS mode change process, I’ve not looked at the GraphicsV documentation yet to see what’s changed. If I’m making changes to ADFFS, I’ll see if I can get it to a point where AnyMode isn’t required. In theory it shouldn’t be a requirement in the latest ADFFS builds, as the GraphicsV driver allows all resolutions and bpp. |
Richard Walker (2090) 431 posts |
I decided to re-test without the disable_mode_changes flag, thinking that maybe the latest OS changes have missed something in that area. But I ended up with similar results, apart from games trying to change to old-fashioned modes which causes my TV to display ‘resolution not supported’. :) I’ve also just concluded that AnyMode could well be part of the problem. I’ve killed that and can see more normal behaviour if I do F12, BASIC, MODE 13 etc. but it it still doesn’t work for games via ADFFS. I didn’t realise that ADFFS was involved in the mode change behaviour. Probably best to ignore this from a RISC OS perspective: there I was casting doubt on some recent changes! |
Jon Abbott (1421) 2651 posts |
ADFFS 2.68 introduced a full GraphicsV driver which provides all legacy modes at the desktop via DA2 and a virtual VIDC20. With ADFFS loaded, if you go into MODE 0/9/12/13 etc they’re redirected to DA2 and it blits them to the GPU at 24bit. One of the issues this change was hopefully going to resolve was the OS not managing DA2 correctly – which I think was due to it not handling driver changes between modes. ADFFS currently has a botch in it to manage DA2 size, but it looks like the OS is preventing the mode early on, so ADFFS doesn’t get to size it before the OS reports there’s not enough memory. It could simply be that I need to implemented some changes to coincide with Jeffrey’s changes. The thread related to this is here I believe there may be further changes to come as Jeffrey noted this change didn’t fix another issue, where VCHIQ locks the machine if a low priority thread raises a VSync. |
Jeffrey Lee (213) 6048 posts |
I think I’ll need to do some investigating to find out why AnyMode is broken (I had a quick look at the code last night, but couldn’t spot anything obvious that would explain the problem you’re seeing).
Nothing’s changed in GraphicsV. The most significant change was moving the logic for picking substitute modes out of the core part of the VDU driver and into the Service_ModeTranslation implementations. I’ll work on an updated version of the flow chart to show the changes, but for now I think this is an accurate summary of the new logic for handling mode changes:
These are the two changes that contain everything: https://www.riscosopen.org/viewer/revisions/logs?ident=1541629683-530634.html There’s also this wiki page which attempts to explain some of the nuances with different mode types (Service_ModeTranslation needs to be fairly complex if it wants to preserve the “mode type” when it’s searching for substitutes). |
Jon Abbott (1421) 2651 posts |
Possibly an issue in the Service phase then. ADFFS does implement GraphicsV 19, which returns “use DA2”. I’ll do some debugging during the week, as on the face of it there shouldn’t be a knock on effect. I’ll try blocking DA2 being downsized by the OS to rule it out. |
Rick Murray (539) 13840 posts |
A Wiki walk from the linked page led me here: https://www.riscosopen.org/wiki/documentation/show/Monitor%20Types Is type 0 accurate, being called “Television (50Hz PAL)”? The original Archimedes range did indeed run an RGB output at 50Hz, and a composite video output, however:
How did the A3010 do things? Did they modulate colour CVBS or take it from RGB à la Beeb? Maybe it would be better to call this “50Hz monitor” rather than “Television”? 1 Experiments: DVD player in progressive scan mode made a lovely picture on my AKF12 monitor. A3000 in every settings I could think of made no useful picture on my Daewoo TV (SCART RGB input). |
Chris Evans (457) 1614 posts |
Or “15KHz display” |
Jon Abbott (1421) 2651 posts |
This appears to be a generic error covering several failures and so is misreporting the actual issue. I think the reason ADFFS doesn’t work is the call to Service_PreModeChange is occurring after the call to VetMode/VetMode 2. I can’t figure out why 1/2/4bpp modes are failing though, as it forces them to be available by always taking over GraphicsV 8 (Features). If I move the mode validation into VetMode/VetMode 2, there’s no error and it will go into MODE 13, but it’s not in DA2 so something has subsequently caused ADFFS to shutdown – possibly another call to Service_PreModeChange? Once the flow diagram of the mode change process is updated, it might become clearer. |
Jeffrey Lee (213) 6048 posts |
Service_PreModeChange is essentially step 0 in the flow I gave earlier – when you request a mode change by VDU 22, OS_ScreenMode, etc. it occurs before any vetting or substitution that the kernel does. (Previously it wasn’t the first thing in the flow – there was some code just before it where, if it’s a known numbered mode, the kernel would have issued GraphicsV 8 and then used a lookup table to find a substitute mode if the BPP wasn’t supported) When I get home tonight I’ll upload the module that I was using to test low BPP emulation. |
Jon Abbott (1421) 2651 posts |
My best guess is one of the checks after DoFullVetMode is failing as it never gets to the XOS_ReadDynamicArea on line 702. As far as I can tell, I’m returning the correct values so it should drop through. VetMode is returning:
VetMode 2 is returning:
|
Jeffrey Lee (213) 6048 posts |
VetMode 2 is returning: 2 is “use the external framestore (as defined by R3 & R5)”. You want to return 1 for DA 2.
http://www.phlamethrower.co.uk/misc2/bpptest.zip Since it’s test code it’s a bit rough around the edges, but it’ll install a driver which causes 1-8bpp modes to use DA 2, using software to copy the contents to an 8bpp GPU framebuffer. If a higher colour depth mode is selected it’ll pass the calls straight through to the GPU (but because I couldn’t be bothered implementing GraphicsV 18 to return the full pixel format list, on a Raspberry Pi it means 64K colour modes won’t be available while the module is loaded). Also because it was just meant to be unreleased test code, the BPP conversion code was stolen from ADFFS ;-) There’s also a bug where it won’t copy the full framebuffer if there’s padding on the end of the framebuffer rows. |
Richard Walker (2090) 431 posts |
Putting ADFFS aside for a moment, I tried the latest OS with the GPU mode changes disabled and AnyMode loaded. If I request MODE 15 or 28, then happy days. But modes like 12 or 9 or 0 just refuse. Says something about mode unavailable. If I try in the desktop, it tells me the desktop doesn’t support that mode. Strangely, MODE 7 works outside the desktop quite nicely! Are low BBP modes simply unavailable? |
Jeffrey Lee (213) 6048 posts |
I’m looking into the AnyMode problem now. |
Jon Abbott (1421) 2651 posts |
I’ve misread the values for that field as the bit not the value. Corrected, it now works…how embarrassing! Regards AnyMode, it partly works as without it my custom 1360×768×50hz doesn’t work. It’s only the numbered modes that are problematic. |
Jeffrey Lee (213) 6048 posts |
Last night I did check in a couple of fixes so that when AnyMode is loaded selecting a numbered mode in an unsupported colour depth will now give you a mode – but it won’t be any AnyMode mode, because there’s a bit of a question over exactly how Service_ModeTranslation should operate. |
Steve Pampling (1551) 8170 posts |
From observation of the behaviour of Anymode on an RPCEmu install1 if you try to select an unsupported colour depth / resolution combination it drops to a bog basic resolution, which I suppose is down to not having a valid mode or conversely it has selected a bog basic mode which isn’t supported by the GPU of a Pi 1 Makes the RPCEmu window fit the space above the windows bar perfectly. |
Jon Abbott (1421) 2651 posts |
Steve’s sent me the source code for AnyMode if we need to make any changes. I guess it needs to validate the mode and up the bpp until it gets a valid one? |
Jeffrey Lee (213) 6048 posts |
Pretty much, yeah. I think the only thing you need to watch out for is that Service_ModeTranslation shouldn’t call OS_CheckModeValid, since OS_CheckModeValid will try calling Service_ModeTranslation in order to find out what the alternate screen mode is. So you’d need to validate the mode manually (e.g. GraphicsV 19 with a fallback to GraphicsV 7) – probably as part of Service_ModeExtension as the other thread suggests. And of course you can’t modify the mode selector block that’s provided as input, so you’ll need to return your own copy of it (using a global buffer similar to how the VIDC lists are returned). |
Jon Abbott (1421) 2651 posts |
AnyMode works by claiming Service_ModeExtension and returning a VIDC type 3 list. Modifying that so it issues GraphicsV 19 / 7 upping the bpp until it gets a valid mode does get low bpp mode changes working again, but it looks like the OS isn’t using the updated bpp returned in the VIDC list and continues to use the original mode specifier’s bpp. Tested on the 16-11-18 build. |
Jeffrey Lee (213) 6048 posts |
That’s because Service_ModeExtension shouldn’t be altering the parameters of the mode (except for adding extra padding via the ExtraBytes control list item). Service_ModeTranslation is the one that’s used to pick a different mode – you need to add an implementation of that and place the BPP change logic there. |
Jon Abbott (1421) 2651 posts |
The documentation isn’t clear on that point, perhaps it should detail which VIDC parameters can be set. Is Service_ModeExtension occurring before or after Service_ModeTranslation in the mode change process? |
Jeffrey Lee (213) 6048 posts |
Before, after, and possibly during. You shouldn’t make any assumptions as to when they’ll be called in relation to each other. Service_ModeExtension is used for:
Service_ModeTranslation is the “I’ve been told that I can’t display mode X on this hardware, can someone suggest a similar mode Y which can be displayed?” call. Since it gets told the mode number and the monitor type, there’s no need for it to know anything about any prior or future Service_ModeExtension calls. OK, there is the slight issue of the bandwidth & memory limits in R4 & R5 – but (for RISC OS 5.20+) you can probably just pass 232-1 for those, since they are/will be redundant:
|
Jon Abbott (1421) 2651 posts |
I believe it was working in prior OS builds because Service_ModeTranslation has occurred before Service_ModeExtension, I’m not sure it’s going to work otherwise. I’ve not looked to see what’s happening on earlier builds, but on the 16-11-18 build Service_ModeExtension is being called up to four times on a mode change, more importantly it’s getting called before Service_ModeTranslation so the mode fails if Service_ModeExtension doesn’t up the bpp in the VIDC list. |
Jeffrey Lee (213) 6048 posts |
It worked before because, prior to calling Service_ModeExtension, the kernel was spotting that it was a known numbered mode in an unsupported BPP and was swapping it out for a different mode (and without calling Service_ModeTranslation). |
Pages: 1 2