I use a Perforce server for maintaining my source code and it was a lifesaver. Over the last few weeks, I've been making extensive upgrades to Burgerlib, inserting hand tuned assembly here and there and general clean up. I had several unit tests to verify my work and it's been working out great.
Until last Wednesday...
I ran numerous tests on the game Aliens vs. Predator to make sure that nothing was broken and it was running flawlessly. So I switched over to the Mac PowerPC version and ran it and to my horror, I found the 3D rendering engine was drawing all the textures black. A quick look at the source history showed me that I had made hundreds of changes to the code and finding out why the gamma tables were all screwed up was going to be a nightmare.
Then Perforce came to the rescue. I did a "revert" and went back in time, grabbing a source tree revision, rebuilding and testing until I found that it was a change made about 6 weeks ago that broke AvP MacOS PowerPC. With the possible suspects narrowed down, I quickly traced it to an inline assembly gotcha that happens with the Metrowerks CodeWarrior compiler for PowerPC. Shortly, I found that my Wii version also suffered from the compiler "glitch".
Here's the errorneous code...
static Int32 BURGER_INLINE FromFloatFloor(register float fInput)
{
Int32 iResult;
fInput = fInput-0.5f;
register Int32 *pResult = &iResult;
asm { fctiw fInput,fInput; stfiwx fInput,r0,pResult }
return iResult;
}
In a controlled unit test, this code generated the assembly I was expecting, but in a gamma table creation function in Aliens Vs. Predator, the "return iResult" operation was optimized out and as such, it was filling the table with whatever was in register r3 at the time (In this case, it was always zero). Gamma = 0 means textures are all black.
The fix was to force the compiler to never get rid of iResult and here's where "volatile" has its uses.
static Int32 BURGER_INLINE FromFloatFloor(register float fInput)
{
volatile Int32 iResult;
fInput = fInput-0.5f;
register volatile Int32 *pResult = &iResult;
asm { fctiw fInput,fInput; stfiwx fInput,r0,pResult }
return iResult;
}
Adding the keyword fixed the code and I double check the Wii compiler and it solved the issue there too.
Lesson learned... No matter how many safeguards you put in your development process, something always gets through. Being able to "go back in time" through source reversion saved me hours, even days, of crazy coding detective work.
Until last Wednesday...
I ran numerous tests on the game Aliens vs. Predator to make sure that nothing was broken and it was running flawlessly. So I switched over to the Mac PowerPC version and ran it and to my horror, I found the 3D rendering engine was drawing all the textures black. A quick look at the source history showed me that I had made hundreds of changes to the code and finding out why the gamma tables were all screwed up was going to be a nightmare.
Then Perforce came to the rescue. I did a "revert" and went back in time, grabbing a source tree revision, rebuilding and testing until I found that it was a change made about 6 weeks ago that broke AvP MacOS PowerPC. With the possible suspects narrowed down, I quickly traced it to an inline assembly gotcha that happens with the Metrowerks CodeWarrior compiler for PowerPC. Shortly, I found that my Wii version also suffered from the compiler "glitch".
Here's the errorneous code...
static Int32 BURGER_INLINE FromFloatFloor(register float fInput)
{
Int32 iResult;
fInput = fInput-0.5f;
register Int32 *pResult = &iResult;
asm { fctiw fInput,fInput; stfiwx fInput,r0,pResult }
return iResult;
}
In a controlled unit test, this code generated the assembly I was expecting, but in a gamma table creation function in Aliens Vs. Predator, the "return iResult" operation was optimized out and as such, it was filling the table with whatever was in register r3 at the time (In this case, it was always zero). Gamma = 0 means textures are all black.
The fix was to force the compiler to never get rid of iResult and here's where "volatile" has its uses.
static Int32 BURGER_INLINE FromFloatFloor(register float fInput)
{
volatile Int32 iResult;
fInput = fInput-0.5f;
register volatile Int32 *pResult = &iResult;
asm { fctiw fInput,fInput; stfiwx fInput,r0,pResult }
return iResult;
}
Adding the keyword fixed the code and I double check the Wii compiler and it solved the issue there too.
Lesson learned... No matter how many safeguards you put in your development process, something always gets through. Being able to "go back in time" through source reversion saved me hours, even days, of crazy coding detective work.
- Mood:geeky
- Music:Hare Hare Yukai-Hirano Aya & Chihara Minori &-Hare Hare Yukai


Comments