gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > Odd quad rendering behavior

#116446 - NeX - Thu Jan 25, 2007 9:02 pm

This works in an emulator; on hardware nothing appears.
The array TRACKMESH is a v16 array; nothing unusual there. In Dualis, the track displays perfectly. If I set the first vertex to a fixed position, the DS draws a single line across the screen - like one of the quads is stick thin. It is no where near as messed up in Dualis... it just does exactly what I expect it to.
Code:

      //draw the obj
      glBegin(GL_QUAD_STRIP);
         u8 i=0;
         while(i<22)
         {
            glColor3b(255,0,0);
            glVertex3v16(trackmesh[i][0][0],trackmesh[i][0][1],trackmesh[i][0][2]);

            glColor3b(0,255,0);
            glVertex3v16(trackmesh[i][1][0],trackmesh[i][1][1],trackmesh[i][1][2]);
         i++;
         }


      glEnd();


I could check the array with a console output, but there is unfortunately no v16tofloat command, so all I get is jibberish.

#116451 - simonjhall - Thu Jan 25, 2007 9:49 pm

As a v16 is a 4.12 format number, if you want it in floating-point format I'd just divide it by 4096. If you just shift it left by 12 bits you'll only get the whole number part.
So,
Code:
v16 anus;
...
float number = (float)anus / 4096.
Cha'mone.

Dunno about the rendering problem however...
_________________
Big thanks to everyone who donated for Quake2

#116461 - Rajveer - Thu Jan 25, 2007 11:18 pm

Just to make sure, I had a problem where models were a scanline thick on the ds and perfect on dualis (or ideas, i forget) and its when I first got into programming on the DS where I didnt use fixed point values (i.e. 4096 instead of 1) with those commands.

#116554 - NeX - Fri Jan 26, 2007 8:33 pm

Hmm... I noticed a red dot, and realized it was the track being compressed into one point. So I made it console display the exact data being turned into the track (signed 8 bit accuracy). Guess what. It's all zero. But it's right on Dualis...

I'm using this to shift the data into the array-
Code:

   u8 track[1024];

      const void *track_raw = gbfs_get_obj(&data_gbfs, "ttrack.dsm", NULL);    
         DC_FlushAll();
         
      dmaCopy(track_raw, (void*)track, 200);
         DC_FlushAll();

Is dmaCopy a good idea to use in this situation? And what does the DC_FlushAll() do? All my other instances of dmaCopy fail without it.

#116572 - simonjhall - Sat Jan 27, 2007 12:10 am

Ah ha! I don't know the specifics of this dmaCopy function, but if it's non-blocking then that could be the cause of your problem. Try just doing a regular memcpy first to see if you still get problems.

The DC_FlushAll tells the ARM9's MPU co-pro to flush the CPU's data cache to memory. I doubt the MPU waits for pending DMAs to finish before doing this.

Also (again, don't know DS specifics), but other platforms I've worked with require the source and destination addresses to be aligned to 'good' values (eg 16 bytes) and the transfer size to be a multiple of some nice size (eg 16 bytes). Again, try memcpy. You shouldn't need a cache flush with that and you won't need aligned addresses.

The reason it may work on an emulator is that DMAs can often be coded as just plain DMAs - ie instant. This isn't the case on real hardware...
_________________
Big thanks to everyone who donated for Quake2

#116714 - NeX - Sun Jan 28, 2007 8:17 pm

Thanks! I wouldn't have figured this out on my own. Bad DMAcopy!

#116715 - tepples - Sun Jan 28, 2007 8:20 pm

simonjhall wrote:
Also (again, don't know DS specifics), but other platforms I've worked with require the source and destination addresses to be aligned to 'good' values (eg 16 bytes) and the transfer size to be a multiple of some nice size (eg 16 bytes).

DMAs on at least Game Boy Advance use 4-byte alignment.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#116761 - wintermute - Mon Jan 29, 2007 5:02 am

NeX wrote:

Is dmaCopy a good idea to use in this situation? And what does the DC_FlushAll() do? All my other instances of dmaCopy fail without it.


DC_FlushAll() flushes all pending writes in the data cache to memory and is a bit overkill. DC_FlushRange( base address, size ) should be used in preference.

The cache requires flushing when you wish to DMA from a region of memory which has been manipulated by the CPU.

You should use DC_InvalidateRange( base address, size ) when you wish the CPU to manipulate a region of memory which has been changed by DMAing to it.

tepples wrote:

DMAs on at least Game Boy Advance use 4-byte alignment.


Unless they're 16bit DMAs in which case it's 2 byte alignment.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog