BCMVideo GraphicsV 2 timing
Jon Abbott (1421) 2651 posts |
Is it possible to get GraphicsV 2 to apply the resolution change during flyback on the Pi? The GPU appears to apply the resolution change mid-scan even when GraphicsV 2 is issued at VSync. I’m trying to figure out how to change the screen geometry every frame without flickering. EDIT: I’d also like to know if GraphicsV 2 actively clears the screen – or if its blanking the screen as a side effect of reallocating GPU memory. |
Jeffrey Lee (213) 6048 posts |
Remember that (to avoid blocking or additional frame lag during palette updates or bank switches), BCMVideo generates the VSync event at about halfway through the frame. Now that we have GPU mode control it might be possible to tweak the VSync timing so that it occurs nearer to the end of the frame (preferably at the start of the blanking period, depending on exactly when the deadline is for getting the messages over to the GPU). The only problem is that for your use case (GPU mode changes disabled) that might be a bit tricky since I don’t think we have an easy way of getting the mode timings the GPU is using (worst-case, the driver could just have a lookup table for converting GPU mode numbers to VSync offsets). Or I guess we could check with the Pi firmware team to see if they can provide a more useful VSync interrupt.
That’ll be the GPU clearing it when it reallocates the framebuffer. There’s no requirement/expectation in the GraphicsV spec that memory should be cleared by the driver. |
Jon Abbott (1421) 2651 posts |
That’s possibly not an issue, provided the geometry is changed during flyback by the GPU. My guess is it’s acted on immediately, would delaying the mailbox until the next physical VSync resolve the flickering? I believe its possible to schedule a mailbox for the next VSync, could BCMVideo do this for GraphicsV 2?
I thought it was raised at flyback, but too late to pass anything to the GPU via mailbox for that frame.
popcornmix committed a change back in 2014 so FBIOPUT_VSCREENINFO doesn’t clear the frame if the allocated size doesn’t change. Not sure if that’s the physical or virtual size though. Here’s the GitHub issue that covers some of this. Here’s a repro that shows the issue:
|
Jon Abbott (1421) 2651 posts |
Here’s another example, that uses the SMI IRQ to lock to VSync. It looks like the SMI IRQ is triggered shortly after the start of the scan though, as you can still see the frame being blanked by SetMode. It does at least lock to a set time from VSync though, which is an improvement on OS_Byte 19 which drifts out of sync (as visible in the repro above.)
|
Jeffrey Lee (213) 6048 posts |
Correction: VSync occurs normally (i.e. whenever the GPU raises the SMI interrupt). Palette updates / bank switches get buffered by BCMVideo and are acted on halfway through the frame. The primary aim of this buffering is to avoid any blocking while waiting for the GPU because (at the time the code was written – 2014) the GPU seemed to only process palette updates (and bank switches?) at a rate of one message sequence per frame. And IIRC the halfway point was chosen because (a) I don’t know when the deadline is for getting the messages sent to the GPU in order to make sure they get acted on ready for the next frame, and (b) the ARM timer (which is what I’m using to generate the mid-frame interrupt) can have its frequency affected by changes to the main ARM clock, so precisely timing the mailbox send would have been difficult. (I also didn’t want to use HAL timer 1, since that would have left the system without any spare HAL timers for other code to use) Mode change requests are acted on immediately, so the half-frame interrupt isn’t relevant. I haven’t tried looking into the mode change timing on the GPU side (changing the screen geometry every frame isn’t the typical use case!) |
Jon Abbott (1421) 2651 posts |
If you compare the two examples I’ve included above, the first drifts out of sync (geometry is changed at VSync) and the second is locked (geometry is changed at SMI interrupt).
Is it the GPU? Or a restriction in the blob? There’s been a lot of changes to the GPU side, so this may have changed since we tested in 2014.
No, not a typical use case. I’m aware of it being used to dynamically stretch the screen in height. The original release of Stunt Racer 2000 used it during the intro and Cartoon Line pt.1 uses it to shake the screen when the bull appears. The Pi appears to be capable of rapidly changing the geometry, but it does highlight the fact VSync doesn’t occur at flyback. You’d think that would be fixed by now – unless the GPU simply doesn’t generate an event at flyback. |
Jeffrey Lee (213) 6048 posts |
I haven’t got round to running those yet – hopefully tonight. In both cases it should be the SMI interrupt that’s triggering your code. Maybe the OS_Byte 19 approach would see an extra random delay added, but I wouldn’t expect it to completely drift out of sync.
Almost certainly a restriction in the blob.
“letterbox” might be a more accurate description. With Stunt Racer the mode timings being sent to the monitor remained the same, it just used the VIDC border controls to change the dimensions and position of the displayed framebuffer. The scale remained the same. If you were to try the same thing by adjusting the screen height on the Pi (even if you were to supply border parameters in the VIDC list) then there’s a good chance it will also affect the scale of the image. To get the same effect via the Pi’s framebuffer functionality I think we’d need a way of translating the border settings into overscan settings; the overscan settings can be modified via the mailbox interface, the tricky bit is working out when they should be used. |
Jon Abbott (1421) 2651 posts |
It must be a bug in my code then as the blitter handles any letterboxing, it shouldn’t be pass any geometry changes to the GPU. EDIT: It was indeed a bug in my code, the check for geometry changes was checking hdisp/vdisp instead of HCR/VCR. |
Jeffrey Lee (213) 6048 posts |
Running your test code on a Pi 1 with RC15, the two seemed to behave pretty much identically. The flickering band of black was at the same location near the top of the screen. It did seem like the first program (OS_Byte 19) had an increased chance of the band being larger than normal, but no obvious signs of things being completely out of sync. |