 |
forums.ps2dev.org Homebrew PS2, PSP & PS3 Development Discussions
|
| View previous topic :: View next topic |
| Author |
Message |
MDave
Joined: 09 May 2005 Posts: 84
|
Posted: Thu Aug 21, 2008 11:45 am Post subject: Hardware bugs in phat psp? |
|
|
I tried a search to see if there was anything on hardware bugs sony left behind for phat psp's, but no such luck.
Reason I ask, is because I'm rendering a skybox which works perfectly fine on my slim psp, but on the phat psp it looks like the uv coordinates are screwing up in strange ways when I start clipping the skybox polys against my world geometry (when it isn't getting clipped, it looks fine). Same eboot, same rendering code, doing nothing specific for the slim or phat psp's.
Slim:
Phat:
Rendering Code (sorry its a lot, would be great if I could get it cut down):
| Code: |
vec3_t skyclip[6] = {
{1,1,0},
{1,-1,0},
{0,-1,1},
{0,1,1},
{1,0,1},
{-1,0,1}
};
int c_sky;
// 1 = s, 2 = t, 3 = 2048
int st_to_vec[6][3] =
{
{3,-1,2},
{-3,1,2},
{1,3,2},
{-1,-3,2},
{-2,-1,3}, // 0 degrees yaw, look straight up
{2,-1,-3} // look straight down
// {-1,2,3},
// {1,2,-3}
};
// s = [0]/[2], t = [1]/[2]
int vec_to_st[6][3] =
{
{-2,3,1},
{2,3,-1},
{1,3,2},
{-1,3,-2},
{-2,-1,3},
{-2,1,-3}
// {-1,2,3},
// {1,2,-3}
};
float skymins[2][6], skymaxs[2][6];
void DrawSkyPolygon (int nump, vec3_t vecs)
{
int i,j;
vec3_t v, av;
float s, t, dv;
int axis;
float *vp;
c_sky++;
// decide which face it maps to
VectorCopy (vec3_origin, v);
for (i=0, vp=vecs ; i<nump ; i++, vp+=3)
{
VectorAdd (vp, v, v);
}
av[0] = fabs(v[0]);
av[1] = fabs(v[1]);
av[2] = fabs(v[2]);
if (av[0] > av[1] && av[0] > av[2])
{
if (v[0] < 0)
axis = 1;
else
axis = 0;
}
else if (av[1] > av[2] && av[1] > av[0])
{
if (v[1] < 0)
axis = 3;
else
axis = 2;
}
else
{
if (v[2] < 0)
axis = 5;
else
axis = 4;
}
// project new texture coords
for (i=0 ; i<nump ; i++, vecs+=3)
{
j = vec_to_st[axis][2];
if (j > 0)
dv = vecs[j - 1];
else
dv = -vecs[-j - 1];
j = vec_to_st[axis][0];
if (j < 0)
s = -vecs[-j -1] / dv;
else
s = vecs[j-1] / dv;
j = vec_to_st[axis][1];
if (j < 0)
t = -vecs[-j -1] / dv;
else
t = vecs[j-1] / dv;
if (s < skymins[0][axis])
skymins[0][axis] = s;
if (t < skymins[1][axis])
skymins[1][axis] = t;
if (s > skymaxs[0][axis])
skymaxs[0][axis] = s;
if (t > skymaxs[1][axis])
skymaxs[1][axis] = t;
}
}
#define MAX_CLIP_VERTS 64
void ClipSkyPolygon (int nump, vec3_t vecs, int stage)
{
float *norm;
float *v;
qboolean front, back;
float d, e;
float dists[MAX_CLIP_VERTS];
int sides[MAX_CLIP_VERTS];
vec3_t newv[2][MAX_CLIP_VERTS];
int newc[2];
int i, j;
if (nump > MAX_CLIP_VERTS-2)
Sys_Error ("ClipSkyPolygon: MAX_CLIP_VERTS");
if (stage == 6)
{ // fully clipped, so draw it
DrawSkyPolygon (nump, vecs);
return;
}
front = back = qfalse;
norm = skyclip[stage];
for (i=0, v = vecs ; i<nump ; i++, v+=3)
{
d = DotProduct (v, norm);
if (d > ON_EPSILON)
{
front = qtrue;
sides[i] = SIDE_FRONT;
}
else if (d < ON_EPSILON)
{
back = qtrue;
sides[i] = SIDE_BACK;
}
else
sides[i] = SIDE_ON;
dists[i] = d;
}
if (!front || !back)
{ // not clipped
ClipSkyPolygon (nump, vecs, stage+1);
return;
}
// clip it
sides[i] = sides[0];
dists[i] = dists[0];
VectorCopy (vecs, (vecs+(i*3)) );
newc[0] = newc[1] = 0;
for (i=0, v = vecs ; i<nump ; i++, v+=3)
{
switch (sides[i])
{
case SIDE_FRONT:
VectorCopy (v, newv[0][newc[0]]);
newc[0]++;
break;
case SIDE_BACK:
VectorCopy (v, newv[1][newc[1]]);
newc[1]++;
break;
case SIDE_ON:
VectorCopy (v, newv[0][newc[0]]);
newc[0]++;
VectorCopy (v, newv[1][newc[1]]);
newc[1]++;
break;
}
if (sides[i] == SIDE_ON || sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
continue;
d = dists[i] / (dists[i] - dists[i+1]);
for (j=0 ; j<3 ; j++)
{
e = v[j] + d*(v[j+3] - v[j]);
newv[0][newc[0]][j] = e;
newv[1][newc[1]][j] = e;
}
newc[0]++;
newc[1]++;
}
// continue
ClipSkyPolygon (newc[0], newv[0][0], stage+1);
ClipSkyPolygon (newc[1], newv[1][0], stage+1);
}
/*
==============
R_ClearSkyBox
==============
*/
void R_ClearSkyBox (void)
{
int i;
for (i=0 ; i<6 ; i++)
{
skymins[0][i] = skymins[1][i] = 9999;
skymaxs[0][i] = skymaxs[1][i] = -9999;
}
}
float s_axis;
float t_axis;
vec3_t v_axis;
void MakeSkyVec (float s, float t, int axis)
{
vec3_t b;
int j, k;
b[0] = s*r_skyclip.value;
b[1] = t*r_skyclip.value;
b[2] = r_skyclip.value;
for (j=0 ; j<3 ; j++)
{
k = st_to_vec[axis][j];
if (k < 0)
v_axis[j] = -b[-k - 1];
else
v_axis[j] = b[k - 1];
v_axis[j] += r_origin[j];
}
// avoid bilerp seam
s = (s+1)*0.5;
t = (t+1)*0.5;
if (s < 1.0/512)
s = 1.0/512;
else if (s > 511.0/512)
s = 511.0/512;
if (t < 1.0/512)
t = 1.0/512;
else if (t > 511.0/512)
t = 511.0/512;
t = 1.0 - t;
s_axis = s;
t_axis = t;
}
/*
==============
R_DrawSkyBox
==============
*/
void R_DrawSkyBox (void)
{
int i;
float r,g,b,a;
for (i=0 ; i<6 ; i++)
{
// Allocate memory for this polygon.
const int unclipped_vertex_count = 4;
glvert_t* const unclipped_vertices =
static_cast<glvert_t*>(sceGuGetMemory(sizeof(glvert_t) * unclipped_vertex_count));
if (skymins[0][i] >= skymaxs[0][i]
|| skymins[1][i] >= skymaxs[1][i])
continue;
GL_Bind (skyimage[skytexorder[i]]);
MakeSkyVec (skymins[0][i], skymins[1][i], i);
unclipped_vertices[0].st[0] = s_axis;
unclipped_vertices[0].st[1] = t_axis;
unclipped_vertices[0].xyz[0] = v_axis[0];
unclipped_vertices[0].xyz[1] = v_axis[1];
unclipped_vertices[0].xyz[2] = v_axis[2];
MakeSkyVec (skymins[0][i], skymaxs[1][i], i);
unclipped_vertices[1].st[0] = s_axis;
unclipped_vertices[1].st[1] = t_axis;
unclipped_vertices[1].xyz[0] = v_axis[0];
unclipped_vertices[1].xyz[1] = v_axis[1];
unclipped_vertices[1].xyz[2] = v_axis[2];
MakeSkyVec (skymaxs[0][i], skymaxs[1][i], i);
unclipped_vertices[2].st[0] = s_axis;
unclipped_vertices[2].st[1] = t_axis;
unclipped_vertices[2].xyz[0] = v_axis[0];
unclipped_vertices[2].xyz[1] = v_axis[1];
unclipped_vertices[2].xyz[2] = v_axis[2];
MakeSkyVec (skymaxs[0][i], skymins[1][i], i);
unclipped_vertices[3].st[0] = s_axis;
unclipped_vertices[3].st[1] = t_axis;
unclipped_vertices[3].xyz[0] = v_axis[0];
unclipped_vertices[3].xyz[1] = v_axis[1];
unclipped_vertices[3].xyz[2] = v_axis[2];
if (clipping::is_clipping_required(
unclipped_vertices,
unclipped_vertex_count))
{
// Clip the polygon.
const glvert_t* clipped_vertices;
std::size_t clipped_vertex_count;
clipping::clip(
unclipped_vertices,
unclipped_vertex_count,
&clipped_vertices,
&clipped_vertex_count);
// Did we have any vertices left?
if (clipped_vertex_count)
{
// Copy the vertices to the display list.
const std::size_t buffer_size = clipped_vertex_count * sizeof(glvert_t);
glvert_t* const display_list_vertices = static_cast<glvert_t*>(sceGuGetMemory(buffer_size));
memcpy(display_list_vertices, clipped_vertices, buffer_size);
if(cl.worldmodel)
VID_SetPaletteSKY ();
Fog_DisableGFog();
if (r_refdef.fog_end > 0 && r_skyfog.value)
{
a = r_refdef.fog_end * 0.00025f;
r = r_refdef.fog_red * 0.01f + (a * 0.25f);
g = r_refdef.fog_green * 0.01f + (a * 0.25f);
b = r_refdef.fog_blue * 0.01f + (a * 0.25f);
if (a > 1)
a = 1;
if (r > 1)
r = 1;
if (g > 1)
g = 1;
if (b > 1)
b = 1;
sceGuEnable(GU_BLEND);
sceGuBlendFunc(GU_ADD, GU_FIX, GU_FIX, GU_COLOR(r,g,b,a), GU_COLOR(r,g,b,a));
}
sceGuDepthRange(32767, 65535);
// Draw the clipped vertices.
sceGuDrawArray(
GU_TRIANGLE_FAN,
GU_TEXTURE_32BITF | GU_VERTEX_32BITF,
clipped_vertex_count, 0, display_list_vertices);
sceGuDepthRange(0, 65535);
if (r_refdef.fog_end > 0 && r_skyfog.value)
{
sceGuDisable(GU_BLEND);
sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
}
VID_SetPaletteTX ();
Fog_EnableGFog();
}
}
else
{
if(cl.worldmodel)
VID_SetPaletteSKY ();
Fog_DisableGFog();
if (r_refdef.fog_end > 0 && r_skyfog.value)
{
a = r_refdef.fog_end * 0.00025f;
r = r_refdef.fog_red * 0.01f + (a * 0.25f);
g = r_refdef.fog_green * 0.01f + (a * 0.25f);
b = r_refdef.fog_blue * 0.01f + (a * 0.25f);
if (a > 1)
a = 1;
if (r > 1)
r = 1;
if (g > 1)
g = 1;
if (b > 1)
b = 1;
sceGuEnable(GU_BLEND);
sceGuBlendFunc(GU_ADD, GU_FIX, GU_FIX, GU_COLOR(r,g,b,a), GU_COLOR(r,g,b,a));
}
sceGuDepthRange(32767, 65535);
// Draw the poly directly.
sceGuDrawArray(
GU_TRIANGLE_FAN,
GU_TEXTURE_32BITF | GU_VERTEX_32BITF,
unclipped_vertex_count, 0, unclipped_vertices);
sceGuDepthRange(0, 65535);
if (r_refdef.fog_end > 0 && r_skyfog.value)
{
sceGuDisable(GU_BLEND);
sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
}
VID_SetPaletteTX ();
Fog_EnableGFog();
}
}
}
//===============================================================
/*
=================
R_DrawSkyChain
=================
*/
void R_DrawSkyChain (msurface_t *s)
{
msurface_t *fa;
int i;
vec3_t verts[MAX_CLIP_VERTS];
glpoly_t *p;
if (skybox_name[0]) // if the skybox has a name, draw the skybox
{
c_sky = 0;
// GL_Bind(solidskytexture);
// calculate vertex values for sky box
for (fa=s ; fa ; fa=fa->texturechain)
{
for (p=fa->polys ; p ; p=p->next)
{
for (i=0 ; i<p->numverts ; i++)
{
VectorSubtract (p->verts[i].xyz, r_origin, verts[i]);
}
ClipSkyPolygon (p->numverts, verts[0], 0);
}
}
}
else // otherwise, draw the normal quake sky
{
// used when gl_texsort is on
GL_Bind(solidskytexture);
if (kurok)
speedscale = realtime*2;
else
speedscale = realtime*8;
speedscale -= (int)speedscale & ~127 ;
for (fa=s ; fa ; fa=fa->texturechain)
EmitSkyPolys (fa);
sceGuEnable(GU_BLEND);
// sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
GL_Bind (alphaskytexture);
if (kurok)
speedscale = realtime*4;
else
speedscale = realtime*16;
speedscale -= (int)speedscale & ~127 ;
for (fa=s ; fa ; fa=fa->texturechain)
EmitSkyPolys (fa);
sceGuDisable(GU_BLEND);
// sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
}
}
|
|
|
| Back to top |
|
 |
J.F.
Joined: 22 Feb 2004 Posts: 2906
|
Posted: Thu Aug 21, 2008 1:41 pm Post subject: |
|
|
| I'd look more into how you're doing the textures... the main difference between the Phat and Slim as far a video goes is the amount of vram. Maybe you're loading more than 2 MB into vram, which will work in the Slim, but not the Phat. |
|
| Back to top |
|
 |
MDave
Joined: 09 May 2005 Posts: 84
|
Posted: Thu Aug 21, 2008 1:57 pm Post subject: |
|
|
I havn't unlocked the extra 2mb of vram for the slim (because I'm having problems using it after unlocking it).
Can't be vram because I fallback on using system ram if there isn't any vram left to allocate. Thanks to some help on irc, it seems to be related to how the phat psp dosn't like uvmap coordinates below 0, which the slim dosn't suffer from. Which is what happens when the skypolys are being shifted around (and the coordinates) because of clipping against the world geometry. Not sure what to do. |
|
| Back to top |
|
 |
