Hello everyone. I have run across a problem while trying to use GU_SEND diplay lists with double buffering. It works... kind of... If i use GU_DIRECT - all is perfect, but as soon as i switch to GU_SEND, it looks like sceGuSwapBuffers() stops working. Only each 2nd frame is shown (looks like : frame/black/frame/black/frame... etc). Maybe someone could lend a hand on this situation? I tried to search for additional info on sceGuSendList() but with no success. Here is my draw-loop.
static unsigned int __attribute__((aligned(16))) __list[262144];
// Setup environment, nothing special...
while (running()) {
sceGuStart(GU_SEND,__list);
// --- Draw everything here ---
sceGuFinish();
sceGuSendList(GU_TAIL,__list,NULL);
sceGuSync(0,0);
sceDisplayWaitVblankStart();
sceGuSwapBuffers();
}
Once again - this codepath works perfectly if GU_SEND is replaced by GU_DIRECT. But i really-really need to work with GU_SEND. What's wrong with such approach? Thanks.
P.S. Sorry for bad english.
I have encountered the same problem man times, I eventually just decided it wasn't worth the hassle, but I suppose maybe this is a bug in the sdk. As I have never got sceGuSendList to work right. Ill take a look at the code, and see if I can spot something.
/**
* Enqueue a display list at the tail of the GE display list queue.
*
* @param list - The head of the list to queue.
* @param stall - The stall address.
* If NULL then no stall address set and the list is transferred immediately.
* @param cbid - ID of the callback set by calling sceGeSetCallback
* @param arg - Structure containing GE context buffer address
*
* @return The ID of the queue.
*/
int sceGeListEnQueue(const void *list, void *stall, int cbid, PspGeListArgs *arg);
Well, in case someone might need it, here's the workaround. Putting 1 call to GuStart() with GU_DIRECT mode (and finishing it right away) right after sceGuSwapBuffers() seems solve the problem. Here is my rendering loop when frame being rendered while next frame is being computed. So i managed to keep sceGuSync() execution time down to 100 µs.
// At this point, frame must be already rendered in display list
sceGuSync(0,0);
__fbp0 = sceGuSwapBuffers();
sceGuStart(GU_DIRECT,__list_blank);
sceGuFinish();
sceGuSendList(GU_TAIL,__list[frame_num%2],NULL); // Send frame to GE
frame_num++;
sceGuStart(GU_SEND,__list[frame_num%2]); // Start to fill current frame's display list
// ...rendering code