forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Getting simple framebuffer going

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
Sdw



Joined: 17 Jul 2007
Posts: 29

PostPosted: Tue Jul 17, 2007 11:26 pm    Post subject: Getting simple framebuffer going Reply with quote

I've just got my PSP development environment up and running, and I'm trying to do some really basic things like getting a simple framebuffer to work.
However the only thing I get is a black screen. Can anyone spot any obvious mistakes:

Code:

#include <pspkernel.h>
#include <pspdisplay.h>

PSP_MODULE_INFO("Gfx Test", 0, 1, 1);

unsigned int frameBuf[512*272];

/* Exit callback */
int exit_callback(int arg1, int arg2, void *common)
{
   sceKernelExitGame();
   return 0;
}

/* Callback thread */
int CallbackThread(SceSize args, void *argp)
{
    int cbid;
   
    cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
    sceKernelRegisterExitCallback(cbid);   
    sceKernelSleepThreadCB();   
    return 0;
}

/* Sets up the callback thread and returns its thread id */
int SetupCallbacks(void)
{
   int thid = 0;

   thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
     if(thid >= 0)
     {
      sceKernelStartThread(thid, 0, 0);
   }
   return thid;
}

int main()
{
   int x,y;
   
   SetupCallbacks();
   for(x=0;x<480;x++)
   {
      for(y=0;y<272;y++)
      {
         frameBuf[y*512+x]=(x&255)+((y&255)*256);
      }
   }
   sceDisplaySetMode(0,480,272);
   sceDisplaySetFrameBuf((char*)frameBuf, 512, PSP_DISPLAY_PIXEL_FORMAT_8888, PSP_DISPLAY_SETBUF_IMMEDIATE);
   sceKernelSleepThread();
   return 0;
}
Back to top
View user's profile Send private message
kururin



Joined: 05 Jul 2006
Posts: 36

PostPosted: Wed Jul 18, 2007 2:09 am    Post subject: Re: Getting simple framebuffer going Reply with quote

Sdw wrote:
I've just got my PSP development environment up and running, and I'm trying to do some really basic things like getting a simple framebuffer to work.
However the only thing I get is a black screen. Can anyone spot any obvious mistakes:

Code:

#include <pspkernel.h>
#include <pspdisplay.h>

PSP_MODULE_INFO("Gfx Test", 0, 1, 1);

unsigned int frameBuf[512*272];

/* Exit callback */
int exit_callback(int arg1, int arg2, void *common)
{
   sceKernelExitGame();
   return 0;
}

/* Callback thread */
int CallbackThread(SceSize args, void *argp)
{
    int cbid;
   
    cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
    sceKernelRegisterExitCallback(cbid);   
    sceKernelSleepThreadCB();   
    return 0;
}

/* Sets up the callback thread and returns its thread id */
int SetupCallbacks(void)
{
   int thid = 0;

   thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
     if(thid >= 0)
     {
      sceKernelStartThread(thid, 0, 0);
   }
   return thid;
}

int main()
{
   int x,y;
   
   SetupCallbacks();
   for(x=0;x<480;x++)
   {
      for(y=0;y<272;y++)
      {
         frameBuf[y*512+x]=(x&255)+((y&255)*256);
      }
   }
   sceDisplaySetMode(0,480,272);
   sceDisplaySetFrameBuf((char*)frameBuf, 512, PSP_DISPLAY_PIXEL_FORMAT_8888, PSP_DISPLAY_SETBUF_IMMEDIATE);
   sceKernelSleepThread();
   return 0;
}


unsigned int frameBuf[512*272]; -> unsigned int *frameBuf = (u32 *)0x04000000;
Back to top
View user's profile Send private message
Sdw



Joined: 17 Jul 2007
Posts: 29

PostPosted: Wed Jul 18, 2007 2:26 am    Post subject: Reply with quote

Thanks for the reply! I gave it a try, but it didn't make any difference - still black screen.
If I understand it correctly, the change was to put the framebuffer in videomem instead of main mem, right?
I read an article that stated that if you were planning on filling the framebuffer with CPU-calculated stuff as opposed to using the GPU, you should actually keep the framebuffer in main mem for better performance, however this might have been wrong.

