Page 1 of 1

Optimal DMA chain length?

Posted: Wed Oct 12, 2005 12:04 am
by cheriff
Right now i'm sending my model data to vu1 in 'chunks', each chunk is 1or more vif1 UNPACKS (upto 4 since each chunk may have upto 1010 qwords fo data and there is a 255 qwords limit on the length of a ref dma tag), then a
MSCALF to get the vu to transform and kick the tirangles.

Now this works fine if I loop over the model inside the render function and construct one UNPACK, MSCALF dma chain per chunk, my largest model is 15k tris, and that displays fine.

However, i'd rather generate a massive dma chain at loadtime and simple kick it on a per frame basis, to save looping over each chunkall the time. This seems to transfer all the data ok, but i think the timing is off since there seems to be a line across the tv, above which nothing is drawn. the more complex the model the lower this cutoff is. It reminds me of when you have too many printfs running and it is slightly lagging behind (or just in front of) the vertical retrace or something..

I tried a few combinations of various flush's before both the MSCALF and the UNPACK but no difference. This should be faster, but just doesnt seem to be fast enough?

Code: Select all

void draw(){
	
	for each chunk{
               packet_reset(packet);		
		

		while(more data in this chunk){
                /* a chunk is a vumem-full of data, but can only fit 255 qwords within
                 * a dma ref tag. hence subchunks for transfer
                 */
			packet_append_64(packet, DMA_SET_TAG(1, 0, DMA_TAG_CNT, 0, 0, 0));
			packet_append_64(packet, 0x0000000000000000);
			
			packet_append_32(packet, VIF_NOP);
			packet_append_32(packet, VIF_NOP);
			packet_append_32(packet, VIF1_FLUSHA);
			packet_append_32(packet, VIF_UNPACK_V4_32(subchunk_size, subchunk_vuoffset);
		
			packet_append_64(packet, DMA_SET_TAG(subchunk_size, 0, DMA_TAG_REF, 0, subchunk_addr, 0));
			packet_append_64(packet, 0x0000000000000000);
			
		}	

		if(this chunk requires vu1 code to be run on it){
                /* Some don't eg those that just load materials and no geometry */
			packet_append_64(packet, DMA_SET_TAG(1, 0, DMA_TAG_CNT, 0, 0, 0));
			packet_append_64(packet, 0x0000000000000000);
		
			packet_append_32(packet, VIF_NOP);
			packet_append_32(packet, VIF_NOP);
			packet_append_32(packet, VIF1_FLUSHA);
			packet_append_32(packet, VIF1_MSCALF(0));
		}	
		

		packet_append_64(packet, DMA_SET_TAG(0, 0, DMA_TAG_END, 0, 0, 0));
		packet_append_64(packet, 0x0000000000000000);
		
		FlushCache(2);
		FlushCache(0);		
	/* Now send this chunk-in-a-packet! */
		dma_channel_wait(DMA_CHANNEL_VIF1, 0, DMA_FLAG_CHAIN);	
		packet_send(packet, DMA_CHANNEL_VIF1, DMA_FLAG_CHAIN);	

	}

}
this works nicely but when moving the packet reset before the outer loop, and the dma terminate/flush/packet send to just after it i get the artifacts previously described..

gurus?

Posted: Wed Oct 12, 2005 12:12 am
by ooPo
Possibly unrelated, but I got the same kind of artifact when I was trying to get the teapot sample to draw more than one teapot onscreen at once. I think it had something to do with the wait functions not working properly but I didn't entirely figure it out.