Between sceGuStart and sceGuFinish

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
Bits
Posts: 11
Joined: Mon Sep 19, 2005 5:25 am
Location: UK

Between sceGuStart and sceGuFinish

Post by Bits »

Hi all,

I have the wierdest thing happening.
The following simple code runs perfectly.

Code: Select all

  sceGuStart(GU_DIRECT, VideoBuf);
  sceGuClear(GU_COLOR_BUFFER_BIT);
  sceGuCopyImage(GU_PSM_8888,0,0,32,32,512,Sprites,xPos,yPos,512, (void *)ActivePage);
  sceGuFinish();
  sceGuSync(0,0);
But as soon as I move sceCopyImage into a procedure of its own...

Code: Select all

  
void Draw(void)
{
  sceGuCopyImage(GU_PSM_8888,0,0,32,32,512,Sprites,xPos,yPos,512,(void *)ActivePage);
}

...

  sceGuStart(GU_DIRECT, VideoBuf);
  sceGuClear(GU_COLOR_BUFFER_BIT);
  Draw();
  sceGuFinish();
  sceGuSync(0,0);
Then it doesn't draw anything.
Has it got something to do with allignment?
You know all the answers to life... don't make me tell you again.
Bits
Posts: 11
Joined: Mon Sep 19, 2005 5:25 am
Location: UK

Post by Bits »

I have more on this... now I'm really confused.
Sorry for the trouble... it's probably a beginner problem. :(

I have a main.c where I run my main code and then I have other units *.c and their *.h header files for individual sections, like graphics, pad and so on.

The above example showed the problem with moving sceGuCopyImage out into it's own procedure. The fact is, if it's in it's own procedure in my main.c file, it works, but as soon as it's in my graphics.c file then it does nothing. And... it is not just linked to that specific sce function. I now found that moving anything to my graphics unit results in doing nothing.

PLEASE HELP!!!

I'll prob feel like an idiot after someone tells me what i'm doing wrong. :)

example code...

graphics.h

Code: Select all

#define SCREEN_WIDTH 480
#define SCREEN_HEIGHT 272
#define SCREEN_BUFWIDTH 512

static unsigned int __attribute__((aligned(16))) Sprites[512*272];

int DoSomething(char* something);
graphics.c

Code: Select all

#include <psptypes.h>
#include <png.h>
#include <graphics.h>
#include <pspgu.h>
#include <stdlib.h>

int DoSomething&#40;char* something&#41;
&#123;
	unsigned int x, y;
	for &#40;y = 0; y < 272; y++&#41;
	&#123;
		unsigned int* row = &Sprites&#91;y * 512&#93;;
		for &#40;x = 0; x < 480; x++&#41;
		&#123;
			row&#91;x&#93; = 0xffffffff;
		&#125;
	&#125;
&#125;
makefile

Code: Select all

TARGET = Demo
OBJS = main.o graphics.o

INCDIR = 
CFLAGS = -O2 -G0 -Wall
CXXFLAGS = $&#40;CFLAGS&#41; -fno-exceptions -fno-rtti
ASFLAGS = $&#40;CFLAGS&#41;

LIBDIR =
LDFLAGS =
LIBS = -lpspgu -lpng -lz -lm

EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = Demo

PSPSDK=$&#40;shell psp-config --pspsdk-path&#41;
include $&#40;PSPSDK&#41;/lib/build.mak
If I put the code to fill up "Sprites" into my main.c file then it works but as soon as it is called from graphics.c then it does nothing.
You know all the answers to life... don't make me tell you again.
Shine
Posts: 728
Joined: Fri Dec 03, 2004 12:10 pm
Location: Germany

Post by Shine »

How did you allocate ActivePage? If it is static, try "__attribute__((aligned(16))) ". If you are using malloc, try memalign with 16 instead.
Bits
Posts: 11
Joined: Mon Sep 19, 2005 5:25 am
Location: UK

Post by Bits »

How did you allocate ActivePage? If it is static, try "__attribute__((aligned(16))) ". If you are using malloc, try memalign with 16 instead.
I am using __attribute__((aligned(16))).
You know all the answers to life... don't make me tell you again.
Shine
Posts: 728
Joined: Fri Dec 03, 2004 12:10 pm
Location: Germany

Post by Shine »

Bits wrote:I am using __attribute__((aligned(16))).
Ok, then probably something is wrong, because ActivePage should point to vram :-)

How did you allocate "VideoBuf"? It is not the video buffer, but the command list for the GE and for example you can use "static unsigned int __attribute__((aligned(16))) list[256];" and then "list" instead of "VideoBuf".
Bits
Posts: 11
Joined: Mon Sep 19, 2005 5:25 am
Location: UK

Post by Bits »

hehehehe <- (laugh of a man going crazy)

Ok, details...

I'm running in 32bit graphics mode.

The "list" is in fact...
static u32 __attribute__((aligned(16))) VideoBuf[512*272];

When I call sceGuStart I use...
sceGuStart(GU_DIRECT, VideoBuf);

Then I have 2 vars...
void* FrameBuffer = 0;
u32 ActivePage;

At the start of my main loop...
ActivePage = 0x04000000 + (u32)FrameBuffer;

At the end of my main loop...
FrameBuffer = sceGuSwapBuffers();

It still confuses me that everything works just fine if it sits in main.c but breaks when I move a simple bit of code to another unit.
You know all the answers to life... don't make me tell you again.
holger
Posts: 204
Joined: Thu Aug 18, 2005 10:57 am

Post by holger »

