Vsync Problem


MST

Still Fresh
Joined
Jul 22, 2011
Messages
2
I'm trying to cause a wait for vsync, but none of the methods I've been able to find are actually working for me

Code:
int fd = open( "/dev/fb0" , O_RDONLY );
                if( 0 < fd )
                {
                        int ret = 0;
                        ret = ioctl(fd, FBIO_WAITFORVSYNC, &ret );
                        /*if ( ret != 0 )
                VSYNC failed
                        */
                }
                close(fd);
The ioctl method above fails with ret == -1, and errno == 22 ("EINVAL")

Code:
while(memregs16[0x1182>>1]&(1<<4));
Checking the register always turns up false. I tried the opposite condition to be sure (while the same condition is false), and it creates an infinite loop, so the flag is never being set

Is there another method that will work, or are there any initial steps (other than using mmap to map the registers) required for these to work?

Thanks for any help
 
I'm pretty sure FBIO_WAITFORVSYNC is not supported by Wiz/Caanoo's kernel.

I used this code in PicoDrive:
Code:
static void gp2x_video_wait_vsync_(void)
{
        while (!(memregl[0x308c>>2] & (1 << 10)))
                ;
        memregl[0x308c>>2] |= 1 << 10;
}
memregl is int pointer to mmap'ed soc registers.
 
Thanks for the response, but that seems to have the same problem. Just no wait, and an infinite loop when testing the opposite condition

The registers are mapped this way:
Code:
memregs32 = (volatile uint32_t*)mmap(0, 0x20000, PROT_READ|PROT_WRITE, MAP_SHARED, memfd, 0xC0000000);

Printing out the value of the register before and after the wait code you gave me not only gives values that are the reverse of what I'd expect (0x223F9400 before and 0x223F9000 after), but also shows that the value frequently reads as 0x223F9000 before, too. For some reason, it never creates an infinite loop without the additional code for displaying the value, but it did start doing that after. Inserting a counter in the while loop to break out after 1024 iterations seems to trigger about every-other-time (once vsync appears to be triggered proper, once the counter reaches 1024, then another vsync..). Adding a usleep before the counter causes even stranger results- the counter never reaches 1024 (or at least, the message for it isn't printed), but I again frequently get 0x223F9000 from the register both before and after

I assume that vsync is supposed to be 60hz, but non-process-intensive parts of my game appear to be getting over 100, and I'm getting the diagonal tearing. picodrive seems to be perfectly synced
 
Well that code used to work, but I was doing tests on early firmwares.

The LCD doesn't run at 60Hz, it's something in 80-100Hz range.. Also be aware kernel timers on Wiz/Caaonoo are broken, so you can't sleep less than ~13ms (or so), and if you poll for time you get jumpy values. There is direct timer code somewhere on these boards, or you can code your own after reading Pollux databook.

PicoDrive cheats by setting LCD refresh to 100/120Hz for PAL/NTSC (it can't operate well at 50/60Hz) and there is somewhere pollux_set tool (with source) which should help you do that too if you want.
 
notaz said:
I'm pretty sure FBIO_WAITFORVSYNC is not supported by Wiz/Caanoo's kernel.

I used this code in PicoDrive:
Code:
static void gp2x_video_wait_vsync_(void)
{
        while (!(memregl[0x308c>>2] & (1 << 10)))
                ;
        memregl[0x308c>>2] |= 1 << 10;
}
memregl is int pointer to mmap'ed soc registers.

I got something going by monitoring the Dirtyflag on the RGB layer 1 control register. When you set the new frame buffer address the dirty bit gets set. Then during Vsync the hardware clears the dirty flag. So I just sit there waiting for the bit to be cleared.

while((mMemRegl[0x4058>>2] & 0x10) != 0);

EDIT. Out of interest I just used your method and it works fine for me as well on firmware v1.6.0.
 
Last edited by a moderator:
Back
Top