Raphael

Joined: 17 Jan 2006 Posts: 646 Location: Germany
|
Posted: Thu Aug 21, 2008 2:15 pm Post subject: |
|
|
You could try manually wrapping the texture coordinates when they are < 0 by adding 1.0 to it until they are >= 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 Aug 21, 2008 3:31 pm Post subject: |
|
|
Solved via IRC. Screw Sony for not creating a DMA interface aware of the CPU cache for the sake of saving a few latency cycles.
Tradeoff: Hours and days of debugging pseudo-random bugs, again and again.
Anyway, thank you SCE.
For all follow-up readers - the once again solution:
Whenever you're going to draw a vertex buffer that you dynamically create (or have touched for any means), be sure to add a sceKernelDcacheWritebackRange( vertex_buffer, vertex_buffer_size ); before the following sceGu(m)Draw* call. _________________ <Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
Last edited by Raphael on Fri Aug 22, 2008 7:14 am; edited 1 time in total |
|
| Back to top |
|
 |
hlide
Joined: 10 Sep 2006 Posts: 750
|
Posted: Thu Aug 21, 2008 7:17 pm Post subject: |
|
|
| are you speaking about the GPU internal cache for texture or about Allegrex cache ? so far as I know, you always need to writeback the Allegrex cache especially if a DMA operation is envolved. |
|
| Back to top |
|
 |