just to be sure: add an array of 64 extra-bytes before and after your command buffer array. Otherwise it may share a cache line with variables allocated before or after it, depending on the link order. This can lead to effects like the one you describe (the command buffer is accessed with uncached pointers, the other variables most likely as cached pointers. Writeback of the cache can thus destroy the first and last words of your command buffer content at any time).
Bits
Posts: 11
Joined: Mon Sep 19, 2005 5:25 am
Location: UK

Post by Bits »

I'm not too sure though what you mean by "command buffer array".

Could you explain please?
You know all the answers to life... don't make me tell you again.
holger
Posts: 204
Joined: Thu Aug 18, 2005 10:57 am

Post by holger »

That's the array you pass to sceGuStart(), where the libgu stores it's command packet for the GE. In your case "VideoBuf". So you want to do something like:

Code: Select all

static unsigned char margin_before_VideoBuf &#91;64&#93;;
static unsigned long __attribute__&#40;&#40;aligned&#40;16&#41;&#41;&#41; VideoBuf &#91;GE_CMD_BUF_SIZE&#93;;
static unsigned char margin_after_VideoBuf &#91;64&#93;;

Now you can be sure that your texture and vertex arrays declared before and after the command buffer won't share a cache line with the command buffer, and that you won't get inconsistencies when you are initializing or modifying one of them.
Bits
Posts: 11
Joined: Mon Sep 19, 2005 5:25 am
Location: UK

Post by Bits »

That looks like a good tip. I tried it but unfortionately it didn't make a difference. :(

Here is some more info that will help get to the bottom of this.

I took the "copy" GU example in the pspsdk and removed the sceGuCopyImage from the main file and put it in a new unit.

So the new unit has...

Code: Select all

#include <psptypes.h>
#include <png.h>
#include <pspgu.h>
#include <stdlib.h>
#include <test.h>

void Temp&#40;void&#41;
&#123;
  sceGuCopyImage&#40;GU_PSM_8888,0,0,480,272,512,pixels,0,0,512,&#40;void*&#41;&#40;0x04000000+&#40;u32&#41;framebuffer&#41;&#41;;
&#125;
(I left all the includes in just incase it has something to do with things not working)

Then I created a header file (test.h) and put the following in...

Code: Select all

static unsigned int __attribute__&#40;&#40;aligned&#40;16&#41;&#41;&#41; pixels&#91;512*272&#93;;

void* framebuffer;

void Temp&#40;void&#41;;
Obviously removing pixels from the main unit and replacing (void *) framebuffer = 0 with framebuffer = 0;

Drum-roll

Result = not working. Black screen. Same as what I get.
You know all the answers to life... don't make me tell you again.
Shine
Posts: 728
Joined: Fri Dec 03, 2004 12:10 pm
Location: Germany

Post by Shine »

Bits wrote:Then I created a header file (test.h) and put the following in...

Code: Select all

static unsigned int __attribute__&#40;&#40;aligned&#40;16&#41;&#41;&#41; pixels&#91;512*272&#93;;

void* framebuffer;

void Temp&#40;void&#41;;
This looks strange. Did you really define the pixels array in a header and did you include the static array in two C files? Of course, this don't work. Can you provide a zip file with your project?
Bits
Posts: 11
Joined: Mon Sep 19, 2005 5:25 am
Location: UK

Post by Bits »

Oooops... :) I've done exactly that.

(errr... where can I put this zip file?)
It's exactly the "copy" example with my additions mentioned above.

Oh man... I'm really wishing I'm an idiot in this case so I can sort out a quick and stupid problem and carry on.
You know all the answers to life... don't make me tell you again.
Shine
Posts: 728
Joined: Fri Dec 03, 2004 12:10 pm
Location: Germany

Post by Shine »

Bits wrote:Oooops... :) I've done exactly that.
I was assuming you know C :-)

Hint: you have 2 arrays. You are filling array 1 and you are displaying array 2.
Bits
Posts: 11
Joined: Mon Sep 19, 2005 5:25 am
Location: UK

Post by Bits »

Seasoned programmer, but not in C. :)

Brushing up as I go.

So, must I declare it in my main.c file and then "extern" it in my other files?

Could you help with what I must do please?
You know all the answers to life... don't make me tell you again.
CyberBill
Posts: 86
Joined: Tue Jul 26, 2005 3:53 pm
Location: Redmond, WA

Post by CyberBill »

Dont make your array static!!!!

Static arrays (in global scope) mean that the data is only accessable to THAT FILE.

Same goes with static global scope functions.

Make your array non-static, and then extern it at the top of your other file.
Bits
Posts: 11
Joined: Mon Sep 19, 2005 5:25 am
Location: UK

Post by Bits »

You guys are the best!!!

Thanks for all your help. It's working now.

To pay back my due's

I noticed that there is some code on this forum to capture a PNG file.
I fixed it up a bit and also wrote a procedure to open a PNG file (which I couldn't find anywhere).

I'll put it up once I've sorted out my code layout.

(If anyone wants it?)
You know all the answers to life... don't make me tell you again.
Shine
Posts: 728
Joined: Fri Dec 03, 2004 12:10 pm
Location: Germany

Post by Shine »

Bits wrote:I fixed it up a bit and also wrote a procedure to open a PNG file (which I couldn't find anywhere).

I'll put it up once I've sorted out my code layout.

(If anyone wants it?)
Thanks, but I'm not sure if I want to use code you've written :-)

Some code for loading a PNG image ("showImage") and saving a screenshot ("screenshot") from and to every possible PSP pixelformat and framebuffer address, which are auto detected:

http://svn.ps2dev.org/filedetails.php?r ... rev=0&sc=0
Bits
Posts: 11
Joined: Mon Sep 19, 2005 5:25 am
Location: UK

Post by Bits »

Thanks, but I'm not sure if I want to use code you've written :-)
Ohhhh... that's low.
You know all the answers to life... don't make me tell you again.
Post Reply