However, right now I would be happy if it could display any framebuffer at all, be it from main or video mem... Argh, it seems like such a simple thing, I just can't see what is going wrong!

-edit-

Just to clarify what happens - I get a black screen, however the PSP hasn't locked up or anything, when I press the "home" button I get the "do you want to quit.." prompt just as it is supposed to.
Back to top
View user's profile Send private message
Raphael



Joined: 17 Jan 2006
Posts: 646
Location: Germany

PostPosted: Wed Jul 18, 2007 4:11 am    Post subject: Reply with quote

Code:

...

unsigned int frameBuf[512*272];

int main(int argc, char *argv[])
{
   int x,y;
   
   SetupCallbacks();
   for(y=0;y<272;y++)
   {
      for(x=0;x<480;x++)
      {
         frameBuf[y*512+x]=(x&255)+((y&255)*256);
      }
   }
   sceKernelDcacheWritebackAll();
   sceDisplaySetMode(0,480,272);
   sceDisplaySetFrameBuf(frameBuf, 512, PSP_DISPLAY_PIXEL_FORMAT_8888, PSP_DISPLAY_SETBUF_IMMEDIATE);
   
   sceKernelSleepThread();
   sceKernelExitGame();
   return(0);
}


Works perfectly fine for me. Make sure you're on the latest toolchain and SDK. Also, if you really want to do software drawing having the framebuffer in sys ram is faster, yes.
_________________
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
Back to top
View user's profile Send private message Visit poster's website
Sdw



Joined: 17 Jul 2007
Posts: 29

PostPosted: Wed Jul 18, 2007 5:20 am    Post subject: Reply with quote

I still just get the black screen. Could you post your entire code, and also your Makefile and I'll see if I can compile it EXACTLY as yours.

I'm using the latest toolchain downloaded from ps2dev.org. My makefile looks like this:

Code:

TARGET = test
OBJS = test.o

CFLAGS = -O2 -G0 -Wall
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)

EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = Gfx Test

PSPSDK=/usr/local/pspdev/psp/sdk
include $(PSPSDK)/lib/build.mak


and I compile it with 'make kxploit'
Back to top
View user's profile Send private message
Sdw



Joined: 17 Jul 2007
Posts: 29

PostPosted: Wed Jul 18, 2007 8:10 am    Post subject: Reply with quote

AAAAAARGHHH!! This is driving me TOTALLY NUTS! I've developed for tons of more or less strange systems (GP32, TI83, C64DTV etc. etc.) and I have never ever been so totally stuck (going on 24 hours now!) with something so basic!

How hard can it be to get a god damn framebuffer going? Can't someone please provide a complete source. I've been searching the net for several hours now and I can't find a single complete source code that shows how to do this.
I found a whole bunch of samples that shows using the 3D hardware and all other jazz, but nothing that just shows "set up a double buffered linear 32 bit framebuffer, then do a fire effect" or something like that.
The only "simple" sources I found only use pspDebugScreenInit()/pspDebugScreenPrintf and that works fine for me, but I want a framebuffer that I can draw to myself!
Back to top
View user's profile Send private message
Sdw



Joined: 17 Jul 2007
Posts: 29

PostPosted: Wed Jul 18, 2007 8:39 am    Post subject: Reply with quote

OK, I think I've found the problem. The following code demonstrates the problem:

Code:

unsigned int* frameBuf = (0x40000000 | (0x04000000));
//unsigned int frameBuf[512*272];

int main()
{
   int x,y;
   
   SetupCallbacks();
   sceDisplaySetMode(0,480,272);
   sceDisplaySetFrameBuf(frameBuf, 512, PSP_DISPLAY_PIXEL_FORMAT_8888, PSP_DISPLAY_SETBUF_IMMEDIATE);
   for(y=0;y<272;y++)
   {
      for(x=0;x<480;x++)
      {
         frameBuf[y*512+x]=(x&255)+((y&255)*256)+(((x+y)&255)*65536);
      }
   }
   sceKernelDelayThread(3000000);   
   pspDebugScreenInit();
   for(y=0;y<272;y++)
   {
      for(x=0;x<480;x++)
      {
         frameBuf[y*512+x]=(x&255)+((y&255)*256)+(((x+y)&255)*65536);
      }
   }   
   sceKernelSleepThread();   
   return 0;
}


