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 

Flicker problem driving me crazy!

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



Joined: 22 Apr 2007
Posts: 17

PostPosted: Mon Oct 19, 2009 6:09 pm    Post subject: Flicker problem driving me crazy! Reply with quote

I'm dealing with what has to be one of the most annoying, stubborn bugs I've ever had. Every time I think I got it, it goes away and then comes back later. I'm going over everything with a fine-tooth comb and I just can't get to the root of the problem.

The problem is that I get BAD flicker, but only sometimes. In fact, I can get to a situation where I'll link, get no flicker, then I'll add a couple of C++ instructions, compile, link, and get flicker.

Here's the relevant code. I'm posting everything related to graphics since I'm really getting desperate with this bug.

Code:

#define PIXEL_SIZE (4)
#define BUF_WIDTH (512)
#define   PSP_SCREEN_WIDTH   480
#define   PSP_SCREEN_HEIGHT   272
#define PSP_FRAME_SIZE (BUF_WIDTH * PSP_SCREEN_HEIGHT * PIXEL_SIZE)
#define MOUSE_SIZE   128
#define   KBD_DATA_SIZE   130560

#define   MAX_FPS   30

unsigned int __attribute__((aligned(16))) displayList[2048];
unsigned short __attribute__((aligned(16))) clut256[256];
unsigned short __attribute__((aligned(16))) mouseClut[256];
unsigned short __attribute__((aligned(16))) cursorPalette[256];
unsigned int __attribute__((aligned(16))) mouseBuf256[MOUSE_SIZE*MOUSE_SIZE];


unsigned long RGBToColour(unsigned long r, unsigned long g, unsigned long b) {
   return (((b >> 3) << 10) | ((g >> 3) << 5) | ((r >> 3) << 0)) | 0x8000;
}

const OSystem::GraphicsMode OSystem_PSP::s_supportedGraphicsModes[] = {
   { "320x200 (centered)", "320x200 16-bit centered", CENTERED_320X200 },
   { "435x272 (best-fit, centered)", "435x272 16-bit centered", CENTERED_435X272 },
   { "480x272 (full screen)", "480x272 16-bit stretched", STRETCHED_480X272 },
   { "362x272 (4:3, centered)", "362x272 16-bit centered", CENTERED_362X272 },
   {0, 0, 0}
};


