 |
forums.ps2dev.org Homebrew PS2, PSP & PS3 Development Discussions
|
| View previous topic :: View next topic |
| Author |
Message |
Bluddy
Joined: 22 Apr 2007 Posts: 17
|
Posted: Mon Oct 19, 2009 6:09 pm Post subject: Flicker problem driving me crazy! |
|
|
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 |
|
 |
Bluddy
Joined: 22 Apr 2007 Posts: 17
|
Posted: Wed Oct 21, 2009 5:22 pm Post subject: |
|
|
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 |
|
 |
J.F.
Joined: 22 Feb 2004 Posts: 2906
|
Posted: Thu Oct 22, 2009 12:44 pm Post subject: |
|
|
Well, you could edit the post and put it in code tags. :)
Try flipping these two lines around
| Code: | sceDisplayWaitVblankStart();
sceGuSwapBuffers(); |
|
|
| Back to top |
|
 |
Bluddy
Joined: 22 Apr 2007 Posts: 17
|
Posted: Fri Oct 23, 2009 7:17 pm Post subject: |
|
|
| Tried swapping the lines. It didn't work, but thanks for the idea. |
|
| Back to top |
|
 |
cory1492
Joined: 10 Dec 2004 Posts: 216
|
Posted: Fri Oct 23, 2009 10:16 pm Post subject: |
|
|
| 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 |
|
 |
Bluddy
Joined: 22 Apr 2007 Posts: 17
|
Posted: Sun Oct 25, 2009 4:03 pm Post subject: |
|
|
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 |
|
 |
Jim

Joined: 02 Jul 2005 Posts: 487 Location: Sydney
|
Posted: Sun Oct 25, 2009 8:44 pm Post subject: |
|
|
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 |
|
 |
Bluddy
Joined: 22 Apr 2007 Posts: 17
|
Posted: Mon Oct 26, 2009 12:47 am Post subject: |
|
|
| 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 |
|
 |
|
|
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
|