The first three seconds is only black screen, then the image is shown correctly. Using a non vram-framebuffer (the commented code) yields black screen all the time.
So my only conclusion is that sceDisplaySetFrameBuf is somehow completely buggy and does just about nothing useful, but that doesn't make any sense at all...
Somehow running pspDebugScreenInit seems to point the frameBuffer at the default location (0x44000000), but this is a poor solution since I don't get double buffer etc. and I had preferred to have the buffer in main mem anyway.
Back to top
View user's profile Send private message
Jim



Joined: 02 Jul 2005
Posts: 487
Location: Sydney

PostPosted: Wed Jul 18, 2007 9:39 am    Post subject: Reply with quote

Because you haven't flushed the dcache.

sceKernelDcacheWritebackAll();

Jim
_________________
http://www.dbfinteractive.com
Back to top
View user's profile Send private message Visit poster's website
Raphael



Joined: 17 Jan 2006
Posts: 646
Location: Germany

PostPosted: Wed Jul 18, 2007 9:41 am    Post subject: Reply with quote

Code:

#include <pspdisplay.h>
#include <pspkernel.h>

PSP_MODULE_INFO("Gfx Test", 0, 1, 1);
PSP_MAIN_THREAD_ATTR(0);

/* Exit callback */
int exit_callback(int arg1, int arg2, void *common)
{
   sceKernelExitGame();
   return 0;
}

/* Callback thread */
int CallbackThread(SceSize args, void *argp)
{
    int cbid;
   
    cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
    sceKernelRegisterExitCallback(cbid);   
    sceKernelSleepThreadCB();   
    return 0;
}

/* Sets up the callback thread and returns its thread id */
int SetupCallbacks(void)
{
   int thid = 0;

   thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
     if(thid >= 0)
     {
      sceKernelStartThread(thid, 0, 0);
   }
   return thid;
}

unsigned int frameBuf[512*272];

int main(int argc, char *argv[])
{
   int x,y;
   
   SetupCallbacks();
   for(y=0;y<272;y++)
   {
      for(x=0;x<480;x++)
      {
         frameBuf[y*512+x]=(x&255)+((y&255)*256);
      }
   }
   sceKernelDcacheWritebackAll();
   sceDisplaySetMode(0,480,272);
   sceDisplaySetFrameBuf(frameBuf, 512, PSP_DISPLAY_PIXEL_FORMAT_8888, PSP_DISPLAY_SETBUF_IMMEDIATE);
   
   sceKernelSleepThread();
   sceKernelExitGame();
   return(0);
}


Makefile:
Code:

TARGET = main6
OBJS = main6.o

INCDIR =
CFLAGS = -O2 -G3 -g -Wall
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)

LIBDIR =
LDFLAGS =
LIBS=-lpspdisplay

EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = Test

PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak


As said, it works perfectly, don't know what problem you have with that.
_________________
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
Back to top
View user's profile Send private message Visit poster's website
Sdw



Joined: 17 Jul 2007
Posts: 29

PostPosted: Wed Jul 18, 2007 7:52 pm    Post subject: Reply with quote

OK, now this problem has passed way into bizarro-land!
I built with Raphaels code, both makefile and source and I get the SAME PROBLEM! Just black screen!
I've uploaded the compiled files here:
http://sdw.webhop.net/tmp/test.zip
Please someone try them on your PSP and see if you get graphics or not.
Also, Raphael, could you post the binaries you built, so I can try them and also do a binary compare and see if our toolchains produce different results.

Could it be something with my PSP? I run 3.40 OE-A and I place the files in the "GAME150" directory. But I haven't had any problems with other homebrew, so I've got a hard time thinking the problem is on the hardware side.