OSystem_PSP::OSystem_PSP() : _screenWidth(0), _screenHeight(0), _overlayWidth(0), _overlayHeight(0),
      _offscreen(0), _overlayBuffer(0), _overlayVisible(false), _shakePos(0), _lastScreenUpdate(0),
      _mouseBuf(0), _prevButtons(0), _lastPadCheck(0), _padAccel(0), _mixer(0) {
   memset(_palette, 0, sizeof(_palette));

   _cursorPaletteDisabled = true;

   _samplesPerSec = 0;

   //init SDL
   uint32   sdlFlags = SDL_INIT_AUDIO | SDL_INIT_TIMER;
   SDL_Init(sdlFlags);

   _keyboardVisible = false;
   _clut = clut256;
   _mouseBuf = (byte *)mouseBuf256;
   _graphicMode = STRETCHED_480X272;
   _keySelected = 1;

   _mouseX = PSP_SCREEN_WIDTH >> 1;   // Mouse in the middle of the screen
   _mouseY = PSP_SCREEN_HEIGHT >> 1;


   // Init GU
   sceGuInit();
   sceGuStart(0, displayList);
   sceGuDrawBuffer(GU_PSM_8888, (void *)0, BUF_WIDTH);
   sceGuDispBuffer(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT, (void*)PSP_FRAME_SIZE, BUF_WIDTH);
   sceGuDepthBuffer((void*)(PSP_FRAME_SIZE * 2), BUF_WIDTH);
   sceGuOffset(2048 - (PSP_SCREEN_WIDTH/2), 2048 - (PSP_SCREEN_HEIGHT/2));
   sceGuViewport(2048, 2048, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
   sceGuDepthRange(0xC350, 0x2710);
   sceGuScissor(0, 0, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
   sceGuEnable(GU_SCISSOR_TEST);
   sceGuFrontFace(GU_CW);
   sceGuEnable(GU_TEXTURE_2D);
   sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT);
   sceGuFinish();
   sceGuSync(0,0);

   sceDisplayWaitVblankStart();
   sceGuDisplay(1);

}

OSystem_PSP::~OSystem_PSP() {

   free(_offscreen);
   free(_overlayBuffer);
   free(_mouseBuf);
   delete _keyboard;

   _offscreen = 0;
   _overlayBuffer = 0;
   _mouseBuf = 0;
    sceGuTerm();
}

void OSystem_PSP::initSize(uint width, uint height, const Graphics::PixelFormat *format) {
   PSPDebugTrace("initSize\n");

   _screenWidth = width;
   _screenHeight = height;

   const int scrBufSize = _screenWidth * _screenHeight * (format ? format->bytesPerPixel : 4);

   _overlayWidth = PSP_SCREEN_WIDTH;   //width;
   _overlayHeight = PSP_SCREEN_HEIGHT;   //height;

   free(_overlayBuffer);
   _overlayBuffer = (OverlayColor *)memalign(64, _overlayWidth * _overlayHeight * sizeof(OverlayColor));
   fprintf(stderr, "_overlaybuffer is from %p, size = %x\n", _overlayBuffer, _overlayWidth * _overlayHeight * sizeof(OverlayColor));

   free(_offscreen);
   _offscreen = (byte *)memalign(64, scrBufSize);
   fprintf(stderr, "_offscreen is at %p, size = %x\n", _offscreen, scrBufSize);
   bzero(_offscreen, scrBufSize);
   
   clearOverlay();
   memset(_palette, 0xFFFF, 256 * sizeof(unsigned short));

   _mouseVisible = false;
   sceKernelDcacheWritebackAll();
}

int16 OSystem_PSP::getWidth() {
   return _screenWidth;
}

int16 OSystem_PSP::getHeight() {
   return _screenHeight;
}

void OSystem_PSP::setPalette(const byte *colors, uint start, uint num) {
   const byte *b = colors;

   for (uint i = 0; i < num; ++i) {
      _palette[start + i] = RGBToColour(b[0], b[1], b[2]);
      b += 4;
   }

   //copy to CLUT
   memcpy(_clut, _palette, 256 * sizeof(unsigned short));

   //force update of mouse CLUT as well, as it may have been set up before this palette was set
   memcpy(mouseClut, _palette, 256 * sizeof(unsigned short));
   mouseClut[_mouseKeyColour] = 0;

   sceKernelDcacheWritebackAll();
}

void OSystem_PSP::setCursorPalette(const byte *colors, uint start, uint num) {
   const byte *b = colors;

   for (uint i = 0; i < num; ++i) {
      cursorPalette[start + i] = RGBToColour(b[0], b[1], b[2]);
      b += 4;
   }

   cursorPalette[0] = 0;

   _cursorPaletteDisabled = false;

   sceKernelDcacheWritebackAll();
}

void OSystem_PSP::copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h) {
   //Clip the coordinates
   if (x < 0) {
      w += x;
      buf -= x;
      x = 0;
   }

   if (y < 0) {
      h += y;
      buf -= y * pitch;
      y = 0;
   }

   if (w > _screenWidth - x) {
      w = _screenWidth - x;
   }

   if (h > _screenHeight - y) {
      h = _screenHeight - y;
   }

   if (w <= 0 || h <= 0)
      return;


   byte *dst = _offscreen + y * _screenWidth + x;

   if (_screenWidth == pitch && pitch == w) {
      memcpy(dst, buf, h * w);
   } else {
      do {
         memcpy(dst, buf, w);
         buf += pitch;
         dst += _screenWidth;
      } while (--h);
   }
   sceKernelDcacheWritebackAll();

}

Graphics::Surface *OSystem_PSP::lockScreen() {
   _framebuffer.pixels = _offscreen;
   _framebuffer.w = _screenWidth;
   _framebuffer.h = _screenHeight;
   _framebuffer.pitch = _screenWidth;
   _framebuffer.bytesPerPixel = 1;

   return &_framebuffer;
}

void OSystem_PSP::unlockScreen() {
   // The screen is always completely update anyway, so we don't have to force a full update here.
   sceKernelDcacheWritebackAll();
}

