GU buffers autoswapping?

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
svxs
Posts: 15
Joined: Fri Jun 19, 2009 10:03 am

GU buffers autoswapping?

Post by svxs »

I had an interesting idea. I need to convert DXTn compressed images to RGBA8 pixel format. The GU can handle DXTn compressed images natively, so my idea was to use it to do the conversion so that I won't need to write an algorithm to do it in software.

I planned on using the GU to render it to the draw buffer and just not swap with the display buffer. I'd have it render the DXTn image as a texture on a quad and read back the RGB data directly from the draw buffer in VRAM to somewhere in RAM without affecting anything currently on the screen.

But the buffers are swapping automatically. My code doesn't contain any calls to sceGuSwapBuffers(), so I have no idea what's up.

I also tried going directly to the rasterizer instead of transforming first, but I was wrong to assume that it was my problem.

Code: Select all

/* Body of the function that's messing up. */
sceGuStart (GU_DIRECT, gList);

sceGumMatrixMode (GU_MODEL);
sceGumLoadIdentity()

draw_quad (64, 64);

sceGuFinish();
sceGuSync (0, 0);

/* To illustrate that nothing is going on after this: */
while ( 1 )
{
}

Code: Select all

void
draw_quad ( const float nW
            , const float nH )
{
  struct vert2d
  {
    float u, v;
    uint32_t color;
    float x, y, z;
  } *p_verts = (struct vert2d *)
               sceGuGetMemory (2 * sizeof (struct vert2d));

  p_verts[0] = (struct vert2d) { 0.0f, 0.0f, 0xFF0000FF, 0.0f, 0.0f, 0.0f };
  p_verts[1] = (struct vert2d) { nW,   nH,   0xFF0000FF, nW,   nH,   0.0f };

  sceGumDrawArray
  (
    GU_SPRITES
    , GU_TEXTURE_32BITF|GU_COLOR_8888|GU_VERTEX_32BITF|GU_TRANSFORM_3D
    , 2
    , 0
    , p_verts
  );
}
Any idea what's causing the buffers to swap? Any idea how to avoid it?
svxs
Posts: 15
Joined: Fri Jun 19, 2009 10:03 am

Post by svxs »

Still can't figure this out.

The only things happening prior to this are:

A thread is set up to handle the home button.
The debug screen is initted to display the status of some operations:
The contents of a few archives is indexed in a hash table.
A few megabytes of models and images for textures are stored.
The GU is initted for drawing. Pasting that code into a sample from the SDK doesn't force the sample to automatically swap the buffers, so it isn't that.

And then, the above code is used. I'm puzzled.
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

You'll have to post more code if you want more than just guesses.
User avatar
Jim
Posts: 476
Joined: Sat Jul 02, 2005 10:06 pm
Location: Sydney
Contact:

Post by Jim »

Are you accidentally drawing on the frontbuffer?

Jim
svxs
Posts: 15
Joined: Fri Jun 19, 2009 10:03 am

Post by svxs »

I have a weird feeling that you're right Jim... I'm not sure why I would've been, but all the symptoms point that way. It's tough to tell since I removed the code in order to focus on something else. With a tremendous project like this, it's too easy to get sidetracked by the small things.

What would cause it to draw to the front buffer instead of the back buffer though? Being as intrinsically unfamiliar as I am with the SDK, my only guess would be that it could be the result of some erroneous code as a callback for buffer swapping. I was using a callback for a while, but it would've been registered much later in the program's flow than when this problem was occurring...

I'll try this idea again in a few days probably. There's still a lot of other tiny things to focus on that seem to be causing problems, but that solution to this one makes sense.
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

When you setup the GU, the first few lines usually look like this:

Code: Select all

	sceGuInit();
	sceGuStart(GU_DIRECT, list);
	sceGuDrawBuffer(GU_PSM_8888, (void*)0, BUF_WIDTH);
	sceGuDispBuffer(SCR_WIDTH, SCR_HEIGHT, (void*)0x88000, BUF_WIDTH);
The (void*)0 sets the offset in vram for the draw buffer, and the (void*)0x88000 sets the offset for the display buffer. This would most likely were you'd get them backwards (or possible have them set to the same value).
svxs
Posts: 15
Joined: Fri Jun 19, 2009 10:03 am

Post by svxs »

Hmm. Definitely wouldn't be that, then. Pointers to all three memory areas for the draw, display, and z buffers have always been to the correct places, although I recently started using valloc() from the libvram helper library to allocate them properly. The pointers are properly converted to VRAM-relative addresses for that, of course.

Was:

Code: Select all

  void *const p_draw_buffer = (void *) 0x0;
  void *const p_display_buffer = (void *) 0x88000;
  void *const p_depth_buffer = (void *) 0x110000;

  /* Set up the buffers. */
  sceGuDrawBuffer (GU_PSM_8888, p_draw_buffer, 512);
  sceGuDispBuffer (SCREEN_WIDTH, SCREEN_HEIGHT, p_display_buffer, 512);
  sceGuDepthBuffer (p_depth_buffer, 512);
Now is:

Code: Select all

  void *const p_draw_buffer = vGuPointer (valloc (512 * SCREEN_HEIGHT * 4));
  void *const p_display_buffer = vGuPointer (valloc (512 * SCREEN_HEIGHT * 4));
  void *const p_depth_buffer = vGuPointer (valloc (512 * SCREEN_HEIGHT * 2));

  /* Set up the buffers. */
  sceGuDrawBuffer (GU_PSM_8888, p_draw_buffer, 512);
  sceGuDispBuffer (SCREEN_WIDTH, SCREEN_HEIGHT, p_display_buffer, 512);
  sceGuDepthBuffer (p_depth_buffer, 512);
It would have to be something else, but my guess is that it was having to do with a callback and some bad code to swap buffers that I wrote in a rush. I removed it a day or two ago since it became no longer necessary; I'll add it back in some time and see if this whole idea goes any differently.

Edit:

On second thought, I wasn't even swapping the buffers at that point. A mystery.
Post Reply