I build using cygwin (latest release, downloaded yesterday) and psptoolchain-20070626.tar.bz2.
I get no compiler errors/warning or other indications that something should not be right.
Strangeness++!!!
Back to top
View user's profile Send private message
Raphael



Joined: 17 Jan 2006
Posts: 646
Location: Germany

PostPosted: Thu Jul 19, 2007 2:35 am    Post subject: Reply with quote

Your eboot works fine for me too, at least from PSPLink. From XMB I get the same result as you though (even with my binary). After finding this, I tried around a bit more and it seems the setFrameBuf call somehow fails when called from XMB, as a subsequent getFrameBuf call always returns the same, no matter if setFrameBuf was called or not (though the returned address is weird - it's 0, same for width, only the pixelformat is correct, so probably that call just fails too? but why is the pfm set correctly?).
Apart from that, the same function works just fine within PMP Mod, where it is used to display the decoded video in system RAM. So I really don't know what's happening here.
I also tried running the app in Kernel mode, but that didn't make a difference (only the home button callback was messed up by not accepting my O button input on YES).
As a last resort, I could imagine to try to call the function from a new thread (as is done in PMP Mod), though I don't know why that should make a difference.
Maybe TyRaNiD has an idea why it works flawless from PSPLink, though I'm pretty sure it's nothing specific with PSPLink that makes the call succeed.

At least, it's nothing to do with your setup.

here's the last code I used:
Code:


__attribute__((aligned(64))) unsigned int frameBuf[512*272];


int main(int argc, char *argv[])
{
   int x,y;
   void *buf = -1;
   int width = -512, pfm = -3, vsync = -9;
   SetupCallbacks();

   for(y=0;y<272;y++)
   {
      for(x=0;x<480;x++)
      {
         frameBuf[y*512+x]=(x&255)+((y&255)*256);
      }
   }
   sceKernelDcacheWritebackAll();
   sceDisplaySetMode(0,480,272);
   sceDisplaySetFrameBuf(frameBuf, 512, PSP_DISPLAY_PIXEL_FORMAT_8888, PSP_DISPLAY_SETBUF_IMMEDIATE);
   int ret = sceDisplayGetFrameBuf( &buf, &width, &pfm, &vsync );
   sceKernelDelayThread(1000*2000);

   pspDebugScreenInit();
   pspDebugScreenPrintf("(%i) %p:%i:%i:%i\n", ret, buf, width, pfm, vsync );
   
   sceKernelSleepThread();
   sceKernelExitGame();
   return(0);
}

_________________
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
Back to top
View user's profile Send private message Visit poster's website
Raphael



Joined: 17 Jan 2006
Posts: 646
Location: Germany

PostPosted: Thu Jul 19, 2007 3:34 am    Post subject: Reply with quote

Some more findings:
I wondered why the SetFrameBuf function wouldn't return a error code like all other pspdisplay functions do, so I just tried making it return a value and it seems it really does. Running from PSPLink the function returns 0 (success), while from XMB it returns 0x80000107, which looks like some error code. After some testing from PSPLink, it seems the code denotes a wrong argument, as it is given when the buffer width or pixelformat are different from 512 and 3 (seems like SetFrameBuf only works in 32bit). The error code 0x80000103 means something like "invalid pointer", since this is the return value if you supply a -1 as framebuffer argument (not with null though?) or a null pointer for GetFrameBuf - not the last argument though, see below for explanation.

So from here it was clear that the function was denied because of a wrong argument, but using 512, 3, PSP_DISPLAY_SETBUF_IMMEDIATE didn't change the behaviour in XMB. Now I tried 512, 3, 1 (_NEXT) and tada - it works.
I'm not sure yet, why the call from XMB will resolve PSP_DISPLAY_SETBUF_IMMEDIATE as invalid argument, but that shouldn't be a problem to find out (maybe the call just happens at a problematic time, like during the vblank? At least the same argument is used in PMP Mod and works there).

Now regarding GetFrameBuf:
As the tests showed, the function doesn't care about the last argument being NULL, so it seems the last argument isn't a pointer but rather an immediate value - my guess is the same as in SetFrameBuf, since that would make sense: It denotes when the poll for the frame buffer mode is to be done, immediately or on next vblank.

I'm gonna throw up a patch for this and post it later.
_________________
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
Back to top
View user's profile Send private message Visit poster's website
Sdw



Joined: 17 Jul 2007
Posts: 29

PostPosted: Thu Jul 19, 2007 3:38 am    Post subject: Reply with quote

Raphael - I can't thank you enough for helping me with this!
I was just about ready to tear my hair and/or throw the PSP in the wall, but now it seems like it was one of those rare occasions when a bug actually was NOT caused by my code! :D

It is really strange though, I wonder how all other programs that work from the XMB access the framebuffer (say emulators etc.) Perhaps they always do some kind of render-to-texture and use the video hardware?
But I do find it strange that noone has encountered this before, I thought my example was just about the first thing any programmer would try!
Back to top
View user's profile Send private message
Sdw



Joined: 17 Jul 2007
Posts: 29

PostPosted: Thu Jul 19, 2007 3:45 am    Post subject: Reply with quote

Exactly how did your code look when you got it to work, I didn't quite get what you meant by "512, 3, 1 (_NEXT)" ?
Back to top
View user's profile Send private message
Raphael



Joined: 17 Jan 2006
Posts: 646
Location: Germany

PostPosted: Thu Jul 19, 2007 3:49 am    Post subject: Reply with quote

Normally emulators and other applications use the GU to render stuff, which directly draws to VRAM so they don't make use of SetFrameBuf at all. Only exception I know of is PMP Mod and as said, it worked there.

Code:
sceDisplaySetFrameBuf( frameBuf, 512, PSP_DISPLAY_PIXEL_FORMAT_8888, PSP_DISPLAY_SETBUF_NEXTFRAME );

This works fine from XMB.

Glad I could help with this, as I just know too well how frustrating PSP development can be sometimes. Hope to see some good stuff from you in the future to make up though ;P
_________________
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
Back to top
View user's profile Send private message Visit poster's website
jimparis



Joined: 10 Jun 2005
Posts: 1179
Location: Boston

PostPosted: Thu Jul 19, 2007 5:11 am    Post subject: Reply with quote

Probably _IMMEDIATE only works in certain cases. pspDebugScreenInit (which most homebrew calls at startup.. including psplink) uses _NEXTFRAME. Maybe after that _IMMEDIATE is fine, but sticking with _NEXTFRAME seems safe -- as far as I know nobody has ever had a problem with pspDebugScreenInit.
Back to top
View user's profile Send private message
Sdw



Joined: 17 Jul 2007
Posts: 29

PostPosted: Thu Jul 19, 2007 9:43 am    Post subject: Reply with quote

Raphael wrote:
Glad I could help with this, as I just know too well how frustrating PSP development can be sometimes. Hope to see some good stuff from you in the future to make up though ;P


Aw man, that's some serious pressure you are putting on me!
Well, I'll see what I can come up with... :)
I'm guessing my 15-minutes-of-code-radial-plasma I just finished isn't going to cut it? At least I finished what I set out to do a couple of days ago, only it took like 60 hours total instead of the 30 minutes I originally anticipated... ;)
Back to top
View user's profile Send private message
Sdw



Joined: 17 Jul 2007
Posts: 29

PostPosted: Sat Jul 21, 2007 12:09 am    Post subject: Reply with quote



Yay! Triple buffered plasma up and running! And there was much rejoicing... :)
Back to top
View user's profile Send private message
PeterM



Joined: 31 Dec 2005
Posts: 125
Location: Edinburgh, UK

PostPosted: Sat Jul 21, 2007 9:01 am    Post subject: Reply with quote

Woo, looks pretty! Thanks for sharing!
_________________
http://aaiiee.wordpress.com/

I can no longer do any homebrew PSP development nor discuss PSP specific topics.
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group