void OSystem_PSP::updateScreen() {
   u32 now = getMillis();
   if (now - _lastScreenUpdate < 1000 / MAX_FPS)
      return;

   _lastScreenUpdate = now;

   sceGuStart(0, displayList);

   sceGuClearColor(0xFF000000);
   sceGuClear(GU_COLOR_BUFFER_BIT);

   sceGuClutMode(GU_PSM_5551, 0, 0xFF, 0);
   sceGuClutLoad(32, clut256); // upload 32*8 entries (256)
   sceGuTexMode(GU_PSM_T8, 0, 0, 0); // 8-bit image
   if (_screenWidth == 320)
      sceGuTexImage(0, 512, 256, _screenWidth, _offscreen);
   else
      sceGuTexImage(0, 512, 512, _screenWidth, _offscreen);
   sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB);
   sceGuTexFilter(GU_LINEAR, GU_LINEAR);
   sceGuTexOffset(0,0);
   sceGuAmbientColor(0xFFFFFFFF);
   sceGuColor(0xFFFFFFFF);

   Vertex *vertices = (Vertex *)sceGuGetMemory(2 * sizeof(Vertex));
   vertices[0].u = 0.5f;
   vertices[0].v = 0.5f;
   vertices[1].u = _screenWidth - 0.5f;
   vertices[1].v = _screenHeight - 0.5f;

   switch (_graphicMode) {
      case CENTERED_320X200:
         vertices[0].x = (PSP_SCREEN_WIDTH - 320) / 2;
         vertices[0].y = (PSP_SCREEN_HEIGHT - 200) / 2;
         vertices[0].z = 0;
         vertices[1].x = PSP_SCREEN_WIDTH - (PSP_SCREEN_WIDTH - 320) / 2;
         vertices[1].y = PSP_SCREEN_HEIGHT - (PSP_SCREEN_HEIGHT - 200) / 2;
         vertices[1].z = 0;
      break;
      case CENTERED_435X272:
         vertices[0].x = (PSP_SCREEN_WIDTH - 435) / 2;
         vertices[0].y = 0; vertices[0].z = 0;
         vertices[1].x = PSP_SCREEN_WIDTH - (PSP_SCREEN_WIDTH - 435) / 2;
         vertices[1].y = PSP_SCREEN_HEIGHT;
         vertices[1].z = 0;
      break;
      case STRETCHED_480X272:
         vertices[0].x = 0;
         vertices[0].y = 0;
         vertices[0].z = 0;
         vertices[1].x = PSP_SCREEN_WIDTH;
         vertices[1].y = PSP_SCREEN_HEIGHT;
         vertices[1].z = 0;
      break;
      case CENTERED_362X272:
         vertices[0].x = (PSP_SCREEN_WIDTH - 362) / 2;
         vertices[0].y = 0;
         vertices[0].z = 0;
         vertices[1].x = PSP_SCREEN_WIDTH - (PSP_SCREEN_WIDTH - 362) / 2;
         vertices[1].y = PSP_SCREEN_HEIGHT;
         vertices[1].z = 0;
      break;
   }

   if (_shakePos) {
      vertices[0].y += _shakePos;
      vertices[1].y += _shakePos;
   }

   sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices);
   if (_screenWidth == 640) {
      // 2nd draw
      Vertex *vertices2 = (Vertex *)sceGuGetMemory(2 * sizeof(Vertex));
      sceGuTexImage(0, 512, 512, _screenWidth, _offscreen+512);
      vertices2[0].u = 512 + 0.5f;
      vertices2[0].v = vertices[0].v;
      vertices2[1].u = vertices[1].u;
      vertices2[1].v = _screenHeight - 0.5f;
      vertices2[0].x = vertices[0].x + (vertices[1].x - vertices[0].x) * 511 / 640;
      vertices2[0].y = 0;
      vertices2[0].z = 0;
      vertices2[1].x = vertices[1].x;
      vertices2[1].y = vertices[1].y;
      vertices2[1].z = 0;
      sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices2);
   }


   // draw overlay
   if (_overlayVisible) {
      Vertex *vertOverlay = (Vertex *)sceGuGetMemory(2 * sizeof(Vertex));
      vertOverlay[0].x = 0;
      vertOverlay[0].y = 0;
      vertOverlay[0].z = 0;
      vertOverlay[1].x = PSP_SCREEN_WIDTH;
      vertOverlay[1].y = PSP_SCREEN_HEIGHT;
      vertOverlay[1].z = 0;
      vertOverlay[0].u = 0.5f;
      vertOverlay[0].v = 0.5f;
      vertOverlay[1].u = _overlayWidth - 0.5f;
      vertOverlay[1].v = _overlayHeight - 0.5f;
      sceGuTexMode(GU_PSM_4444, 0, 0, 0); // 16-bit image
      sceGuDisable(GU_ALPHA_TEST);
      sceGuEnable(GU_BLEND);

      //sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
      sceGuBlendFunc(GU_ADD, GU_FIX, GU_ONE_MINUS_SRC_ALPHA, 0xFFFFFFFF, 0);

      if (_overlayWidth > 320)
         sceGuTexImage(0, 512, 512, _overlayWidth, _overlayBuffer);
      else
         sceGuTexImage(0, 512, 256, _overlayWidth, _overlayBuffer);

      sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
      sceGuDrawArray(GU_SPRITES,GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D,2,0,vertOverlay);
      // need to render twice for textures > 512
      if ( _overlayWidth > 512) {
         Vertex *vertOverlay2 = (Vertex *)sceGuGetMemory(2 * sizeof(Vertex));
         sceGuTexImage(0, 512, 512, _overlayWidth, _overlayBuffer + 512);
         vertOverlay2[0].u = 512 + 0.5f;
         vertOverlay2[0].v = vertOverlay[0].v;
         vertOverlay2[1].u = vertOverlay[1].u;
         vertOverlay2[1].v = _overlayHeight - 0.5f;
         vertOverlay2[0].x = PSP_SCREEN_WIDTH * 512 / 640;
         vertOverlay2[0].y = 0;
         vertOverlay2[0].z = 0;
         vertOverlay2[1].x = PSP_SCREEN_WIDTH;
         vertOverlay2[1].y = PSP_SCREEN_HEIGHT;
         vertOverlay2[1].z = 0;         
         sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertOverlay2);
      }
      sceGuDisable(GU_BLEND);
   }

   // draw mouse
   if (_mouseVisible) {
      sceGuTexMode(GU_PSM_T8, 0, 0, 0); // 8-bit image
      sceGuClutMode(GU_PSM_5551, 0, 0xFF, 0);
      sceGuClutLoad(32, _cursorPaletteDisabled ? mouseClut : cursorPalette); // upload 32*8 entries (256)
      sceGuAlphaFunc(GU_GREATER, 0, 0xFF);
      sceGuEnable(GU_ALPHA_TEST);
      sceGuTexImage(0, MOUSE_SIZE, MOUSE_SIZE, MOUSE_SIZE, _mouseBuf);
      sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA);

      Vertex *vertMouse = (Vertex *)sceGuGetMemory(2 * sizeof(Vertex));
      vertMouse[0].u = 0.5f;
      vertMouse[0].v = 0.5f;
      vertMouse[1].u = _mouseWidth - 0.5f;
      vertMouse[1].v = _mouseHeight - 0.5f;

      //adjust cursor position
      int mX = _mouseX - _mouseHotspotX;
      int mY = _mouseY - _mouseHotspotY;

      if (_overlayVisible) {
         float scalex, scaley;

         scalex = (float)PSP_SCREEN_WIDTH /_overlayWidth;
         scaley = (float)PSP_SCREEN_HEIGHT /_overlayHeight;

         vertMouse[0].x = mX * scalex;
         vertMouse[0].y = mY * scaley;
         vertMouse[0].z = 0;
         vertMouse[1].x = vertMouse[0].x + _mouseWidth * scalex;
         vertMouse[1].y = vertMouse[0].y + _mouseHeight * scaley;
         vertMouse[1].z = 0;
      } else
         switch (_graphicMode) {
         case CENTERED_320X200:
            vertMouse[0].x = (PSP_SCREEN_WIDTH - 320) / 2 + mX;
            vertMouse[0].y = (PSP_SCREEN_HEIGHT - 200) / 2 + mY;
            vertMouse[0].z = 0;
            vertMouse[1].x = vertMouse[0].x + _mouseWidth;
            vertMouse[1].y = vertMouse[0].y + _mouseHeight;
            vertMouse[1].z = 0;
         break;
         case CENTERED_435X272:
         {
            float scalex, scaley;

            scalex = 435.0f / _screenWidth;
            scaley = 272.0f / _screenHeight;

            vertMouse[0].x = (PSP_SCREEN_WIDTH - 435) / 2 + mX * scalex;
            vertMouse[0].y = mY * scaley;
            vertMouse[0].z = 0;
            vertMouse[1].x = vertMouse[0].x + _mouseWidth * scalex;
            vertMouse[1].y = vertMouse[0].y + _mouseHeight * scaley;
            vertMouse[1].z = 0;
         }
         break;
         case CENTERED_362X272:
         {
            float scalex, scaley;

            scalex = 362.0f / _screenWidth;
            scaley = 272.0f / _screenHeight;

            vertMouse[0].x = (PSP_SCREEN_WIDTH - 362) / 2 + mX * scalex;
            vertMouse[0].y = mY * scaley;
            vertMouse[0].z = 0;
            vertMouse[1].x = vertMouse[0].x + _mouseWidth * scalex;
            vertMouse[1].y = vertMouse[0].y + _mouseHeight * scaley;
            vertMouse[1].z = 0;
         }
         break;
         case STRETCHED_480X272:
         {
            float scalex, scaley;

            scalex = (float)PSP_SCREEN_WIDTH / _screenWidth;
            scaley = (float)PSP_SCREEN_HEIGHT / _screenHeight;

            vertMouse[0].x = mX * scalex;
            vertMouse[0].y = mY * scaley;
            vertMouse[0].z = 0;
            vertMouse[1].x = vertMouse[0].x + _mouseWidth * scalex;
            vertMouse[1].y = vertMouse[0].y + _mouseHeight * scaley;
            vertMouse[1].z = 0;
         }
         break;
      }
      sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertMouse);
   }

   if (_keyboardVisible) {
      _keyboard->render();
   }

   sceGuFinish();
   sceGuSync(0,0);

   sceDisplayWaitVblankStart();
   sceGuSwapBuffers();
}

