pspgl freezes
pspgl freezes
I'm testing based on the pspgl glut-test sample (added some more polygons). I have 2 problems.
- can't get the depth buffer to work (tried with glEnable(GL_DEPTH_TEST))
- after a few seconds the prog. freezes on the psp, it works o.k. when just the polygons of the original sample are rendered, any buffers must be cleared before rendering ???
- can't get the depth buffer to work (tried with glEnable(GL_DEPTH_TEST))
- after a few seconds the prog. freezes on the psp, it works o.k. when just the polygons of the original sample are rendered, any buffers must be cleared before rendering ???
Re: pspgl freezes
Do you have a 1.0 or a 1.5 firmware PSP? I have the same problem, but only on 1.0 firmware. Can you post your code? I have two PSPs, a 1.0 and a 1.5 and I can test it.cadaver wrote:- after a few seconds the prog. freezes on the psp, it works o.k. when just the polygons of the original sample are rendered, any buffers must be cleared before rendering ???
pspgl freezes + depthbuffer not working
here ist the complete (modified) simple.c
- if you move a few seconds with the triangle and x buttons the prog hangs, also the depth buffer doesn't work (don't know why)
- I tested only on a psp with 1.0
#include <stdlib.h>
#include <GL/glut.h>
static float zPos = -2.5f;
char keys[256];
/******* PSP specific debugging ********************************************/
extern void __psp_log (const char *fmt, ...);
/* enable GLerror logging to "ms0:/log.txt" */
#if 1
#define GLCHK(x) \
do { \
GLint errcode; \
x; \
errcode = glGetError(); \
if (errcode != GL_NO_ERROR) { \
__psp_log("%s (%d): GL error 0x%04x\n", \
__FUNCTION__, __LINE__, \
(unsigned int) errcode); \
} \
} while (0)
#else
#define GLCHK(x) x
#endif
/******* end of PSP specific debugging *************************************/
void reshape(int w, int h)
{
float ratio = ((float)w/(float)h);
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, ratio, 1.5, 500);
}
static float delta = 1.0;
static
void display (void)
{
int x=0,y=0;
static GLfloat angle;
angle += delta;
if (keys['d'])
zPos += 0.5f;
if (keys['x'])
zPos -= 0.5f;
GLCHK(glMatrixMode(GL_MODELVIEW));
GLCHK(glLoadIdentity());
GLCHK(glTranslatef(0.0f, 0.0f, zPos));
GLCHK(glRotatef(angle * 1.32f, 0.0f, 0.0f, 1.0f));
GLCHK(glShadeModel(GL_SMOOTH));
GLCHK(glEnable(GL_DEPTH_TEST));
GLCHK(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
GLCHK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
for (y=-2; y<3; y++) {
for (x=-2; x<3; x++) {
GLCHK(glBegin(GL_TRIANGLES));
GLCHK(glColor3f(0.0f, 0.0f, 1.0f)); GLCHK(glVertex3f( 1.0f+x, 0.0f+y, 0.0f));
GLCHK(glColor3f(0.0f, 0.0f, 1.0f)); GLCHK(glVertex3f( 0.0f+x, 1.0f+y, 0.0f));
GLCHK(glColor3f(0.0f, 0.0f, 1.0f)); GLCHK(glVertex3f( -1.0f+x, 0.0f+y, 0.0f));
GLCHK(glEnd());
GLCHK(glBegin(GL_TRIANGLES));
GLCHK(glColor3f(0.0f, 1.0f, 0.0f)); GLCHK(glVertex3f( 1.0f+x*1.0f, 0.0f+y*1.0f, -2.0f));
GLCHK(glColor3f(0.0f, 1.0f, 0.0f)); GLCHK(glVertex3f( 0.0f+x*1.0f, 2.0f+y*1.0f, -2.0f));
GLCHK(glColor3f(0.0f, 1.0f, 0.0f)); GLCHK(glVertex3f( -1.0f+x*1.0f, 0.0f+y*1.0f, -2.0f));
GLCHK(glEnd());
}
}
glutSwapBuffers();
glutPostRedisplay();
}
static
void keydown (unsigned char key, int x, int y)
{
keys[key] = 1;
switch (key) {
case 'd': /* delta, triangle */
break;
case 'o': /* round */
delta = 0.0f;
break;
case 'q': /* square*/
break;
case 'x': /* cross button */
// exit(0);
break;
default:
;
}
}
static
void keyup (unsigned char key, int x, int y)
{
keys[key] = 0;
switch (key) {
case 'o':
delta = 1.0f;
break;
default:
;
}
}
static
void joystick (unsigned int buttonMask, int x, int y, int z)
{
// GLCHK(glClearColor(x * 1.0f/2000.0f + 0.5f, y * 1.0f/2000.0f + 0.5f, 1.0f, 1.0f));
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutCreateWindow( __FILE__ );
glutKeyboardFunc(keydown);
glutKeyboardUpFunc(keyup);
glutJoystickFunc(joystick, 0);
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
- if you move a few seconds with the triangle and x buttons the prog hangs, also the depth buffer doesn't work (don't know why)
- I tested only on a psp with 1.0
#include <stdlib.h>
#include <GL/glut.h>
static float zPos = -2.5f;
char keys[256];
/******* PSP specific debugging ********************************************/
extern void __psp_log (const char *fmt, ...);
/* enable GLerror logging to "ms0:/log.txt" */
#if 1
#define GLCHK(x) \
do { \
GLint errcode; \
x; \
errcode = glGetError(); \
if (errcode != GL_NO_ERROR) { \
__psp_log("%s (%d): GL error 0x%04x\n", \
__FUNCTION__, __LINE__, \
(unsigned int) errcode); \
} \
} while (0)
#else
#define GLCHK(x) x
#endif
/******* end of PSP specific debugging *************************************/
void reshape(int w, int h)
{
float ratio = ((float)w/(float)h);
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, ratio, 1.5, 500);
}
static float delta = 1.0;
static
void display (void)
{
int x=0,y=0;
static GLfloat angle;
angle += delta;
if (keys['d'])
zPos += 0.5f;
if (keys['x'])
zPos -= 0.5f;
GLCHK(glMatrixMode(GL_MODELVIEW));
GLCHK(glLoadIdentity());
GLCHK(glTranslatef(0.0f, 0.0f, zPos));
GLCHK(glRotatef(angle * 1.32f, 0.0f, 0.0f, 1.0f));
GLCHK(glShadeModel(GL_SMOOTH));
GLCHK(glEnable(GL_DEPTH_TEST));
GLCHK(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
GLCHK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
for (y=-2; y<3; y++) {
for (x=-2; x<3; x++) {
GLCHK(glBegin(GL_TRIANGLES));
GLCHK(glColor3f(0.0f, 0.0f, 1.0f)); GLCHK(glVertex3f( 1.0f+x, 0.0f+y, 0.0f));
GLCHK(glColor3f(0.0f, 0.0f, 1.0f)); GLCHK(glVertex3f( 0.0f+x, 1.0f+y, 0.0f));
GLCHK(glColor3f(0.0f, 0.0f, 1.0f)); GLCHK(glVertex3f( -1.0f+x, 0.0f+y, 0.0f));
GLCHK(glEnd());
GLCHK(glBegin(GL_TRIANGLES));
GLCHK(glColor3f(0.0f, 1.0f, 0.0f)); GLCHK(glVertex3f( 1.0f+x*1.0f, 0.0f+y*1.0f, -2.0f));
GLCHK(glColor3f(0.0f, 1.0f, 0.0f)); GLCHK(glVertex3f( 0.0f+x*1.0f, 2.0f+y*1.0f, -2.0f));
GLCHK(glColor3f(0.0f, 1.0f, 0.0f)); GLCHK(glVertex3f( -1.0f+x*1.0f, 0.0f+y*1.0f, -2.0f));
GLCHK(glEnd());
}
}
glutSwapBuffers();
glutPostRedisplay();
}
static
void keydown (unsigned char key, int x, int y)
{
keys[key] = 1;
switch (key) {
case 'd': /* delta, triangle */
break;
case 'o': /* round */
delta = 0.0f;
break;
case 'q': /* square*/
break;
case 'x': /* cross button */
// exit(0);
break;
default:
;
}
}
static
void keyup (unsigned char key, int x, int y)
{
keys[key] = 0;
switch (key) {
case 'o':
delta = 1.0f;
break;
default:
;
}
}
static
void joystick (unsigned int buttonMask, int x, int y, int z)
{
// GLCHK(glClearColor(x * 1.0f/2000.0f + 0.5f, y * 1.0f/2000.0f + 0.5f, 1.0f, 1.0f));
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutCreateWindow( __FILE__ );
glutKeyboardFunc(keydown);
glutKeyboardUpFunc(keyup);
glutJoystickFunc(joystick, 0);
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
Re: pspgl freezes + depthbuffer not working
Your code is difficult to read, please use the "code" markup, but I can reproduce the bug with your code on 1.00. I've tried to shrink it to the error, only and used a simplified test-egl/eglcube.c, merged with some of your triangle draw code, which is compiled with the test-egl Makefile target. This is the code:
On my 1.00 PSP firmware it freezes after 2 seconds, on my 1.50 PSP firmware it spins forever.
There is another bug: on both firmware versions I can see a black stripe on top, with the width of the screen and about 10 pixels high, but sometime more and sometimes less. Looks like the glClear command overlaps the triangle draw command. Perhaps this is the reason for the freeze, because two command writes at the same time to the video ram. Without the "zPos += 0.01f;" line it doesn't freeze on the 1.00 firmware.
Code: Select all
#include <pspctrl.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <GLES/egl.h>
#include <GLES/gl.h>
static const EGLint attrib_list [] = {
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_DEPTH_SIZE, 16,
EGL_NONE
};
int main(int argc, char* argv[])
{
EGLDisplay dpy;
EGLConfig config;
EGLint num_configs;
EGLContext ctx;
EGLSurface surface;
GLfloat angle = 0.0f;
GLfloat zPos = 0.0f;
int x, y;
/* pass NativeDisplay=0, we only have one screen... */
dpy = eglGetDisplay(0);
eglInitialize(dpy, NULL, NULL);
eglChooseConfig(dpy, attrib_list, &config, 1, &num_configs);
ctx = eglCreateContext(dpy, config, NULL, NULL);
surface = eglCreateWindowSurface(dpy, config, 0, NULL);
eglMakeCurrent(dpy, surface, surface, ctx);
glViewport(0.0f, 0.0f, 480.0f, 272.0f);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspectivef(75.0f, 16.0f/9.0f, 0.5f, 1000.0f);
glMatrixMode(GL_MODELVIEW);
while (1) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAtf(0.0f, 0.0f, 2.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
glRotatef(angle, 0.0f, 0.0f, 1.0f);
glTranslatef(0.0f, 0.0f, zPos);
angle += 1.0f;
zPos += 0.01f;
if (zPos > 0.9f) zPos = 0.9f;
for (y=-2; y<3; y++) {
for (x=-2; x<3; x++) {
glBegin(GL_TRIANGLES);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f( 1.0f+x, 0.0f+y, 0.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f( 0.0f+x, 1.0f+y, 0.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f( -1.0f+x, 0.0f+y, 0.0f);
glEnd();
}
}
glFlush();
eglSwapBuffers(dpy, surface);
}
eglTerminate(dpy);
return 0;
}
There is another bug: on both firmware versions I can see a black stripe on top, with the width of the screen and about 10 pixels high, but sometime more and sometimes less. Looks like the glClear command overlaps the triangle draw command. Perhaps this is the reason for the freeze, because two command writes at the same time to the video ram. Without the "zPos += 0.01f;" line it doesn't freeze on the 1.00 firmware.
I only have a 1.50, so I can't test the 1.00 problem... if anybody of you can help to track down this problem this would be very welcome!
About the black stripe: we still have a sync problem in pspgl_vidmem.c, pspgl_vidmem_setup_write_and_display_buffer(). Basically we would like to call sceDisplaySetFrameBuf() with the PSP_DISPLAY_SETBUF_IMMEDIATE argument, but then we only get a black screen, no idea why. Need to investigate this in detail.
About the black stripe: we still have a sync problem in pspgl_vidmem.c, pspgl_vidmem_setup_write_and_display_buffer(). Basically we would like to call sceDisplaySetFrameBuf() with the PSP_DISPLAY_SETBUF_IMMEDIATE argument, but then we only get a black screen, no idea why. Need to investigate this in detail.
A friend of mine with a 1.00 did some testing: he experienced, that the GE always locks up when a triangle comes near the boundary to the clip area, so all depth values where transformed triangles are about to almost get clipped are affected.
It's probably a bug in the firmware, but there is likely a workaround (otherwise no commercial 3D game would work, clipping is something very common - ). Could you please port your code to the libgu and see how it behaves there?
It's probably a bug in the firmware, but there is likely a workaround (otherwise no commercial 3D game would work, clipping is something very common - ). Could you please port your code to the libgu and see how it behaves there?
It is not clipping related. I've tried my code above with fixed zPos = -1.0f and it works, but when I add a glFinish() after the glEnd() in the inner loop of the triangle drawing section, it freezes.holger wrote:A friend of mine with a 1.00 did some testing: he experienced, that the GE always locks up when a triangle comes near the boundary to the clip area, so all depth values where transformed triangles are about to almost get clipped are affected.
It is not exactly the same (I think there are differences with the viewing frustrum), but the result looks like the pspgl sample. And it doesn't freeze.holger wrote: It's probably a bug in the firmware, but there is likely a workaround (otherwise no commercial 3D game would work, clipping is something very common - ). Could you please port your code to the libgu and see how it behaves there?
main.c:
Code: Select all
#include <pspkernel.h>
#include <pspdisplay.h>
#include <pspgu.h>
#include <string.h>
#include <math.h>
/* Define the module info section */
PSP_MODULE_INFO("GUTEST", 0x1000, 1, 1);
/* Define the main thread's attribute value (optional) */
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU);
/* Exit callback */
int exit_callback(void)
{
// Unload modules
sceKernelExitGame();
return 0;
}
/* Callback thread */
int CallbackThread(SceSize args, void *argp)
{
int cbid;
cbid = sceKernelCreateCallback("Exit Callback", (void *) 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;
}
static unsigned int __attribute__((aligned(16))) list[262144];
struct Vertex
{
unsigned int color;
float x, y, z;
};
void matrix_identity(float* matrix)
{
matrix[(0<<2)+0] = 1.0f;
matrix[(0<<2)+1] = 0.0f;
matrix[(0<<2)+2] = 0.0f;
matrix[(0<<2)+3] = 0.0f;
matrix[(1<<2)+0] = 0.0f;
matrix[(1<<2)+1] = 1.0f;
matrix[(1<<2)+2] = 0.0f;
matrix[(1<<2)+3] = 0.0f;
matrix[(2<<2)+0] = 0.0f;
matrix[(2<<2)+1] = 0.0f;
matrix[(2<<2)+2] = 1.0f;
matrix[(2<<2)+3] = 0.0f;
matrix[(3<<2)+0] = 0.0f;
matrix[(3<<2)+1] = 0.0f;
matrix[(3<<2)+2] = 0.0f;
matrix[(3<<2)+3] = 1.0f;
}
void matrix_projection(float* matrix, float fovy, float aspect, float near, float far)
{
matrix_identity(matrix);
float angle = (fovy / 2.0f) * (M_PI/180.0f);
float cotangent = cosf(angle) / sinf(angle);
matrix[(0<<2)+0] = cotangent / aspect;
matrix[(1<<2)+1] = cotangent;
matrix[(2<<2)+2] = (far + near) / (near - far);
matrix[(3<<2)+2] = 2.0f * (far * near) / (near - far);
matrix[(2<<2)+3] = -1.0f;
matrix[(3<<2)+3] = 0.0f;
}
void matrix_multiply(float* result, float* a, float* b)
{
unsigned int i, j, k;
float temp[16];
for (i = 0; i < 4; ++i)
{
for (j = 0; j < 4; ++j)
{
float t = 0.0f;
for (k = 0; k < 4; ++k)
t += a[(k << 2)+j] * b[(i << 2)+k];
temp[(i << 2)+j] = t;
}
}
memcpy(result, temp, sizeof(float)*16);
}
void matrix_translate(float* matrix, float x, float y, float z)
{
float temp[16];
matrix_identity(temp);
temp[(3 << 2)+0] = x;
temp[(3 << 2)+1] = y;
temp[(3 << 2)+2] = z;
matrix_multiply(matrix, matrix, temp);
}
void matrix_setrotatex(float* matrix, float angle)
{
float cs = cosf(angle);
float sn = sinf(angle);
matrix_identity(matrix);
matrix[(1<<2)+1] = cs;
matrix[(1<<2)+2] = sn;
matrix[(2<<2)+1] = -sn;
matrix[(2<<2)+2] = cs;
}
void matrix_setrotatey(float* matrix, float angle)
{
float cs = cosf(angle);
float sn = sinf(angle);
matrix_identity(matrix);
matrix[(0<<2)+0] = cs;
matrix[(0<<2)+2] = -sn;
matrix[(2<<2)+0] = sn;
matrix[(2<<2)+2] = cs;
}
void matrix_setrotatez(float* matrix, float angle)
{
float cs = cosf(angle);
float sn = sinf(angle);
matrix_identity(matrix);
matrix[(0<<2)+0] = cs;
matrix[(0<<2)+1] = sn;
matrix[(1<<2)+0] = -sn;
matrix[(1<<2)+1] = cs;
}
void matrix_rotate(float* matrix, float x, float y, float z)
{
float temp[16];
matrix_setrotatex(temp, x);
matrix_multiply(matrix, matrix, temp);
matrix_setrotatey(temp, y);
matrix_multiply(matrix, matrix, temp);
matrix_setrotatez(temp, z);
matrix_multiply(matrix, matrix, temp);
}
#define BUF_WIDTH (512)
#define SCR_WIDTH (480)
#define SCR_HEIGHT (272)
#define PIXEL_SIZE (4) /* change this if you change to another screenmode */
#define FRAME_SIZE (BUF_WIDTH * SCR_HEIGHT * PIXEL_SIZE)
#define ZBUF_SIZE (BUF_WIDTH SCR_HEIGHT * 2) /* zbuffer seems to be 16-bit? */
int main(int argc, char* argv[])
{
ScePspFMatrix4 projection;
ScePspFMatrix4 view;
ScePspFMatrix4 world;
int val = 0;
SetupCallbacks();
sceGuInit();
// setup
sceGuStart(0, list);
sceGuDrawBuffer(GU_PSM_8888, (void*)0, 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(0xc350, 0x2710);
sceGuScissor(0, 0, SCR_WIDTH, SCR_HEIGHT);
sceGuEnable(GU_SCISSOR_TEST);
sceGuDepthFunc(GU_GEQUAL);
sceGuEnable(GU_DEPTH_TEST);
sceGuDisable(GU_CULL_FACE);
sceGuFinish();
sceGuSync(0, 0);
sceDisplayWaitVblankStart();
sceGuDisplay(1);
float zPos = -5.0;
while (1) {
sceGuStart(0, list);
sceGuClearColor(0);
sceGuClearDepth(0);
sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT);
val++;
matrix_identity((float*)&projection);
matrix_projection((float*)&projection, 75.0f, 16.0/9.0f, 1.0f, 1000.0f);
sceGuSetMatrix(GU_PROJECTION, &projection);
matrix_identity((float*)&view);
sceGuSetMatrix(GU_VIEW, &view);
matrix_identity((float*)&world);
matrix_translate((float*)&world, 0.0f, 0.0f, zPos);
zPos += 0.01f;
if (zPos > -2.0f) zPos = -2.0f;
matrix_rotate((float*)&world, 0, 0, val * 0.79f * (M_PI/180.0f));
sceGuSetMatrix(GU_MODEL, &world);
int x, y;
for (y=-2; y<3; y++) {
for (x=-2; x<3; x++) {
struct Vertex* vertices = (struct Vertex*) sceGuGetMemory(3 * sizeof(struct Vertex));
vertices[0].color = 0xffffffff;
vertices[0].x = 1.0f+x;
vertices[0].y = 0.0f+y;
vertices[0].z = 0.0f;
vertices[1].color = 0xffffffff;
vertices[1].x = 0.0f+x;
vertices[1].y = 1.0f+y;
vertices[1].z = 0.0f;
vertices[2].color = 0xffffffff;
vertices[2].x = -1.0f+x;
vertices[2].y = 0.0f+y;
vertices[2].z = 0.0f;
sceGuDrawArray(GU_TRIANGLES, GU_COLOR_8888|GU_VERTEX_32BITF|GU_TRANSFORM_3D, 3, 0, vertices);
}
}
sceGuFinish();
sceGuSync(0, 0);
sceDisplayWaitVblankStart();
sceGuSwapBuffers();
}
sceGuTerm();
return 0;
}
Code: Select all
TARGET = gutest
OBJS = main.o
INCDIR =
CFLAGS = -G0 -Wall -O2 -fno-strict-aliasing
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)
LIBDIR =
LDFLAGS =
LIBS= -lpspgu -lm
EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = GU Test
PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak
Re: pspgl freezes
Can you please update your source tree and try again? Z coordinate direction was reversed, please let me know if that was the root of your problem.cadaver wrote: - can't get the depth buffer to work (tried with glEnable(GL_DEPTH_TEST))
Re: pspgl freezes
Try the latest pspgl version from SVN, with the latest pspsdk and toolchain (see http://forums.ps2dev.org/viewtopic.php?p=26380#26380 ).cadaver wrote:- after a few seconds the prog. freezes on the psp, it works o.k. when just the polygons of the original sample are rendered, any buffers must be cleared before rendering ???
If the problem relates to clipping, then this could make all the difference.Shine wrote:It is not exactly the same (I think there are differences with the viewing frustrum), but the result looks like the pspgl sample. And it doesn't freeze.holger wrote: It's probably a bug in the firmware, but there is likely a workaround (otherwise no commercial 3D game would work, clipping is something very common - ). Could you please port your code to the libgu and see how it behaves there?
I adjusted the EGL test a little bit; it should be exactly the same, but it batches things in larger batches. It would be interesting to know if it makes a difference.
Just out of curiosity, is there any reason to not want to update 1.0->1.5?
Code: Select all
#include <pspctrl.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <GLES/egl.h>
#include <GLES/gl.h>
static const EGLint attrib_list [] = {
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_DEPTH_SIZE, 16,
EGL_NONE
};
int main(int argc, char* argv[])
{
EGLDisplay dpy;
EGLConfig config;
EGLint num_configs;
EGLContext ctx;
EGLSurface surface;
GLfloat angle = 0.0f;
GLfloat zPos = 0.0f;
int x, y;
/* pass NativeDisplay=0, we only have one screen... */
dpy = eglGetDisplay(0);
eglInitialize(dpy, NULL, NULL);
eglChooseConfig(dpy, attrib_list, &config, 1, &num_configs);
ctx = eglCreateContext(dpy, config, NULL, NULL);
surface = eglCreateWindowSurface(dpy, config, 0, NULL);
eglMakeCurrent(dpy, surface, surface, ctx);
glViewport(0.0f, 0.0f, 480.0f, 272.0f);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspectivef(75.0f, 16.0f/9.0f, 0.5f, 1000.0f);
glMatrixMode(GL_MODELVIEW);
glColor3f(0.0f, 0.0f, 1.0f);
while (1) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAtf(0.0f, 0.0f, 2.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
glRotatef(angle, 0.0f, 0.0f, 1.0f);
glTranslatef(0.0f, 0.0f, zPos);
angle += 1.0f;
zPos += 0.01f;
if (zPos > 0.9f) zPos = 0.f;
glBegin(GL_TRIANGLES);
for (y=-2; y<3; y++) {
for (x=-2; x<3; x++) {
glVertex3f( 1.0f+x, 0.0f+y, 0.0f);
glVertex3f( 0.0f+x, 1.0f+y, 0.0f);
glVertex3f( -1.0f+x, 0.0f+y, 0.0f);
}
}
glEnd();
//glFlush();
eglSwapBuffers(dpy, surface);
}
eglTerminate(dpy);
return 0;
}
It's the same. With the SVN version it works and with your tree of pspgl it freezes immediatly after startup (black screen, but exit game is possible).jsgf wrote:If the problem relates to clipping, then this could make all the difference.
I adjusted the EGL test a little bit; it should be exactly the same, but it batches things in larger batches. It would be interesting to know if it makes a difference.
mrbrown answered this already :-) but seriously, homebrews programs starts faster on 1.0 firmware PSPs and I might be wrong, but I feel if it works on 1.0 and 1.5, then the program is more stable and it will work on every firmware version (once there will be exploits for it).jsgf wrote: Just out of curiosity, is there any reason to not want to update 1.0->1.5?
OK, so that's a different behaviour? Previously it would run for a bit before hanging?Shine wrote:It's the same. With the SVN version it works and with your tree of pspgl it freezes immediatly after startup (black screen, but exit game is possible).
The big, possibly relevent difference between my PSPGL and SVN is that I've flipped the Z direction around to get depth-testing working properly. Aside from that, there really isn't very much in PSPGL which could make a difference. I suspect that other programs will hang one or the other version of PSPGL.
The fact that the PSP doesn't lock solid suggests that GE is hanging, but the main CPU is still fine; I would guess it is blocked in a sceGeListSync() call.
Well, yes, but since the GE hangs with an apparently OK program, it looks like buggy GE firmware.mrbrown answered this already :-) but seriously, homebrews programs starts faster on 1.0 firmware PSPs and I might be wrong, but I feel if it works on 1.0 and 1.5, then the program is more stable and it will work on every firmware version (once there will be exploits for it).
Could you grab a register dump of a hanging run? Set #if 1 around the pspgl_ge_register_dump defines in pspgl_misc.h; it will put a pspgl.ge file on the root of your stick (make sure you don't have an old one hanging around).
a friend of mine did some testing on his 1.00 and the problem seems indeed depth-related.jsgf wrote:OK, so that's a different behaviour? Previously it would run for a bit before hanging?Shine wrote:It's the same. With the SVN version it works and with your tree of pspgl it freezes immediatly after startup (black screen, but exit game is possible).
The big, possibly relevent difference between my PSPGL and SVN is that I've flipped the Z direction around to get depth-testing working properly. Aside from that, there really isn't very much in PSPGL which could make a difference. I suspect that other programs will hang one or the other version of PSPGL.
Shine: Could you replace the glDepthRange() call by libGu's DepthRange() in your test program? This inverts the depth orientation but should avoid the lock-up if the theory above is true.
yes, sounds like a bug, but since quite a lot of commercial games work there must at least be some workaround possible...Well, yes, but since the GE hangs with an apparently OK program, it looks like buggy GE firmware.
Yes. I've done the register dump: http://www.frank-buss.de/tmp/pspgl.ge.zipjsgf wrote:OK, so that's a different behaviour? Previously it would run for a bit before hanging?Shine wrote:It's the same. With the SVN version it works and with your tree of pspgl it freezes immediatly after startup (black screen, but exit game is possible).
I've changed it like this:holger wrote: Shine: Could you replace the glDepthRange() call by libGu's DepthRange() in your test program? This inverts the depth orientation but should avoid the lock-up if the theory above is true.
Code: Select all
void glDepthRangef (GLclampf near, GLclampf far)
{
unsigned int max = (unsigned int)near + (unsigned int)far;
int val = (int)((max >> 31) + max);
float z = (float)(val >> 1);
sendCommandf(68,z - ((float)near));
sendCommandf(71,z + ((float)pspgl_curctx->depth_offset));
if (near > far)
{
int temp = near;
near = far;
far = temp;
}
sendCommandi(214,near);
sendCommandi(215,far);
}
I know not much about the PSP internals, but I assume it must be a trivial, but subtle problem, perhaps the order in which some commands are sent is wrong or some caching problem, like GE doesn't allow some kind memory access after or before submitting commands.
is the assumption correct that the bug goes away if you exchange the values for near and far (e.g. 0.0 and 65535)?Shine wrote: Same bug.
I know not much about the PSP internals, but I assume it must be a trivial, but subtle problem, perhaps the order in which some commands are sent is wrong or some caching problem, like GE doesn't allow some kind memory access after or before submitting commands.
no, same problem. I've tried far = 65535; near = 0.0; at the beginning of glDepthRangef and exchanged, but both freezed with jsgf's version. Perhaps a diff to the SVN version should show some hints. But perhaps it is not that much important, as long as it works with the SVN version.holger wrote:is the assumption correct that the bug goes away if you exchange the values for near and far (e.g. 0.0 and 65535)?
I would assume that some other test program would also hang with the SVN version, since the two versions aren't really doing anything very different for a simple test program like this.Shine wrote:no, same problem. I've tried far = 65535; near = 0.0; at the beginning of glDepthRangef and exchanged, but both freezed with jsgf's version. Perhaps a diff to the SVN version should show some hints. But perhaps it is not that much important, as long as it works with the SVN version.
Thanks, but I need a bit more info. Could you run two more tests, using this inner loop:Shine wrote:Yes. I've done the register dump: http://www.frank-buss.de/tmp/pspgl.ge.zip
Code: Select all
glFinish();
for (y=-2; y<3; y++) {
for (x=-2; x<3; x++) {
glBegin(GL_TRIANGLES);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f( 1.0f+x, 0.0f+y, 0.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f( 0.0f+x, 1.0f+y, 0.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f( -1.0f+x, 0.0f+y, 0.0f);
glEnd();
glFinish();
}
}
Thanks,
J
I'm being bit by similar hangs and crashes using PSPGL (the latest in SVN) on a 1.0 PSP. I just checked in support for PSPGL in SDL. If I try the spinning triangle test using PSPGL's glut.c (unmodified), the PSP crashes after the program launches. If I convert the glut.c test to go through SDL's OpenGL interface (source below), I get a hang instead.
Here is the source and Makefile for the SDL PSPGL test that I'm using:
I turned on both log.txt logging and the pspgl.ge dump, and grabbed the output from my 1.0 PSP and a friend's 1.5. The diff of PSPGL's log.txt is as follows (+ lines are from the 1.5 PSP):
It looks like PSPGL hangs in glFinish(). A diff of the decode_ge_dump output from both PSPs also seems to indicate this. jsgf, I've PM'd you with info on where these dumps are (I don't have any publically accessible web site).
Here is the source and Makefile for the SDL PSPGL test that I'm using:
Code: Select all
/* Test SDL OpenGL support. */
#include <stdio.h>
#include <stdlib.h>
#include "SDL.h"
#include "SDL_opengl.h"
#define SCREEN_WIDTH 480
#define SCREEN_HEIGHT 272
static GLfloat delta = 1.0f;
static GLfloat angle;
int main(int argc, char *argv[])
{
int done = 0;
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0)
{
fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError());
return 1;
}
if (SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 0, SDL_OPENGL | SDL_FULLSCREEN) == NULL)
{
fprintf(stderr, "Unable to create OpenGL screen: %s\n", SDL_GetError());
SDL_Quit();
return 1;
}
glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-2, 2, -2, 2, -2, 2);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// while (!done)
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
angle += delta;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(angle * 1.32f, 0.0f, 0.0f, 1.0f);
glShadeModel(GL_SMOOTH);
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(1.0f, 0.0f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(0.0f, 0.0f, 1.0f);
glEnd();
glFinish();
SDL_GL_SwapBuffers();
}
return 0;
}
Code: Select all
TARGET = ogl-test
PSPSDK = $(shell psp-config --pspsdk-path)
PSPPREFIX = $(shell psp-config --psp-prefix)
PSPBIN = $(PSPPREFIX)/bin
SDL_CONFIG = $(PSPBIN)/sdl-config
OBJS = $(TARGET).o
DEFAULT_CFLAGS = $(shell $(SDL_CONFIG) --cflags)
MORE_CFLAGS = -O2 -fsingle-precision-constant #-ffast-math
CFLAGS = $(DEFAULT_CFLAGS) $(MORE_CFLAGS)
CXXFLAGS = $(DEFAULT_CFLAGS) $(MORE_CFLAGS) -fno-exceptions
LDFLAGS = -L$(PSPPREFIX)/lib
LIBS = -lGLU $(shell $(SDL_CONFIG) --libs) -lstdc++ -lm
EXTRA_TARGETS = EBOOT.PBP
include $(PSPSDK)/lib/build.mak
Code: Select all
@@ -27,3 +27,8 @@
__pspgl_vidmem_setup_write_and_display_buffer (140): color buffer adr 0x04044000
__pspgl_vidmem_setup_write_and_display_buffer (146): depth buffer adr 0x04088000
__pspgl_vidmem_setup_write_and_display_buffer (167): display @ adr 0x0x04000000
+__pspgl_vidmem_setup_write_and_display_buffer (128): current_front 1
+__pspgl_vidmem_setup_write_and_display_buffer (135): pixfmt 0
+__pspgl_vidmem_setup_write_and_display_buffer (140): color buffer adr 0x04000000
+__pspgl_vidmem_setup_write_and_display_buffer (146): depth buffer adr 0x04088000
+__pspgl_vidmem_setup_write_and_display_buffer (167): display @ adr 0x0x04044000
I've figured out a workaround to the hang: calling sceGuInit() at the top of my test program gets rid of the issues. The only thing sceGuInit() does is send a GE list and setup the GE callbacks (which do nothing if you don't use them). So it seems either that full init sequence must be sent to the GE, or the GE needs to be primed with the sceGeListEnqueue() and sceGeListSync() calls before doing anything else.
I've gone ahead and applied the workaround in the SDL backend.
Yeah, OK, I just added sceGuInit() to my local psp-setup.c, and all of the PSPGL tests appear to be working now.
Thanks goes to rinco for suggesting that this was the problem (and suggesting the workaround).
I've gone ahead and applied the workaround in the SDL backend.
Yeah, OK, I just added sceGuInit() to my local psp-setup.c, and all of the PSPGL tests appear to be working now.
Thanks goes to rinco for suggesting that this was the problem (and suggesting the workaround).
OK, I'm confused. Current head PSPGL and Holger's last version are initializing the same set of registers, though not to precisely the same values.
The table sceGuInit uses zeros out a lot more of the register state, which could be a contributing factor. But I can't see why older PSPGLs would have worked but current ones not on 1.0 PSPs.
Hm, sceGuInit makes sure to initialize texture 0 to the base of VRAM, even though it doesn't set up any other textures. I wonder if 1.0 firmware makes spurious texture fetches even if texturing is disabled?
I'll check in a test change into SVN shortly...
The table sceGuInit uses zeros out a lot more of the register state, which could be a contributing factor. But I can't see why older PSPGLs would have worked but current ones not on 1.0 PSPs.
Hm, sceGuInit makes sure to initialize texture 0 to the base of VRAM, even though it doesn't set up any other textures. I wonder if 1.0 firmware makes spurious texture fetches even if texturing is disabled?
I'll check in a test change into SVN shortly...