 |
forums.ps2dev.org Homebrew PS2, PSP & PS3 Development Discussions
|
| View previous topic :: View next topic |
| Author |
Message |
lego
Joined: 17 Oct 2008 Posts: 43
|
Posted: Wed Oct 21, 2009 3:24 am Post subject: sceGuCopyImage problem |
|
|
Hi.
I have a simple program, which must draws dots as on a chess-board in the top left corner of the screen. But instead, it draws two lines.
gu.c:
| Code: |
#include <malloc.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>
/*
#include <GL/gl.h>
#include <GL/glu.h>
*/
#include <math.h>
#include <pspkernel.h>
#include <pspdebug.h>
#include <pspthreadman.h>
#include <pspdisplay.h>
#include <pspnet_inet.h>
#include <pspnet.h>
#include <psputility.h>
#include <pspgu.h>
#include <pspgum.h>
#include <psputils.h>
PSP_MODULE_INFO("ogl", 0, 3, 5);
PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER | PSP_THREAD_ATTR_VFPU);
PSP_HEAP_SIZE_KB(-1024);
PSP_MAIN_THREAD_STACK_SIZE_KB(1024);
#define printf pspDebugScreenPrintf
#define BUF_WIDTH (512)
#define SCR_WIDTH (480)
#define SCR_HEIGHT (272)
void *dList;// display List, used by sceGUStart
void *fbp0;// frame buffer
typedef struct {
unsigned short u, v;
float x, y, z;
} vertexT_t;
uint32_t __attribute__((aligned(16))) tmpt[] = {
0xff0000ff, 0xff000000, 0xff00ff00, 0xff000000,
0xff000000, 0xff0000ff, 0xff000000, 0xff00ff00,
0xff00ff00, 0xff000000, 0xffff0000, 0xff000000,
0xff000000, 0xff00ff00, 0xff000000, 0xffff0000};
/*************************************************************
* EXIT CALLBACK STUFF
*************************************************************/
/* 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;
}
void initGU( void )
{
// Init GU
sceGuInit();
sceGuStart( GU_DIRECT, dList );
// Set Buffers
sceGuDrawBuffer( GU_PSM_8888, fbp0, BUF_WIDTH );
sceGuDispBuffer( SCR_WIDTH, SCR_HEIGHT, (void*)0x88000, BUF_WIDTH);
sceGuDepthBuffer( (void*)0x110000, BUF_WIDTH);
sceGuOffset( 2048 - (SCR_WIDTH/2), 2048 - (SCR_HEIGHT/2));
sceGuViewport( 2048, 2048, SCR_WIDTH, SCR_HEIGHT);
sceGuDepthRange( 65535, 0);
// Set Render States
sceGuScissor( 0, 0, SCR_WIDTH, SCR_HEIGHT);
sceGuEnable( GU_SCISSOR_TEST );
sceGuDepthFunc( GU_GEQUAL );
sceGuEnable( GU_DEPTH_TEST );
sceGuFrontFace( GU_CCW );
sceGuShadeModel( GU_SMOOTH );
sceGuEnable( GU_CULL_FACE );
sceGuEnable( GU_CLIP_PLANES );
sceGuFinish();
sceGuSync(0,0);
sceDisplayWaitVblankStart();
sceGuDisplay(GU_TRUE);
// finish
}
void setupProjection( void )
{
// setup matrices for the triangle
sceGumMatrixMode(GU_PROJECTION);
sceGumLoadIdentity();
sceGumOrtho(0, 480, 272 , 0, -1, 1);
// sceGumPerspective( 75.0f, 16.0f/9.0f, 0.5f, 1000.0f);
sceGumMatrixMode(GU_VIEW);
sceGumLoadIdentity();
sceGuClearColor( GU_COLOR( 0.0f, 0.0f, 1.0f, 0.0f ) );
sceGuClearDepth(0);
sceGumMatrixMode(GU_MODEL);
sceGumLoadIdentity();
}
int main(void)
{
SetupCallbacks();
pspDebugScreenInit();
if ( SDL_Init(SDL_INIT_VIDEO) ) {
printf("Error: %s\n", SDL_GetError());
return 1;
}
dList = memalign(16, 524288);
initGU();
setupProjection();
sceGuStart(GU_DIRECT, dList);
sceGuClear(GU_COLOR_BUFFER_BIT | GU_DEPTH_BUFFER_BIT);
sceGuCopyImage(GU_PSM_8888, 0, 0, 4, 4, 4,
(void*)tmpt,
1, 1, 512, (void*)0x4000000);
sceGuFinish();
sceGuSync(0, 0);
sceDisplayWaitVblankStart();
sceGuSwapBuffers();
sceKernelSleepThreadCB();
return 0;
}
|
Makefile:
| Code: |
.PHONY: myclean
MOUNTDIR := /media/usbflash
DESTDIR := $(MOUNTDIR)/psp/game5xx/CopyImage_test
TARGET = gu.c
OBJS = gu.o
PSP-PREF = $(shell psp-config --psp-prefix)
CFLAGS += -O2 -G0 -Wall -I$(PSP-PREF)/include \
-I/home/lego/work/psp/pspdev/psp/include/SDL
LDFLAGS :=
LIBS = -L$(PSP-PREF)/lib -L$(shell psp-config --pspsdk-path)/lib \
-lconfig \
-lpng -lz -lSDL_ttf -lSDL -lglut -lGLU -lGL \
-lfreetype -lpspvfpu -lpspgum -lm -lpspgu -lpspaudio -lpspwlan \
-lpsphprm -lpsprtc
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)
BUILD_PRX = 1
PSP_FW_VERSION = 500
PSP_LARGE_MEMORY = 1
EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = CopyImage test
PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak
myclean:
rm -f *~
install: all
mount $(MOUNTDIR)
mkdir -p $(DESTDIR) || true
cp EBOOT.PBP $(DESTDIR)/
umount $(MOUNTDIR)
|
|
|
| Back to top |
|
 |
lego
Joined: 17 Oct 2008 Posts: 43
|
Posted: Thu Oct 22, 2009 3:33 am Post subject: |
|
|
If I change the line:
| Code: |
sceGuCopyImage(GU_PSM_8888, 0, 0, 4, 4, 4,
(void*)tmpt,
1, 1, 512, (void*)0x4000000);
|
to the following one:
| Code: |
sceGuCopyImage(GU_PSM_8888, 0, 0, 4, 2, 8,
(void*)tmpt,
1, 1, 512, (void*)0x4000000);
|
it seems that everything drawn correctly. |
|
| Back to top |
|
 |
J.F.
Joined: 22 Feb 2004 Posts: 2906
|
Posted: Thu Oct 22, 2009 12:39 pm Post subject: |
|
|
From the docs:
| Code: | void sceGuCopyImage ( int psm,
int sx,
int sy,
int width,
int height,
int srcw,
void * src,
int dx,
int dy,
int destw,
void * dest
)
Image transfer using the GE.
Note:
Data must be aligned to 1 quad word (16 bytes)
Example: Copy a fullscreen 32-bit image from RAM to VRAM
sceGuCopyImage(GU_PSM_8888,0,0,480,272,512,pixels,0,0,512,(void*)(((unsigned int)framebuffer)+0x4000000));
Parameters:
psm - Pixel format for buffer
sx - Source X
sy - Source Y
width - Image width
height - Image height
srcw - Source buffer width (block aligned)
src - Source pointer
dx - Destination X
dy - Destination Y
destw - Destination buffer width (block aligned)
dest - Destination pointer
References sendCommandi().
|
http://psp.jim.sh/pspsdk-doc/ |
|
| Back to top |
|
 |
lego
Joined: 17 Oct 2008 Posts: 43
|
Posted: Thu Oct 22, 2009 4:03 pm Post subject: |
|
|
Hm... Possibly, I incorrectly explained.
I have a dots array with 16 elements within. If I use it like a 4x4 array of dots:
| Code: |
sceGuCopyImage(GU_PSM_8888, 0, 0, 4, 4, 4,
(void*)tmpt,
1, 1, 512, (void*)0x4000000);
|
I see on the screen something wrong. And if I use it like a 2x4 image in the 2x8 array:
| Code: |
sceGuCopyImage(GU_PSM_8888, 0, 0, 4, 2, 8,
(void*)tmpt,
1, 1, 512, (void*)0x4000000);
|
I see right 2x4 image.
But I don't understand what wrong with my 4x4 image :-( ... |
|
| Back to top |
|
 |
J.F.
Joined: 22 Feb 2004 Posts: 2906
|
Posted: Sat Oct 24, 2009 2:38 am Post subject: |
|
|
| How about some shots of what the "wrong" thing looks like. Your description doesn't really help. |
|
| Back to top |
|
 |
lego
Joined: 17 Oct 2008 Posts: 43
|
Posted: Sat Oct 24, 2009 9:16 pm Post subject: |
|
|
Sorry :-).
I couldn't make photos of a PSP, so I made shots by hands. My background is blue.
This is what I want (4x4):
This is what I get (wrong 4x4 image):
This is right 2x4 image:
So, I don't understand why my 4x4 image wrong and at the same time my 2x4 image in the 2x8 buffer right.
Thanks for replies. |
|
| Back to top |
|
 |
J.F.
Joined: 22 Feb 2004 Posts: 2906
|
Posted: Mon Oct 26, 2009 10:32 am Post subject: |
|
|
Your init doesn't seem very complete. Here's the one in the "standard" graphics.c:
| Code: | sceGuInit();
guStart();
sceGuDrawBuffer(GU_PSM_8888, (void*)FRAMEBUFFER_SIZE, PSP_LINE_SIZE);
sceGuDispBuffer(SCREEN_WIDTH, SCREEN_HEIGHT, (void*)0, PSP_LINE_SIZE);
sceGuClear(GU_COLOR_BUFFER_BIT | GU_DEPTH_BUFFER_BIT);
sceGuDepthBuffer((void*) (FRAMEBUFFER_SIZE*2), PSP_LINE_SIZE);
sceGuOffset(2048 - (SCREEN_WIDTH / 2), 2048 - (SCREEN_HEIGHT / 2));
sceGuViewport(2048, 2048, SCREEN_WIDTH, SCREEN_HEIGHT);
sceGuDepthRange(0xc350, 0x2710);
sceGuScissor(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
sceGuEnable(GU_SCISSOR_TEST);
sceGuAlphaFunc(GU_GREATER, 0, 0xff);
sceGuEnable(GU_ALPHA_TEST);
sceGuDepthFunc(GU_GEQUAL);
sceGuEnable(GU_DEPTH_TEST);
sceGuFrontFace(GU_CW);
sceGuShadeModel(GU_SMOOTH);
sceGuEnable(GU_CULL_FACE);
sceGuEnable(GU_TEXTURE_2D);
sceGuEnable(GU_CLIP_PLANES);
sceGuTexMode(GU_PSM_8888, 0, 0, 0);
sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
sceGuTexFilter(GU_NEAREST, GU_NEAREST);
sceGuAmbientColor(0xffffffff);
sceGuEnable(GU_BLEND);
sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
sceGuFinish();
sceGuSync(0, 0);
sceDisplayWaitVblankStart();
sceGuDisplay(GU_TRUE);
initialized = 1;
|
You also seem to have an undefined variable (fbp0). |
|
| Back to top |
|
 |
lego
Joined: 17 Oct 2008 Posts: 43
|
Posted: Fri Oct 30, 2009 12:46 am Post subject: |
|
|
fbp0 is initialized to 0 by default, like an any global variable which is not initialized explicitly.
My init function is lacking of a texture stuff, but I don't use textures in this code. So, I think my init function is similar to your. In any case I will try to use your init function.
J.F., does my code work on your psp in the same manner? |
|
| Back to top |
|
 |
J.F.
Joined: 22 Feb 2004 Posts: 2906
|
Posted: Fri Oct 30, 2009 5:48 am Post subject: |
|
|
Haven't tried it. In fact, I don't even have the psp toolchain setup on this computer (yet).
Have you tried some of the existing samples to see if you're even making properly working executables? |
|
| Back to top |
|
 |
a_noob
Joined: 17 Sep 2006 Posts: 97 Location: _start: jr 0xDEADBEEF
|
Posted: Fri Oct 30, 2009 10:00 am Post subject: |
|
|
| lego wrote: | fbp0 is initialized to 0 by default, like an any global variable which is not initialized explicitly.
My init function is lacking of a texture stuff, but I don't use textures in this code. So, I think my init function is similar to your. In any case I will try to use your init function.
J.F., does my code work on your psp in the same manner? |
Eww, worst assumption ever! NEVER EVER assume a pointer is NULL, or valid. That is one of the big problems that can occur in pointer programming.
as for the gu setup you can use
| Code: |
#define BUF_WIDTH (512)
#define SCR_WIDTH (480)
#define SCR_HEIGHT (272)
#define FRAME_SIZE (BUF_WIDTH * SCR_HEIGHT * 4)
void initGU(){
sceGuInit();
sceGuStart(GU_DIRECT,list);
sceGuDrawBuffer(GU_PSM_8888,(void*)0,BUF_WIDTH);
sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,(void*)FRAME_SIZE,BUF_WIDTH);
sceGuDepthBuffer((void*)(FRAME_SIZE*2),BUF_WIDTH);
sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2));
sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT);
sceGuDepthRange(65535,0);
sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT);
sceGuEnable(GU_SCISSOR_TEST);
sceGuFrontFace(GU_CW);
sceGuFinish();
sceGuSync(0,0);
sceGuDisplay(1);
}
|
this would be one of your more minimalistic context initializations of course. _________________
| Code: | .øOº'ºOø.
'ºOo.oOº' |
|
|
| Back to top |
|
 |
lego
Joined: 17 Oct 2008 Posts: 43
|
Posted: Fri Oct 30, 2009 8:23 pm Post subject: |
|
|
| J.F. wrote: | Haven't tried it. In fact, I don't even have the psp toolchain setup on this computer (yet).
Have you tried some of the existing samples to see if you're even making properly working executables? |
Yes. I run some gu examples. It worked fine. |
|
| Back to top |
|
 |
lego
Joined: 17 Oct 2008 Posts: 43
|
Posted: Fri Oct 30, 2009 8:31 pm Post subject: |
|
|
| a_noob wrote: | | lego wrote: | fbp0 is initialized to 0 by default, like an any global variable which is not initialized explicitly.
My init function is lacking of a texture stuff, but I don't use textures in this code. So, I think my init function is similar to your. In any case I will try to use your init function.
J.F., does my code work on your psp in the same manner? |
Eww, worst assumption ever! NEVER EVER assume a pointer is NULL, or valid. That is one of the big problems that can occur in pointer programming. |
Ok, but what about C standard :-)? Which say that every _global_ variable non initialized by user initialize to 0 by default.
I tried your init function. It gave me the same result :-(. |
|
| Back to top |
|
 |
Criptych
Joined: 12 Sep 2009 Posts: 79
|
Posted: Sat Oct 31, 2009 6:42 am Post subject: |
|
|
| lego wrote: | | a_noob wrote: | | Eww, worst assumption ever! NEVER EVER assume a pointer is NULL, or valid. That is one of the big problems that can occur in pointer programming. |
Ok, but what about C standard :-)? Which say that every _global_ variable non initialized by user initialize to 0 by default. |
a_noob beat me to it, but I'd have said the same thing, because not every C compiler is 100% compatible with the standard. And in any case it's just good practice to initialize all variables - especially pointers - to a known value so that you don't need to rely on a default. |
|
| Back to top |
|
 |
Jim

Joined: 02 Jul 2005 Posts: 487 Location: Sydney
|
Posted: Sat Oct 31, 2009 6:52 am Post subject: |
|
|
That would be a glaring fuck up of a C compiler if it didn't do that.
Jim _________________ http://www.dbfinteractive.com |
|
| Back to top |
|
 |
Criptych
Joined: 12 Sep 2009 Posts: 79
|
Posted: Sat Oct 31, 2009 11:50 am Post subject: |
|
|
| Maybe so, but it's still good practice to initialize explicitly. Even if the compiler does give global variables some default value, say you decide to make one a static local instead - suddenly it doesn't have that default, and you may end up with a pretty sneaky bug. |
|
| Back to top |
|
 |
J.F.
Joined: 22 Feb 2004 Posts: 2906
|
Posted: Sun Nov 01, 2009 4:05 am Post subject: |
|
|
| The compiler doesn't clear uninitialized variables... ever. It's not up to the compiler. Uninitialized variables merely go into the BSS. It's up to the start code linked to the head of the program to clear the BSS segment. Look in crt0 or crt1 files for that code. I've seen some that rely on the memory allocator to provide a zeroed block of memory for the BSS, and don't clear it themselves. My own start code specifically clears the BSS - it may not be needed, but it's good practice, and since this occurs at start up, it's not going to slow the program. |
|
| Back to top |
|
 |
Torch

Joined: 28 May 2008 Posts: 842
|
Posted: Sun Nov 01, 2009 2:25 pm Post subject: |
|
|
| J.F. wrote: | | The compiler doesn't clear uninitialized variables... ever. It's not up to the compiler. Uninitialized variables merely go into the BSS. It's up to the start code linked to the head of the program to clear the BSS segment. Look in crt0 or crt1 files for that code. I've seen some that rely on the memory allocator to provide a zeroed block of memory for the BSS, and don't clear it themselves. My own start code specifically clears the BSS - it may not be needed, but it's good practice, and since this occurs at start up, it's not going to slow the program. |
But if you declare a variable at compile time, say int x; it's put in the binary as FF FF FF FF? Are ALL variables hardcoded like this or does it intelligently malloc uninitialized arrays etc to save space? I don't think the PSP toolchain does this, but on other platforms? |
|
| Back to top |
|
 |
a_noob
Joined: 17 Sep 2006 Posts: 97 Location: _start: jr 0xDEADBEEF
|
Posted: Sun Nov 01, 2009 3:38 pm Post subject: |
|
|
Wether or not the compiler or system does it, adding = 0 isnt hard, and can avoid these problems ;D. Especially with pointers, assumptions can be bad. Wether it's 0 or not by default is not the case. Setting it your self is always a better programming practice because then you know that it is always going to be the value you need it to be. _________________
| Code: | .øOº'ºOø.
'ºOo.oOº' |
|
|
| Back to top |
|
 |
J.F.
Joined: 22 Feb 2004 Posts: 2906
|
Posted: Mon Nov 02, 2009 2:47 am Post subject: |
|
|
| Torch wrote: | | J.F. wrote: | | The compiler doesn't clear uninitialized variables... ever. It's not up to the compiler. Uninitialized variables merely go into the BSS. It's up to the start code linked to the head of the program to clear the BSS segment. Look in crt0 or crt1 files for that code. I've seen some that rely on the memory allocator to provide a zeroed block of memory for the BSS, and don't clear it themselves. My own start code specifically clears the BSS - it may not be needed, but it's good practice, and since this occurs at start up, it's not going to slow the program. |
But if you declare a variable at compile time, say int x; it's put in the binary as FF FF FF FF? Are ALL variables hardcoded like this or does it intelligently malloc uninitialized arrays etc to save space? I don't think the PSP toolchain does this, but on other platforms? |
Uninitialized variables are merely an offset in the BSS. There's nothing like "placeholder" data. Broadly put, most executable formats are like this:
code and constant data section: the actual code and data is stored along with offsets for functions and variables
initialized data section: the actual data is stored along with offsets for the variables
uninitialized data section: only offsets for the variables are here
It's up to either the OS loader or the start code in the executable to set the uninitialized data are to a preset value, and some OSes/start code don't bother. Old C implementations specifically mentioned that you could not count on uninitialized variables having a set value. They would be whatever happened to be in the memory location when the file was loaded. |
|
| 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
|