Welcome! Log In Create A New Profile

Advanced

Direct XFD access

Posted by Roor 
Direct XFD access
December 07, 2008 10:45PM
I'be been trying to solve a problem regarding direct access to the external framebuffer (xfd).

When I render to screen (when having my Wii connected through a three component RGB cable) everything runs ok...
but whenever I try it on with a normal TV cable (on any 240 or 480 render mode) I get this ugly "flickering" on all screen.

I already made it run with GX (creating a full screen texture for every frame)... but that's extremelly slow in comparison :(
( I have to make texture packaging for every frame... and also, this prevents me from making "partial" updates into display memory).

How should I arrange data (graphics) to be loaded into XFD in order to avoid this "flickering" when it get to screen?

The only meaningfull thing I noticed so far, is that in 640x240 modes, flickering doesn't occur if I only write data into "even" horizontal lines, and leave the "odd" lines in black color.

Any clues?

Thanks forward,
Roor
Re: Direct XFD access
December 08, 2008 11:33AM
flickering happens in the 480i mode because a single line is actually only refreshed at 30hz
when you use the component cable, I bet your wii outputs at 480p so you don't have any problems
same goes for 640*240 modes, which are non-interlaced and have a proper 60hz refresh rate (in this mode though, xfb height must be half the VI height, that is 240 lines)
you can have 640x240 interlaced mode also but in that case, you have to rewrite manually the xfb before each vsync to output alternatively odd and even lines, the visual result being the same as flickered 480i

to prevent flickering , the only way is to use the GX rendering (there is a hardware deflickering filter when doing the EFB to XFB copy) or to do software filtering on the xfb yourself but it's probably quite slow

be sure to also use double or triple buffering techniques and always wait for two VSYNC (2 fields) before updating your screen, it might help reducing some artifacts

finally, if you have a PAL wii set to 480i and want to use the GX deflickering ability, beware that libogc VIDEO_GetPreferredMode will return a video mode that does not use the deflickering filter by default (TVEurgb60Hz480Int), you will have to reconfigure the video mode yourself to TVEurgb60Hz480IntDf



Edited 1 time(s). Last edit at 12/08/2008 11:40AM by ekeeke.
Re: Direct XFD access
December 10, 2008 02:17AM
Thanks a lot for your help.

I already remade it in 640x240 single-field (non-interlaced mode) the same night I made this post.

But I found another problem there :(

I can't seem to be able to draw a "straight horizontal line".
It is really weird, but everytime I just draw a line, or a pair of consecutive horizontal pixels.... intead of getting an horizontal lines... I get a two "fractured" lines... getting even pixels on one horizontal line, and odd pixels on the other.

Something like:

1 3 5 7
2 4 6 8

Instead of just:

1234567

Is there an effective way for handling this?

Thanks a lot in advance,

Roor
Re: Direct XFD access
December 10, 2008 10:20AM
how do you draw these lines ?

if you are using XFB direct writing, you must be aware of the weird XFB data format ... this is certainly a problem in your code, in the way you output the data

you should "pastebin" it somewhere so anyone could look at it and tells you what is wrong
Re: Direct XFD access
December 10, 2008 08:05PM
I made this very little stub in order to show how I render stuff to screen.
It is a very simple approach. It worked VERY WELL while I was using it in 640x480, with a RGB component cable... but when I tried the same code using a normal TV cable... I got all that flickering on screen (because of the reasons we all know already).

But when I tried it on a 640x240 videomode (single field, in order to avoid the same problem as before) I find that it seems that "pixels" are not packed exactly the same way :( (as described in my previous post). If you have any clue, it would be greatly appreaciated.

Anyway, thanks in forward,

Roor

----------------------------------

static unsigned long *xfb = NULL;
static GXRModeObj *rmode = NULL;
unsigned long *VRAM = NULL;
bool CanDraw=false;

void Retrace(u32 arg)
{
if (CanDraw)
{
for (int bi = 0; bi<200; bi++) memcpy(xfb+((bi+20)*320),VRAM+(bi*640),320*4);
VIDEO_Flush();
}
}

void SHELL_Run(void)
{
while (1)
{
// HERE VRAM IS UPDATED WITH THE DATA I WANT TO DISPLAY ON SCREEN
// AND I SET CanDraw=true; IF I WANT IT SENT TO SCREEN (XFB)
// OF COURSE ALL DATA IN "VRAM" IS STORED AS YUV422 (YUYV) AS A NORMAL (640X240 2D FRAME BUFFER)
// IE: IF I WANT A HORIZONTAL LINE OF "TWO" GREEN COLORED PIXELS IN THE MIDDLE OF SCREEN I'LL BE WRITING: VRAM[160+(120*320)]=0x0;
// PROBLEM: XFB INFORMATION DOESN'T SEEM TO BE EXACTLY "LINEAR" IN THIS 640X240 MODE... AS IT WAS IN 640X480 :(
}
}

int main(int argc, char *argv[])
{
VRAM=(unsigned long*)memalign(32,4*640*400);
VIDEO_Init();
rmode=TVNtsc240Ds;
xfb = (unsigned long*)MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
VIDEO_Configure(rmode);
VIDEO_ClearFrameBuffer (rmode, xfb, COLOR_BLACK);
VIDEO_SetNextFramebuffer(xfb);
VIDEO_SetBlack(FALSE);
VIDEO_Flush();
VIDEO_WaitVSync();
if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();
VIDEO_SetPreRetraceCallback((VIRetraceCallback)Retrace);
SHELL_Run();
VIDEO_SetPreRetraceCallback(NULL);
free(VRAM);
return 0;
};



Edited 1 time(s). Last edit at 12/10/2008 08:11PM by Roor.
Sorry, only registered users may post in this forum.

Click here to login