Neoblast wrote:patbier wrote:PH3NOM wrote:
Anyhow, I realized there was a limitation in the way the PVR is being utilized by KOS.
I have solved the problem, and now things are faster than ever.
Great ! Can you say more about the PVR limitation and the way you solved it ?
I'm intrigued about that too... did you modify kos for that?
Sorry to get your hopes up, my solution was really simple.
The thing is, the PVR is limited to 60fps. ( I dont know if this is a hardware limitation, or KOS ).
However, the engine I'm writing is capable of much faster than that.
What I was doing is simply rendering every-other frame, so 100 frames processed by the engine meant 50 frames drawn per second.
As things turn out, I decided to try PVR Direct Rendering instead of the other PVR Primitive method.
Success!
Now, even on the larger levels, everything runs smoothly at 60fps, rendering every frame.
So, remember folks, if you are pushing thousands of polys per frame, make sure to use Direct Rendering!
To summarize:
Before, the scene was rendered in two phases.
1 - Compile the polys
Code: Select all
void DCE_compile_l1( LevelSprite_t current, int entries )
{
int i;
for( i=0; i<entries; i++ )
pvr_compile_l1( ¤t[i], 10.0f );
}
Code: Select all
inline pvr_compile_l1( LevelSprite_t sprite, float z )
{
sprite->frame.vert[0].argb = sprite->frame.vert[1].argb = sprite->frame.vert[2].argb = sprite->frame.vert[3].argb = PVR_PACK_COLOR(1.0f, 1.0f, 1.0f, 1.0f);
sprite->frame.vert[0].z = sprite->frame.vert[1].z = sprite->frame.vert[2].z = sprite->frame.vert[3].z = z;
sprite->frame.vert[0].flags = sprite->frame.vert[1].flags = sprite->frame.vert[2].flags = PVR_CMD_VERTEX;
sprite->frame.vert[3].flags = PVR_CMD_VERTEX_EOL;
sprite->frame.vert[0].x = sprite->frame.vert[1].x = sprite->x;
sprite->frame.vert[0].y = sprite->frame.vert[2].y = sprite->y+sprite->height;
sprite->frame.vert[0].v = sprite->frame.vert[2].v = sprite->frame.height_ratio;
sprite->frame.vert[1].y = sprite->frame.vert[3].y = sprite->y;
sprite->frame.vert[2].u = sprite->frame.vert[3].u = sprite->frame.width_ratio;
sprite->frame.vert[2].x = sprite->frame.vert[3].x = sprite->x+sprite->width;
pvr_poly_cxt_txr(&sprite->frame.cxt, PVR_LIST_TR_POLY, sprite->frame.texColor | sprite->frame.texFmt,
sprite->frame.vram_width, sprite->frame.vram_height, sprite->frame.vram_tex, PVR_FILTER_BILINEAR);
pvr_poly_compile(&sprite->frame.poly, &sprite->frame.cxt);
}
2 - Submit the polys
Code: Select all
void DCE_submit_l1( LevelSprite_t, int elements )
{
int i;
for (i=0; i<elements; i++ )
pvr_submit_poly( sprite[i].frame );
}
Code: Select all
inline pvr_submit_poly( struct pvr_frame pvr )
{
pvr_prim(&pvr.poly, sizeof(pvr.poly));
pvr_prim(&pvr.vert[0], sizeof(pvr.vert[0]));
pvr_prim(&pvr.vert[1], sizeof(pvr.vert[1]));
pvr_prim(&pvr.vert[2], sizeof(pvr.vert[2]));
pvr_prim(&pvr.vert[3], sizeof(pvr.vert[3]));
}
That works fine, but slows way down when pushing thousands of polys per frame.
Now, I am using a 1-pass Direct Render method:
Code: Select all
void DCE_render_l1( LevelSprite_t current, int entries )
{
int i;
for( i=0; i<entries; i++ )
pvr_direct_render_l1( ¤t[i], 10.0f );
}
Code: Select all
inline pvr_direct_render_l1( LevelSprite_t sprite, float z )
{
pvr_vertex_t *vert;
pvr_dr_state_t state;
pvr_poly_cxt_txr(&sprite->frame.cxt, PVR_LIST_TR_POLY, sprite->frame.texColor | sprite->frame.texFmt,
sprite->frame.vram_width, sprite->frame.vram_height, sprite->frame.vram_tex, PVR_FILTER_BILINEAR);
pvr_poly_compile(&sprite->frame.poly, &sprite->frame.cxt);
pvr_dr_init(state);
pvr_prim(&sprite->frame.poly, sizeof(pvr_poly_hdr_t));
vert = pvr_dr_target(state);
vert->flags = PVR_CMD_VERTEX;
vert->x = sprite->x;
vert->y = sprite->y+sprite->height;
vert->z = z;
vert->u = 0;
vert->v = sprite->frame.height_ratio;
vert->argb = 0xffffffff;
pvr_dr_commit(vert);
vert = pvr_dr_target(state);
vert->flags = PVR_CMD_VERTEX;
vert->x = sprite->x;
vert->y = sprite->y;
vert->z = z;
vert->u = 0;
vert->v = 0;
vert->argb = 0xffffffff;
pvr_dr_commit(vert);
vert = pvr_dr_target(state);
vert->flags = PVR_CMD_VERTEX;
vert->x = sprite->x+sprite->width;
vert->y = sprite->y+sprite->height;
vert->z = z;
vert->u = sprite->frame.width_ratio;
vert->v = sprite->frame.height_ratio;
vert->argb = 0xffffffff;
pvr_dr_commit(vert);
vert = pvr_dr_target(state);
vert->flags = PVR_CMD_VERTEX_EOL;
vert->x = sprite->x+sprite->width;
vert->y = sprite->y;
vert->z = z;
vert->u = sprite->frame.width_ratio;
vert->v = 0;
vert->argb = 0xffffffff;
pvr_dr_commit(vert);
}
And this is very fast! Constant 60fps.