Help Needing With Low-level Double Buffering


Alain21

Still Fresh
Joined
Apr 14, 2007
Messages
15
I can seem to get the Double buffering system to work

Here is my init code:
CODE

gRegGP2X2DEng = (TRegGp2x2DEng*)mmap(0, 0x200, PROT_READ|PROT_WRITE, MAP_SHARED, gDevMem, 0xE0020000);
vmem = (u16*)mmap(NULL, 8*1024*1024, PROT_READ|PROT_WRITE, MAP_SHARED, gDevMem, 0x3101000);
m_pFB = vmem;
m_pBB = vmem + 0x280000;

gRegGP2X->LCD_DisplayAdressLow = u32((m_pFB - vmem) + 0x3101000) & 0xFFFF;
gRegGP2X->LCD_DisplayAdressHigh = u32((m_pFB - vmem) + 0x3101000) >> 16;
gRegGP2X->LCD_DisplayAdressInterlacedLow = u32((m_pFB - vmem) + 0x3101000) & 0xFFFF;
gRegGP2X->LCD_DisplayAdressInterlacedHigh = u32((m_pFB - vmem) + 0x3101000) >> 16;



gRegGP2X is a bitfield by the way

and here is my flipping :

CODE

while(gRegGP2X->m_regGPIO_In.LCD_VSync);
printf("Wait VSync1\n");
printf("Going to set 0x%x\n", uint((m_pBB - vmem) + 0x3101000));

gRegGP2X->LCD_DisplayAdressLow = u32((m_pBB - vmem) + 0x3101000) & 0xFFFF;
gRegGP2X->LCD_DisplayAdressHigh = u32((m_pBB - vmem) + 0x3101000) >> 16;
gRegGP2X->LCD_DisplayAdressInterlacedLow = u32((m_pBB - vmem) + 0x3101000) & 0xFFFF;
gRegGP2X->LCD_DisplayAdressInterlacedHigh = u32((m_pBB - vmem) + 0x3101000) >> 16;

u16* temp = m_pFB;
m_pFB = m_pBB;
m_pBB = temp;

while(!gRegGP2X->m_regGPIO_In.LCD_VSync);
printf("Wait VSync2\n");



in the client code I keep writing to m_pBB ... but all I see is the screen flicker Black/Frame/Black/Frame/

so i suspect that one of them is not fine.
Thx very much
 
Update I have change some thing after trying to take a look at what is done inside SDL

CODE

vmem= (u16*)mmap(NULL, 8*1024*1024, PROT_READ|PROT_WRITE, MAP_SHARED, gDevMem, 0x3101000);
m_pFB= vmem;
m_pBB= vmem + 0x280000;



to

CODE

vmem= (u16*)mmap(NULL, 5*1024*1024, PROT_READ|PROT_WRITE, MAP_SHARED, gDevMem, 0x3101000);
m_pFB= vmem;
m_pBB= (u16*)(u32(vmem) + 320*240*2);



Put the second buffer right after the first one. And of course changing the reserved zone in UpperMemoryManager

In the client code what I do is
CODE

if(bb == (u16*)0x424ca000){
for(int i= 0; i < 320; ++i){
for(int j= 0; j < 240; ++j){
bb[j*320+i]= 0xFF00;
}
}
}else{
for(int i= 0; i < 320; ++i){
for(int j= 0; j < 240; ++j){
bb[j*320+i]= 0x00FF;
}
}
}



Got it fill one buffer kinda yellow and the other kinda blue .... what I should see is the entire screen flash in yellow and blue. But what I see Is One Frame Entirely Yellow ... and the top Half Yellow Bottom Half Blue ....

What is wrong with my adresses !?!?!

any help is appreciated
 
Wooo hooo .... found it ... damn it wasn't obvious at all !! ...

If anyone can find the problem in the flip code that I posted previously, that guy is strong !!

I'll post the answer shortly
Alain
 
rlyeh said:
m_pBB= (u16*)(u32(vmem) + 320*240*4);
nice try but as far as I know there is nothing wrong with that ... the problem was

CODE

gRegGP2X->LCD_DisplayAdressLow = u32((m_pFB - vmem) + 0x3101000) & 0xFFFF;
gRegGP2X->LCD_DisplayAdressHigh = u32((m_pFB - vmem) + 0x3101000) >> 16;
gRegGP2X->LCD_DisplayAdressInterlacedLow = u32((m_pFB - vmem) + 0x3101000) & 0xFFFF;
gRegGP2X->LCD_DisplayAdressInterlacedHigh = u32((m_pFB - vmem) + 0x3101000) >> 16;



especially doing :

CODE

m_pFB - vmem



Doing arithmetic operation on pt will result on the number of ELEMENTS between them not the number of BYTES. I was especting a certain number but instead the result was Half of it, so setting the pt in the register was halved so that is why i could see half the FB and half BB.

So I fix it using

CODE

gRegGP2X->LCD_DisplayAdressLow = u32((u32(m_pBB) - u32(vmem)) + 0x3101000) & 0xFFFF;
gRegGP2X->LCD_DisplayAdressHigh = u32((u32(m_pBB) - u32(vmem)) + 0x3101000) >> 16;
gRegGP2X->LCD_DisplayAdressInterlacedLow = u32((u32(m_pBB) - u32(vmem)) + 0x3101000) & 0xFFFF;
gRegGP2X->LCD_DisplayAdressInterlacedHigh = u32((u32(m_pBB) - u32(vmem)) + 0x3101000) >> 16;



Doing the cast before the arithmetic
 
Last edited by a moderator:
Back
Top