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 

Flickering / missing single-pixel lines/dots?

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



Joined: 30 Aug 2005
Posts: 29

PostPosted: Fri Sep 02, 2005 1:04 pm    Post subject: Flickering / missing single-pixel lines/dots? Reply with quote

The emu is running along well so I expect my blitting code is working as expected (and its essentially derived from the blit sample in the SDK.) For a couple of days I've been trying to bring over some UI code I've been using in a couple other platforms, but it always renders as a total mess.. the code is known good, and when reduced to the very basics, still futzes up.

Ex:

Draw a filled rectangle most of the screen size; works every time.

Draw a 1 pixel tall line across the screen, just inside the box, and just above the box. The one in the box and the one out of the box will both be missing some parts.. but different parts. Moving the line up or down the screen makes it miss different parts... though things drawn near the bottom right seem to miss more than things in the top left. Its not a simple unsigned char when should be unsigned int issue.. this code works fine on a half dozen platforms, and the kicker.. works fine for thick lines on the PSP more or less.

ie: Thickening the lines up to 10 pixels and they show up pretty well, though still a little distortion near the bottom right. Reduce to 1 or 3 pixels, and piles of parts start missing. Needless to say, rendering fonts and such is a total mess, with most of the pixels just not showing.

I'm relatively new to open-gl like systems, so I'm betting its something like the GPU deciding to average out the texture and dropping the pixels.. but it'd make more sense to me if it dropped out the whole line.. and not just a few bits of it.

Ex:

I'll draw a line and it'll show up like this...

--------------------------- ------------------- ----- ---- - - -

Whats very strange is I can redraw it over and over, and the missing parts might change here or there, every half second or so.. though in general it'll stay constant.

ie:

while ( running ) {
render-line-and-swap-buffers
}

For debugging I've tossedo ut the bresenham line draw and reduced it to a rediculously stupid line draw.. to no avail:

void render_line_v ( display16_t *disp, UInt16 c,
UInt32 x1, UInt32 y1, UInt32 h )
{
UInt32 x = disp -> pitch;
x *= ( (UInt32) y1 );
x += ( (UInt32) x1 );
//UInt16 *cursor = disp -> vram + ( disp -> pitch * y1 ) + x1;
UInt16 *cursor = disp -> vram + x;
while ( h ) {
*cursor = c;
cursor += disp -> pitch;
h--;
}
return;
}

I've got others, but they _all_ have the same effect and the line draw code is known good.

The 'blit' function I'm testing with is here (I've got numerous variatoins, with pre-set vertice lists and such, but since this is damaging my mind I'm keeping this one since its dumb and near to the blit sample.):

void cj_psp_2d_blit ( unsigned short int *pixels ) {
unsigned int j;

// begin logging GPU commands to our command buffer
sceGuStart ( GU_DIRECT, gpu_list );

// setup the source buffer as a 512x512 texture, but only copy 480x272
sceGuTexMode ( GU_PSM_4444, 0, 0, 0 );
sceGuTexImage ( 0, 512, 512, 512, pixels );
sceGuTexFunc ( GU_TFX_REPLACE, GU_TCC_RGB );
sceGuTexFilter ( GU_NEAREST, GU_NEAREST );
sceGuTexScale ( 1.0f/512.0f, 1.0f/512.0f ); // scale UVs to 0..1
sceGuTexOffset ( 0.0f, 0.0f );
sceGuAmbientColor ( 0xffffffff );

// do a striped blit (takes the page-cache into account)
unsigned char stripe = 0;
for ( j = 0; j < 480; j = j+SLICE_SIZE ) {
vertex_t *vertices = g_vertices + ( 2 * stripe );
//vertex_t *vertices = (vertex_t*)sceGuGetMemory(2 * sizeof(vertex_t));

vertices[0].u = j; vertices[0].v = 0;
vertices[0].color = 0;
vertices[0].x = j; vertices[0].y = 0; vertices[0].z = 0;
vertices[1].u = j+SLICE_SIZE; vertices[1].v = 272;
vertices[1].color = 0;
vertices[1].x = j+SLICE_SIZE; vertices[1].y = 272; vertices[1].z = 0;

sceGuDrawArray ( GU_SPRITES,
GU_TEXTURE_16BIT | GU_COLOR_4444 | GU_VERTEX_16BIT |
GU_TRANSFORM_2D, 2, 0, vertices );

stripe++;
} // for

// wrap up the rendering pipe
sceGuFinish();
sceGuSync(0,0);

// sceDisplayWaitVblankStart();
sceGuSwapBuffers();

return;
}

Am I doing anything obviously wrong in the blit routine, to cause the GPU to drop out single pixels or thin lines or the like?

jeff
_________________
--
Have you played Atari today?
Back to top
View user's profile Send private message Visit poster's website AIM Address
ector



Joined: 12 May 2005
Posts: 195

PostPosted: Fri Sep 02, 2005 5:04 pm    Post subject: Reply with quote

Yup, you don't flush your vertex data out of the cpu cache, so the gfx chip can't see all of it in memory properly.
_________________
http://www.dtek.chalmers.se/~tronic/PSPTexTool.zip Free texture converter for PSP with source. More to come.
Back to top
View user's profile Send private message
holger



Joined: 18 Aug 2005
Posts: 204

PostPosted: Fri Sep 02, 2005 9:00 pm    Post subject: Reply with quote

If you are writing to VRAM you either need to use uncached adresses or flush the CPU DCache before calling GE commands again, otherwise it's not guaranteed that all writes are arrived in VRAM when you swap buffers.
Back to top
View user's profile Send private message
skeezixcodejedi



Joined: 30 Aug 2005
Posts: 29

PostPosted: Fri Sep 02, 2005 9:56 pm    Post subject: Reply with quote

Oh baby.. some success! (after a couple of days this is a big thing :)

Where is the proper place to do this? I had dropped a couple of calls in there before but it didn't help.. so the trick is to drop the,m right after each call to the GuDrawArray()?

Which one.. the cache or cache-and-invalidate one?

Thanks guys!

jeff
_________________
--
Have you played Atari today?
Back to top
View user's profile Send private message Visit poster's website AIM Address
holger



Joined: 18 Aug 2005
Posts: 204

PostPosted: Sat Sep 03, 2005 1:25 am    Post subject: Reply with quote

You need to synchronize accesses done by the CPU and the GE. When you started the GE you have to wait for completion (and until it flushed all pending VRAM accesses) before acessing the VRAM from the CPU. When you rendered using CPU memory accesses, you need to flush the caches before you restart the GE.
Back to top
View user's profile Send private message
skeezixcodejedi



Joined: 30 Aug 2005
Posts: 29

PostPosted: Sat Sep 03, 2005 4:23 am    Post subject: Reply with quote

Makes perfect sense in retrospect :) Thanks for the tips my friends,

jeff
_________________
--
Have you played Atari today?
Back to top
View user's profile Send private message Visit poster's website 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