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 

sceGuCopyImage problem

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



Joined: 17 Oct 2008
Posts: 43

PostPosted: Wed Oct 21, 2009 3:24 am    Post subject: sceGuCopyImage problem Reply with quote

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
View user's profile Send private message
lego



Joined: 17 Oct 2008
Posts: 43

PostPosted: Thu Oct 22, 2009 3:33 am    Post subject: Reply with quote

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
View user's profile Send private message
J.F.



Joined: 22 Feb 2004
Posts: 2906

PostPosted: Thu Oct 22, 2009 12:39 pm    Post subject: Reply with quote

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
View user's profile Send private message AIM Address
lego



Joined: 17 Oct 2008
Posts: 43

PostPosted: Thu Oct 22, 2009 4:03 pm    Post subject: Reply with quote

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
View user's profile Send private message
J.F.



Joined: 22 Feb 2004
Posts: 2906

PostPosted: Sat Oct 24, 2009 2:38 am    Post subject: Reply with quote

How about some shots of what the "wrong" thing looks like. Your description doesn't really help.
Back to top
View user's profile Send private message AIM Address
lego



Joined: 17 Oct 2008
Posts: 43

PostPosted: Sat Oct 24, 2009 9:16 pm    Post subject: Reply with quote

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
View user's profile Send private message
J.F.



Joined: 22 Feb 2004
Posts: 2906

PostPosted: Mon Oct 26, 2009 10:32 am    Post subject: Reply with quote

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
View user's profile Send private message AIM Address
lego



Joined: 17 Oct 2008
Posts: 43

PostPosted: Fri Oct 30, 2009 12:46 am    Post subject: Reply with quote

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
View user's profile Send private message
J.F.



Joined: 22 Feb 2004
Posts: 2906

PostPosted: Fri Oct 30, 2009 5:48 am    Post subject: Reply with quote

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
View user's profile Send private message AIM Address
a_noob



Joined: 17 Sep 2006
Posts: 97
Location: _start: jr 0xDEADBEEF

PostPosted: Fri Oct 30, 2009 10:00 am    Post subject: Reply with quote

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
View user's profile Send private message AIM Address MSN Messenger
lego



Joined: 17 Oct 2008
Posts: 43

PostPosted: Fri Oct 30, 2009 8:23 pm    Post subject: Reply with quote

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
View user's profile Send private message
lego



Joined: 17 Oct 2008
Posts: 43

PostPosted: Fri Oct 30, 2009 8:31 pm    Post subject: Reply with quote

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
View user's profile Send private message
Criptych



Joined: 12 Sep 2009
Posts: 79

PostPosted: Sat Oct 31, 2009 6:42 am    Post subject: Reply with quote

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
View user's profile Send private message
Jim



Joined: 02 Jul 2005
Posts: 487
Location: Sydney

PostPosted: Sat Oct 31, 2009 6:52 am    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
Criptych



Joined: 12 Sep 2009
Posts: 79

PostPosted: Sat Oct 31, 2009 11:50 am    Post subject: Reply with quote

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
View user's profile Send private message
J.F.



Joined: 22 Feb 2004
Posts: 2906

PostPosted: Sun Nov 01, 2009 4:05 am    Post subject: Reply with quote

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
View user's profile Send private message AIM Address
Torch



Joined: 28 May 2008
Posts: 842

PostPosted: Sun Nov 01, 2009 2:25 pm    Post subject: Reply with quote

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
View user's profile Send private message
a_noob



Joined: 17 Sep 2006
Posts: 97
Location: _start: jr 0xDEADBEEF

PostPosted: Sun Nov 01, 2009 3:38 pm    Post subject: Reply with quote

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
View user's profile Send private message AIM Address MSN Messenger
J.F.



Joined: 22 Feb 2004
Posts: 2906

PostPosted: Mon Nov 02, 2009 2:47 am    Post subject: Reply with quote

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
View user's profile Send private message AIM Address
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