void OSystem_PSP::clearOverlay() {
   PSPDebugTrace("clearOverlay\n");
   bzero(_overlayBuffer, _overlayWidth * _overlayHeight * sizeof(OverlayColor));
   sceKernelDcacheWritebackAll();
}

void OSystem_PSP::grabOverlay(OverlayColor *buf, int pitch) {
   int h = _overlayHeight;
   OverlayColor *src = _overlayBuffer;

   do {
      memcpy(buf, src, _overlayWidth * sizeof(OverlayColor));
      src += _overlayWidth;
      buf += pitch;
   } while (--h);
}

void OSystem_PSP::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h) {
   PSPDebugTrace("copyRectToOverlay\n");

   //Clip the coordinates
   if (x < 0) {
      w += x;
      buf -= x;
      x = 0;
   }

   if (y < 0) {
      h += y;
      buf -= y * pitch;
      y = 0;
   }

   if (w > _overlayWidth - x) {
      w = _overlayWidth - x;
   }

   if (h > _overlayHeight - y) {
      h = _overlayHeight - y;
   }

   if (w <= 0 || h <= 0)
      return;


   OverlayColor *dst = _overlayBuffer + (y * _overlayWidth + x);

   if (_overlayWidth == pitch && pitch == w) {
      memcpy(dst, buf, h * w * sizeof(OverlayColor));
   } else {
      do {
         memcpy(dst, buf, w * sizeof(OverlayColor));
         buf += pitch;
         dst += _overlayWidth;
      } while (--h);
   }
   sceKernelDcacheWritebackAll();
}

int16 OSystem_PSP::getOverlayWidth() {
   return _overlayWidth;
}

int16 OSystem_PSP::getOverlayHeight() {
   return _overlayHeight;
}


void OSystem_PSP::grabPalette(byte *colors, uint start, uint num) {
   uint i;
   uint16 color;

   for (i = start; i < start + num; i++) {
      color = _palette;
      *colors++ = ((color & 0x1F) << 3);
      *colors++ = (((color >> 5) & 0x1F) << 3);
      *colors++ = (((color >> 10) & 0x1F) << 3);
      *colors++ = (color & 0x8000 ? 255 : 0);
   }
}

void OSystem_PSP::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) {
   //TODO: handle cursorTargetScale
   _mouseWidth = w;
   _mouseHeight = h;

   _mouseHotspotX = hotspotX;
   _mouseHotspotY = hotspotY;

   _mouseKeyColour = keycolor & 0xFF;

   memcpy(mouseClut, _palette, 256 * sizeof(unsigned short));
   mouseClut[_mouseKeyColour] = 0;

   for (unsigned int i = 0; i < h; i++)
      memcpy(_mouseBuf + i * MOUSE_SIZE, buf + i * w, w);
     
   sceKernelDcacheWritebackAll();     
}


Last edited by Bluddy on Thu Oct 22, 2009 3:38 pm; edited 2 times in total
Back to top
View user's profile Send private message
Bluddy



