 |
forums.ps2dev.org Homebrew PS2, PSP & PS3 Development Discussions
|
| View previous topic :: View next topic |
| Author |
Message |
Sdw
Joined: 17 Jul 2007 Posts: 29
|
Posted: Tue Jul 17, 2007 11:26 pm Post subject: Getting simple framebuffer going |
|
|
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 |
|
 |
kururin
Joined: 05 Jul 2006 Posts: 36
|
Posted: Wed Jul 18, 2007 2:09 am Post subject: Re: Getting simple framebuffer going |
|
|
| 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 |
|
 |
Sdw
Joined: 17 Jul 2007 Posts: 29
|
Posted: Wed Jul 18, 2007 2:26 am Post subject: |
|
|
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 |
|
 |
Raphael

Joined: 17 Jan 2006 Posts: 646 Location: Germany
|
Posted: Wed Jul 18, 2007 4:11 am Post subject: |
|
|
| 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 |
|
 |
Sdw
Joined: 17 Jul 2007 Posts: 29
|
Posted: Wed Jul 18, 2007 5:20 am Post subject: |
|
|
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 |
|
 |
Sdw
Joined: 17 Jul 2007 Posts: 29
|
Posted: Wed Jul 18, 2007 8:10 am Post subject: |
|
|
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 |
|
 |
Sdw
Joined: 17 Jul 2007 Posts: 29
|
Posted: Wed Jul 18, 2007 8:39 am Post subject: |
|
|
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 |
|
 |
Jim

Joined: 02 Jul 2005 Posts: 487 Location: Sydney
|
Posted: Wed Jul 18, 2007 9:39 am Post subject: |
|
|
Because you haven't flushed the dcache.
sceKernelDcacheWritebackAll();
Jim _________________ http://www.dbfinteractive.com |
|
| Back to top |
|
 |
Raphael

Joined: 17 Jan 2006 Posts: 646 Location: Germany
|
Posted: Wed Jul 18, 2007 9:41 am Post subject: |
|
|
| 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 |
|
 |
Sdw
Joined: 17 Jul 2007 Posts: 29
|
Posted: Wed Jul 18, 2007 7:52 pm Post subject: |
|
|
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 |
|
 |
Raphael

Joined: 17 Jan 2006 Posts: 646 Location: Germany
|
Posted: Thu Jul 19, 2007 2:35 am Post subject: |
|
|
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 |
|
 |
Raphael

Joined: 17 Jan 2006 Posts: 646 Location: Germany
|
Posted: Thu Jul 19, 2007 3:34 am Post subject: |
|
|
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 |
|
 |
Sdw
Joined: 17 Jul 2007 Posts: 29
|
Posted: Thu Jul 19, 2007 3:38 am Post subject: |
|
|
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 |
|
 |
Sdw
Joined: 17 Jul 2007 Posts: 29
|
Posted: Thu Jul 19, 2007 3:45 am Post subject: |
|
|
| 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 |
|
 |
Raphael

Joined: 17 Jan 2006 Posts: 646 Location: Germany
|
Posted: Thu Jul 19, 2007 3:49 am Post subject: |
|
|
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 |
|
 |
jimparis
Joined: 10 Jun 2005 Posts: 1179 Location: Boston
|
Posted: Thu Jul 19, 2007 5:11 am Post subject: |
|
|
| 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 |
|
 |
Sdw
Joined: 17 Jul 2007 Posts: 29
|
Posted: Thu Jul 19, 2007 9:43 am Post subject: |
|
|
| 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 |
|
 |
Sdw
Joined: 17 Jul 2007 Posts: 29
|
Posted: Sat Jul 21, 2007 12:09 am Post subject: |
|
|
Yay! Triple buffered plasma up and running! And there was much rejoicing... :) |
|
| Back to top |
|
 |
PeterM
Joined: 31 Dec 2005 Posts: 125 Location: Edinburgh, UK
|
Posted: Sat Jul 21, 2007 9:01 am Post subject: |
|
|
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 |
|
 |
|
|
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
|