| View previous topic :: View next topic |
| Author |
Message |
lokust

Joined: 28 May 2006 Posts: 22
|
Posted: Thu Jun 15, 2006 10:12 pm Post subject: Crash When Calling Accessor |
|
|
I have the following acessors in my class, the first set crashes the PSP whenever I call it:
| Code: |
const ScePspFVector2 GetTopLeftUV() const;
const ScePspFVector2 GetBottomRightUV() const;
const ScePspFVector2 CSprite::GetTopLeftUV() const
{
const ScePspFVector2 uv = {m_TexCoords.x, m_TexCoords.y};
return uv;
}
const ScePspFVector2 CSprite::GetBottomRightUV() const
{
const ScePspFVector2 uv = {m_TexCoords.z, m_TexCoords.w};
return uv;
}
|
However this one works ok:
| Code: |
const ScePspFVector4 &GetImageCoords() const { return m_TexCoords; }
|
I am really clueless about whats going on here. I writeback all the data in cache at the beginning of each frame. Is there something else I should be aware of? |
|
| Back to top |
|
 |
PeterM
Joined: 31 Dec 2005 Posts: 125 Location: Edinburgh, UK
|
Posted: Thu Jun 15, 2006 11:03 pm Post subject: |
|
|
| Hmm weird one. Is the 'this' pointer null? |
|
| Back to top |
|
 |
lokust

Joined: 28 May 2006 Posts: 22
|
Posted: Thu Jun 15, 2006 11:38 pm Post subject: |
|
|
| PeterM wrote: | | Hmm weird one. Is the 'this' pointer null? |
Nope, otherwise the second should crash just the same Im pretty sure. |
|
| Back to top |
|
 |
lokust

Joined: 28 May 2006 Posts: 22
|
Posted: Thu Jun 15, 2006 11:45 pm Post subject: |
|
|
And apparently this is becoming an issue with every class I write. Acessors crash. Anyone else writing C++ code for the PSP?
Last edited by lokust on Thu Jun 15, 2006 11:49 pm; edited 1 time in total |
|
| Back to top |
|
 |
PeterM
Joined: 31 Dec 2005 Posts: 125 Location: Edinburgh, UK
|
Posted: Thu Jun 15, 2006 11:46 pm Post subject: |
|
|
| Not if it's just returning a reference, but yes if you dereference that reference. |
|
| Back to top |
|
 |
lokust

Joined: 28 May 2006 Posts: 22
|
Posted: Thu Jun 15, 2006 11:58 pm Post subject: |
|
|
| PeterM wrote: | | Not if it's just returning a reference, but yes if you dereference that reference. |
Its just returning a reference. I have this same problem with this simple acessor in a timer class:
| Code: |
const u32 &GetTickRes() const { return m_iTickRes; }
|
I have tried inlining, not inlining, returning const referece, returning reference, returning value, and making the function non-const. Sometimes I get serious graphical errors, other times the psp just shuts off.
Stumped. |
|
| Back to top |
|
 |
lokust

Joined: 28 May 2006 Posts: 22
|
Posted: Fri Jun 16, 2006 12:06 am Post subject: |
|
|
| It appears sometimes it is if I call the accessor more than once, if I call it once and save the value, then use that _sometimes_ it works. |
|
| Back to top |
|
 |
lokust

Joined: 28 May 2006 Posts: 22
|
Posted: Fri Jun 16, 2006 12:38 am Post subject: |
|
|
Here is my entire render loop:
| Code: |
while(!done)
{
sceKernelDcacheWritebackInvalidateAll();
mySprite->SetTopLeftUV(mySprite->GetImageCoords().x+5.0f,mySprite->GetImageCoords().y);
mySprite->SetBottomRightUV(mySprite->GetImageCoords().z+5.0f,mySprite->GetImageCoords().w);
mySprite->SetPosition(xPos,yPos);
mySprite->Rotate(u*.01);
pspRenderer->BeginDraw();
pspRenderer->ClearScreen();
pspRenderer->Ortho();
sceGuTexImage(0,myImage->iTexWidth,myImage->iTexHeight,myImage->iTexWidth,(void*)myImage->pData);
sceGuTexScale(1.0f/(float)myImage->iTexWidth,1.0f/(float)myImage->iTexHeight);
pspRenderer->DrawSprite(*mySprite);
pspRenderer->EndDraw();
iFrameCount++;
//u32 tickRes = time.GetTickRes();
//u64 elapsedTime = time.GetElapsedTime();
static float fps = 0.0f;
if(time.GetElapsedTime() >= time.GetTickRes())
{
fps = 1.0f / fCurMs;
double span = time.GetElapsedTime() / time.GetTickRes();
fCurMs = span / iFrameCount;
time.Reset();
iFrameCount = 0;
}
pspDebugScreenSetXY(5,5);
printf("%f",fps);
pspRenderer->RenderScene();
}
|
What is interesting is if I change this section here:
| Code: |
iFrameCount++;
//u32 tickRes = time.GetTickRes();
//u64 elapsedTime = time.GetElapsedTime();
static float fps = 0.0f;
if(time.GetElapsedTime() >= time.GetTickRes())
{
fps = 1.0f / fCurMs;
double span = time.GetElapsedTime() / time.GetTickRes();
fCurMs = span / iFrameCount;
time.Reset();
iFrameCount = 0;
}
pspDebugScreenSetXY(5,5);
printf("%f",fps);
pspRenderer->RenderScene();
|
to this:
| Code: |
iFrameCount++;
u32 tickRes = time.GetTickRes();
//u64 elapsedTime = time.GetElapsedTime();
static float fps = 0.0f;
if(time.GetElapsedTime() >= time.GetTickRes())
{
fps = 1.0f / fCurMs;
double span = time.GetElapsedTime() / tickRes;
fCurMs = span / iFrameCount;
time.Reset();
iFrameCount = 0;
}
pspDebugScreenSetXY(5,5);
printf("%f",fps);
pspRenderer->RenderScene();
|
It works, otherwise I get strange graphical error, or the PSP shuts down. Am I handling the cache properly? Should I be writing cache back somewhere? I have tried after the graphics calls (after pspRenderer->RenderScene()), but that didt fix. |
|
| Back to top |
|
 |
Raphael

Joined: 17 Jan 2006 Posts: 646 Location: Germany
|
Posted: Fri Jun 16, 2006 1:58 am Post subject: |
|
|
Just a quick guess: Check for fCurMs and tickRes to be != 0 to get sure. However, tickRes should be a constant, no?
Btw: is GetTickRes() and GetElapsedTime() returning a u32/u64 or float? |
|
| Back to top |
|
 |
lokust

Joined: 28 May 2006 Posts: 22
|
Posted: Fri Jun 16, 2006 2:13 am Post subject: |
|
|
| Raphael wrote: | Just a quick guess: Check for fCurMs and tickRes to be != 0 to get sure. However, tickRes should be a constant, no?
Btw: is GetTickRes() and GetElapsedTime() returning a u32/u64 or float? |
Yes, ideally tickRes would be constant (well, ideally I wouldnt need it at all), however I was playing with return values and such to see what happened. GetElapsedTime returns a float.
My latest attempt seems to work, but I am still not sure why. I create the object on the heap using the new operator. I guess there may not have been enough room on the stack? I also tried declaring it in the global namespace, but that had the same problems. Think I might be missing some detail here.
EDIT: Oh, and the algorithm works, it prints the correct FPS (when it works somewhat) but the image is completely messed up. Sometimes it also just crashes. |
|
| Back to top |
|
 |
Raphael

Joined: 17 Jan 2006 Posts: 646 Location: Germany
|
Posted: Fri Jun 16, 2006 3:30 am Post subject: |
|
|
| lokust wrote: | | Raphael wrote: |
Btw: is GetTickRes() and GetElapsedTime() returning a u32/u64 or float? |
GetElapsedTime returns a float.
|
Well, my guess was that in the one case, where you typecast the GetTickRes to u32, the rounding of a int divide will keep the span and thus the fCurMs from becoming 0, which would cause a crash. But that's idiotic alltogether, since then it should be the other way around (int div rounding down to zero more likely).
In either case, checking for divisors to be non-zero should be done to get on the safe side in every case. |
|
| Back to top |
|
 |
lokust

Joined: 28 May 2006 Posts: 22
|
Posted: Fri Jun 16, 2006 3:49 am Post subject: |
|
|
| Raphael wrote: | | In either case, checking for divisors to be non-zero should be done to get on the safe side in every case. |
Yeah, I suppose I should do that ;) But wouldnt a dbz always crash, and not just produce strange graphical errors? |
|
| Back to top |
|
 |
Raphael

Joined: 17 Jan 2006 Posts: 646 Location: Germany
|
Posted: Fri Jun 16, 2006 4:14 am Post subject: |
|
|
| lokust wrote: |
Yeah, I suppose I should do that ;) But wouldnt a dbz always crash, and not just produce strange graphical errors? |
That's true :) Most graphical issues are cache-related, though I also had one or two cases in which this definitely wasn't the case and only the aproach of completely rewriting some code parts helped.
Allotgether, PSP dev seems to be much more open to random missbehaviour than PC development :) |
|
| Back to top |
|
 |
lokust

Joined: 28 May 2006 Posts: 22
|
Posted: Fri Jun 16, 2006 5:49 am Post subject: |
|
|
| Raphael wrote: | | Allotgether, PSP dev seems to be much more open to random missbehaviour than PC development :) |
So I am learning ;)
Any idea why creating the CTime object on the heap would fix the problem? Maybe dodged some cache mishandling that way? |
|
| Back to top |
|
 |
SSpeare
Joined: 23 May 2006 Posts: 63
|
Posted: Fri Jun 16, 2006 7:10 am Post subject: |
|
|
Getting the proper constructors and such to run for C++ objects that are staticly instantiated can often be a difficulty if the C++ compiler/environment isn't all that great. There is a function that is supposed to do that for you called __ctor or something like that (that name might be way off).
The order of those operations can really be messy, so it's always safer on a less stable toolchain to create things using the heap. It shouldn't be a problem for objects created on the stack at runtime, just those created outside of any function.
From what I've heard and known, C++ development on SONY consoles has not been too favorably looked upon. It works on PS2 today, but the early compilers were C only.
(This is all just conjecture though.... Maybe I shouldn't post it....) |
|
| Back to top |
|
 |
groepaz

Joined: 01 Sep 2005 Posts: 305
|
|
| Back to top |
|
 |
lokust

Joined: 28 May 2006 Posts: 22
|
Posted: Fri Jun 16, 2006 7:23 am Post subject: |
|
|
| SSpeare wrote: | | (This is all just conjecture though.... Maybe I shouldn't post it....) |
No, thank you! That's good info, I will look into it a bit more.
| groepaz wrote: | | problem might be that on fw2.0+ the global constructors dont get called (see eloader docs for details), so you gotta call them manually. |
Also interesting, I am however running 1.5. |
|
| Back to top |
|
 |
dot_blank

Joined: 28 Sep 2005 Posts: 498 Location: Brasil
|
Posted: Fri Jun 16, 2006 12:01 pm Post subject: |
|
|
sceKernelDcacheWritebackInvalidateAll(); should be at end of
drawing loop
also shouldnt this be outside of while loop -> static float fps = 0.0f; _________________ 10011011 00101010 11010111 10001001 10111010 |
|
| Back to top |
|
 |
|