Joined: 22 Apr 2007
Posts: 17

PostPosted: Wed Oct 21, 2009 5:22 pm    Post subject: Reply with quote

OK I see there are no takers. Sorry for now putting the code in a proper box.

Let me add a couple of things I've figured out through my investigations: the code can run either in 320x200 mode (which is usually adjusted to be fullscreen on the PSP) or 640x480 mode (which is shrunk to fit using the GE). In 320x200 mode, I get flickering black horizontal stripes on the screen -- sometimes all the time, sometimes every few seconds, sometimes at the bottom of the screen and sometimes at other locations, though almost never at the top.

In 640x480 mode something more interesting happens: notice that we have to render twice with 512x512 pixel textures. I also get flickering here, but also, the second render (that's shifted right 512 pixels) gets the main picture but also a faint leftover of the first texture rendered! It's as if it didn't manage to write fully, perhaps because of a cache problem?

I know that the updates to the _offscreen texture (done in copyRectToScreen) are fine -- very few of them happen relatively.

Another thing I noticed is that I can make the problem go away by creating a global array. An array of char[30] will often shift *something* enough to 'fix' the problem. This is obviously very strange.

My guess is that it's some kind of cache problem, which is why moving some data helps -- we're moving to a different line in the cache. However, I went over the code several times and I can't find any specific cache problem. Adding a cache invalidate before writing the display list also didn't help.

Another guess is that it may be related to refresh issues. Perhaps for some reason I'm not really synchronized with vsync (even though I do wait for it)?

I've also tried moving the frame buffers in vram so they're not next to each other, and so they're in different locations, just in case something was creating a cache coherency problem on those specific addresses. It also doesn't help.

I'd really appreciate people's input.
Back to top
View user's profile Send private message
J.F.



Joined: 22 Feb 2004
Posts: 2906

PostPosted: Thu Oct 22, 2009 12:44 pm    Post subject: Reply with quote

Well, you could edit the post and put it in code tags. :)

Try flipping these two lines around

Code:
    sceDisplayWaitVblankStart();
    sceGuSwapBuffers();
Back to top
View user's profile Send private message AIM Address
Bluddy



Joined: 22 Apr 2007
Posts: 17

PostPosted: Fri Oct 23, 2009 7:17 pm    Post subject: Reply with quote

Tried swapping the lines. It didn't work, but thanks for the idea.
Back to top
View user's profile Send private message
cory1492



Joined: 10 Dec 2004
Posts: 216

PostPosted: Fri Oct 23, 2009 10:16 pm    Post subject: Reply with quote

Have you tried different alignment size for your __attribute__ declarations? I see you are aligning to 64 in memalign, but only 16 in __attribute__. Not that it will actually fix the problem, though perhaps one of those is copied from in (for example) u32 but instead assembles to/winds up copying in two u16 chunks making it seem somewhat random from build to build.
Back to top
View user's profile Send private message
Bluddy



Joined: 22 Apr 2007
Posts: 17

PostPosted: Sun Oct 25, 2009 4:03 pm    Post subject: Reply with quote

Cory, it used to be aligned to 16 -- I just raised it to 64 thinking it might fix the problem.

Here's some more info, courtesy of ld's mapfiles and ld scripts among others:

First of all, I can rule out the vsync idea. I tested to see what a forced vsync-less refresh looks like, and it looks nothing like the symptoms I'm experiencing and more like screen tearing.

Now, modifying the program and checking the value of the _end symbol, I find the following pattern:
08b44694 - ok
08b44914 - bad
08b44c94 - good
08b44cd4 - good
08b44d04 - good
08b44e14 - bad
08b44e54 - good
08b44e94 - good

Notice that only a value of _end with a 14 in the end seems to cause a problem. All other values are fine. In case you were wondering, the default loader script forces a 4 byte alignment on the _end symbol.

Playing around some more, I find that moving the following symbols causes the trouble:

Code:

               0x0000000008b43234                finaltest
 .bss           0x0000000008b438f4       0xc0 c:/pspsdk/bin/../lib/gcc/psp/4.3.3\libgcc.a(unwind-dw2.o)
 .bss           0x0000000008b439b4        0xc c:/pspsdk/bin/../lib/gcc/psp/4.3.3\libgcc.a(unwind-dw2-fde.o)
 *(COMMON)
 COMMON         0x0000000008b439c0     0x1000 c:/pspsdk/psp/lib\libc.a(fdman.o)
                0x0000000008b439c0                __psp_descriptormap
 COMMON         0x0000000008b449c0      0x100 c:/pspsdk/psp/lib\libc.a(lib_a-gdtoa-gethex.o)
                0x0000000008b449c0                __hexdig
 COMMON         0x0000000008b44ac0       0x20 c:/pspsdk/psp/lib\libSDL.a(SDL_events.o)
                0x0000000008b44ac0                SDL_ProcessEvents
 COMMON         0x0000000008b44ae0       0x24 c:/pspsdk/psp/lib\libSDL.a(SDL_keyboard.o)
                0x0000000008b44ae0                SDL_KeyRepeat
 COMMON         0x0000000008b44b04       0x20 c:/pspsdk/psp/lib\libGL.a(eglMakeCurrent.o)
                0x0000000008b44b04                __pspgl_context_register
 COMMON         0x0000000008b44b24      0x1f0 c:/pspsdk/psp/sdk/lib\libpspgu.a(guInternal.o)
                0x0000000008b44b24                gu_draw_buffer
                0x0000000008b44b44                gu_object_stack
                0x0000000008b44bc4                gu_contexts
                0x0000000008b44cd8                gu_settings
                0x0000000008b44d14                . = ALIGN (0x4)
                0x0000000008b44d14                . = ALIGN (0x4)
                0x0000000008b44d14                _end = .
                0x0000000008b44d14                PROVIDE (end, .)


Finaltest is the array I'm using to manipulate the locations. Moving _end artificially with loader script commands doesn't seem to change anything, but changing the value of finaltest does. This seems to imply that the culprit is one of the above!

As an aside, you may notice that I have GL tagging along since SDL was built with GL support, though I'm not using SDL for graphics at all. I don't think that's an issue but if anyone thinks otherwise, please let me know.
Back to top
View user's profile Send private message
Jim



Joined: 02 Jul 2005
Posts: 487
Location: Sydney

PostPosted: Sun Oct 25, 2009 8:44 pm    Post subject: Reply with quote

Your problem description sounds like a cache problem. Don't you need to flush the dcache between setting the vertices and passing them to the sce functions?

Jim
_________________
http://www.dbfinteractive.com
Back to top
View user's profile Send private message Visit poster's website
Bluddy



Joined: 22 Apr 2007
Posts: 17

PostPosted: Mon Oct 26, 2009 12:47 am    Post subject: Reply with quote

Quote:

Your problem description sounds like a cache problem. Don't you need to flush the dcache between setting the vertices and passing them to the sce functions?

Jim


I believe that since I get the vertices from sceGuGetMemory, the addresses are in the uncached address space, so there's no need to flush. At least that's the impression I got from perusing the sceGuGetMemory code. I agree that it looks like a cache problem -- I just don't know where the problem is.
Back to top
View user's profile Send private message
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