KickinAezz
Joined: 03 Jun 2007 Posts: 328
|
Posted: Fri Aug 22, 2008 12:53 am Post subject: |
|
|
| Raphael wrote: | Solved via IRC. Screw Sony for not creating a DMA interface aware of the CPU cache for the sake of saving a few latency cycles.
Tradeoff: Hours and days of debugging pseudo-random bugs, again and again.
Or was it all just a hardware bug to begin with, seeing this 'fixed' on SLIM?
Anyway, thank you SCE.
For all follow-up readers - the once again solution:
Whenever you're going to draw a vertex buffer that you dynamically create (or have touched for any means), be sure to add a sceKernelDcacheWritebackRange( vertex_buffer, vertex_buffer_size ); before the following sceGu(m)Draw* call. |
Will sceKernelDcacheWriteBackAll() be Sufficient if framerate is not put to consideration? _________________ Intrigued by PSP system Since December 2006.
Use it more for Development than for Gaming. |
|
| Back to top |
|
 |
MDave
Joined: 09 May 2005 Posts: 84
|
Posted: Fri Aug 22, 2008 2:38 am Post subject: |
|
|
It seems it hasn't totally fixed my problems. The S and T coordintes are the prime suspect here, the phat dosn't like me flipping the T axis (so the skybox images are displayed correctly) while the slim has no problem about it.
I get better results if I flip the T axis in these, and don't write back to the cache (still not perfect though):
| Code: |
// Orignal
unclipped_vertices[0].st[1] = t_axis;
// New
unclipped_vertices[0].st[1] = (t_axis = 1.0f - t_axis); |
instead of flipping it in the other original function like this:
Any ideas?
Here's screenshots, using the above fix:
Without cache writeback:
With cache writeback:
 |
|
| Back to top |
|
 |
MDave
Joined: 09 May 2005 Posts: 84
|
Posted: Fri Aug 22, 2008 8:41 am Post subject: |
|
|
Temporary solution for now is to flip the image vertically in an image editor instead of doing it in code.
I guess this is something that won't be easily solved, thanks sony :( |
|
| 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
|