PDA

Voir la version complète : [GBA][Aide] Problèmes de DMA


Brunni
23/04/2006, 12h25
Bonjour tout le monde ^^
Je me rappelle qu'il y a quelques temps il y avait une discussion sur les problèmes de DMA, et quelqu'un disait que c'est même déconseillé par Nintendo.
Bref, impossible de retrouver le topic vu que la recherche à trois lettres retourne rien >_<

Et voilà que justement mon soft (qui fait des milliers de DMA 0/1/2/3 à la seconde :p) plante lorsque je n'attend pas la VSync :(
Les bugs: la palette qui change + blocage complet, ou bien la VRAM (0x6000000) qui foire complètement (on la voit se remplir plusieurs fois avec du n'importe quoi) + blocage, et le son s'arrête net (pas de grésillement).
Par contre, et c'est très dûr à reproduire et très très rare (je n'y suis pas arrivé en désactivant le son par exemple :huh: mais pas non plus en le remettant après <_<). Il se peut aussi que j'ai un buffer overflow quelque part, mais va le retrouver >_<

Donc voilà j'aimerais avoir vos avis et conseils sur les DMA, merci d'avance ^^

Japi
23/04/2006, 21h39
Perso, j'utilise que le DMA3, je m'en sers pas mal mais je charge tjrs en debut de fonction ou bien dans la fonction acitvé sur interruption VBL, j'ai jamais eu de pb avec mais j'ai surement pas tout exploré.

Dr.Vince
24/04/2006, 13h00
c'est Nes qui déconseille l'utilisation de la DMA.

tu pourra peut-être retrouver le topic si tu regarde tout ses messages

Nesgba
24/04/2006, 13h49
Bonjour tout le monde ^^
Je me rappelle qu'il y a quelques temps il y avait une discussion sur les problèmes de DMA, et quelqu'un disait que c'est même déconseillé par Nintendo.
Bref, impossible de retrouver le topic vu que la recherche à trois lettres retourne rien >_<

Et voilà que justement mon soft (qui fait des milliers de DMA 0/1/2/3 à la seconde :p) plante lorsque je n'attend pas la VSync :(
Les bugs: la palette qui change + blocage complet, ou bien la VRAM (0x6000000) qui foire complètement (on la voit se remplir plusieurs fois avec du n'importe quoi) + blocage, et le son s'arrête net (pas de grésillement).
Par contre, et c'est très dûr à reproduire et très très rare (je n'y suis pas arrivé en désactivant le son par exemple :huh: mais pas non plus en le remettant après <_<). Il se peut aussi que j'ai un buffer overflow quelque part, mais va le retrouver >_<

Donc voilà j'aimerais avoir vos avis et conseils sur les DMA, merci d'avance ^^
que veut tu dire par ne pas attendre la vsync ? tu fait appel 2 fois au meme dma avant la vsync ?
esque tu regle bien le mode de transfert en timing immediat ?. meme si c'est le cas le DMA est quand meme source de plantage si tu suit pas les normes de big N (leur methode de copie DMA est vraiment degeu, y'a meme des dma pour copier en 8 bits Oo (sdram ?)).

j'avais deja des plantages aleatoires avec le dma des que j'ai commencé a coder sur gba, ca fait tres longtemp que je m'en passe v_v

Brunni
24/04/2006, 14h23
Merci, j'ai retrouvé, c'est MIKEGBA qui disait que c'est officiellement reconnu par Big N :devil:
Ne pas attendre la VSync c'est simplement qu'au lieu d'attendre la ligne 160 ou le début de la VBlank à chaque frame j'enchaîne direct ;)
Dans ce cas, les DMA peuvent provoquer un crachotement du son ou une VCOUNT ratée, mais ce n'est pas très grave vu que c'est très rare. Par contre si ça crashe, même une fois, là oui c'est grave :p
J'ai essayé de remplacer mes DMA par des memcpy, memset, memmove et compagnie mais c'est ultra lent, et les données ne sont pas copiées correctement en plus.
Je sais pas pourquoi, mais j'ai un pixel sur deux qui est inversé dans le tileset, le même problème que si je fais un DMA 32 bits d'ailleurs, je crois. D'ailleurs si quelqu'un sait pourquoi? :unsure:
Donc à moins que quelqu'un puisse me dire comment faire une copie ultra rapide (mais alors vraiment ultra rapide) en gardant le même format qu'une copie DMA 16 bits, je vais être obligé de garder les DMA :(

Nesgba
24/04/2006, 14h29
desolé c'est tres loin d'un dma mais ca doit etre plus rapide qu'un memset (a tester)
/*################################################# #################################################
## Def : copie en 16 ou 32 bits
################################################## ################################################*/
void IRIS_IN_IWRAM CopieDo16(short *src,short *dst,unsigned short taille){
do { *(dst++) = *(src++) ;} while (--taille) ;}
void IRIS_IN_IWRAM CopieDo32(int *src,int *dst,unsigned int taille){
do { *(dst++) = *(src++) ;} while (--taille) ;}

/*################################################# #################################################
## Def : met tout a 0, en 16 ou 32 bits
################################################## ################################################*/
void IRIS_IN_IWRAM VideDo16(short *src, unsigned short taille){
do { *(src++) = 0 ;} while (--taille) ;}
void IRIS_IN_IWRAM VideDo32(int *src, unsigned int taille){
do { *(src++) = 0 ;} while (--taille) ;}

a part cibler tes copies et deboucler en consequance (en asm de preferance) tu peut pas faire mieu que ca AMHA

[edit] tien je vient de remarquer, on pourrai les deboucler celles la on gagnerai un peu

Japi
24/04/2006, 14h44
stmia ^^^^^^^^^^^^ private joke inside

Brunni
24/04/2006, 15h06
Merci nes, mais désolé c'est loin d'être assez rapide, même en débouclant :(
Japi> Intéressant stmia. Ca peut faire ce dont j'ai besoin (c'est à dire pas d'inversion)? Désolé j'y connais (quasi) rien en ASM et je peux pas tester là :-'

Nesgba
24/04/2006, 18h41
tu sais tres bien que sur ce forum il y a un seul codeur asm capable d'optimiser mieu qu'un compillo, donc va lui demander en personne au lieu d'ouvrir un topic. v_v

[edit]voila quand meme la version debouclée (pour ceux que ca interesse, le VideDo32 gagne enormement en vitesse c'est impressionant !! le CopieDo32 est amelioré aussi)

/*################################################# #################################################
## Def : copie en 16 bits(diviser la valeur par 2) ou 32 bits(diviser la valeur par 4)
## la taille des valeurs doit etre multiple de 2(16 bits) ou 4(32bits)
################################################## ################################################*/
void IRIS_IN_IWRAM CopieDo16(short *src, short *dst, unsigned short taille){
do {
*(dst) = *(src) ;
*(dst+1) = *(src+1) ;
src+=2 ;
dst+=2 ;
} while (--taille) ;
}

void IRIS_IN_IWRAM CopieDo32(int *src, int *dst, unsigned int taille){
do {
*(dst) = *(src) ;
*(dst+1) = *(src+1) ;
*(dst+2) = *(src+2) ;
*(dst+3) = *(src+3) ;
src+=4 ;
dst+=4 ;
} while (--taille) ;
}

/*################################################# #################################################
## Def : efface en 16 bits(diviser la valeur par 2) ou 32 bits(diviser la valeur par 4)
## la taille des valeurs doit etre multiple de 2(16 bits) ou 4(32bits)
################################################## ################################################*/
void IRIS_IN_IWRAM VideDo16(short *dst, unsigned short taille){
do {
*(dst) = 0 ;
*(dst+1) = 0 ;
dst+=2 ;
} while (--taille) ;
}

void IRIS_IN_IWRAM VideDo32(int *dst, unsigned int taille){
do {
*(dst) = 0 ;
*(dst+1) = 0 ;
*(dst+2) = 0 ;
*(dst+3) = 0 ;
dst+=4 ;
} while (--taille) ;
}

Japi
24/04/2006, 19h33
je crois bien que Nes a raison et m^me si j'essaye un peu de m'y mettre, je ne rivaliserais jamais avec ce grand maitre de l'asm.

Autant, ya surement une solution à ce soucis de DMA.

Brunni
24/04/2006, 21h20
tu sais tres bien que sur ce forum il y a un seul codeur asm capable d'optimiser mieu qu'un compillo, donc va lui demander en personne au lieu d'ouvrir un topic. v_v
Hé ben... c'est sympa :o
Le but du topic c'est de discuter de votre avis et vos expériences avec les DMA, j'ai pas demandé "MIKEGBA ponds-moi une routine de copie ASM optimisée" :p
Autant, ya surement une solution à ce soucis de DMA.Oui, mais je vais essayer de remplacer par la routine de nes (merci au passage) au moins déjà pour voir si ça plante toujours avec ça, mais le problème c'est que le bug peut arriver une fois toutes les 3 semaines, comme il peut arriver deux fois en une heure, donc pour s'assurer que le bug a bien disparu... :(

Nesgba
24/04/2006, 21h52
je disai pas ca mechament mais c'est ta phrase qui m'a fait percuter
Donc à moins que quelqu'un puisse me dire comment faire une copie ultra rapide (mais alors vraiment ultra rapide) en gardant le même format qu'une copie DMA 16 bits, je vais être obligé de garder les DMA
le probleme c'est que tu connais parfaitement la reponse, le plus rapide sera un copie optimisée en asm mais elle sera vraiment a peine plus rapide que ma fonction.
la ou tu gagnera le + en asm c'est en debouclant completement des suites de données continues. c'est pas sur 4 pixels que tu va gagner grand chose ...

par exemple pour copier un tile en c completement debouclé:
/*################################################# #################################################
## Def : copie de tiles opaques completement debouclés
################################################## ################################################*/
void IRIS_IN_IWRAM PlotTile16x16_8bits(unsigned short *src, signed short x, signed short y)
{
unsigned int *Dest = &IRIS_BufferVideoActuel[((y<<7)-(y<<3))+(x>>1)] ; // [y*120+x/2]
unsigned int *Orig = &src[0] ;

// debouclée
Orig-=4 ; Dest-=60 ;
*(Dest+=60) = *(Orig+=4); *(Dest+1) = *(Orig+1); *(Dest+2) = *(Orig+2); *(Dest+3) = *(Orig+3);
*(Dest+=60) = *(Orig+=4); *(Dest+1) = *(Orig+1); *(Dest+2) = *(Orig+2); *(Dest+3) = *(Orig+3);
*(Dest+=60) = *(Orig+=4); *(Dest+1) = *(Orig+1 ; *(Dest+2) = *(Orig+2); *(Dest+3) = *(Orig+3);
*(Dest+=60) = *(Orig+=4); *(Dest+1) = *(Orig+1); *(Dest+2) = *(Orig+2); *(Dest+3) = *(Orig+3);
*(Dest+=60) = *(Orig+=4); *(Dest+1) = *(Orig+1); *(Dest+2) = *(Orig+2); *(Dest+3) = *(Orig+3);
*(Dest+=60) = *(Orig+=4); *(Dest+1) = *(Orig+1); *(Dest+2) = *(Orig+2); *(Dest+3) = *(Orig+3);
*(Dest+=60) = *(Orig+=4); *(Dest+1) = *(Orig+1); *(Dest+2) = *(Orig+2); *(Dest+3) = *(Orig+3);
*(Dest+=60) = *(Orig+=4); *(Dest+1) = *(Orig+1); *(Dest+2) = *(Orig+2 ; *(Dest+3) = *(Orig+3);
*(Dest+=60) = *(Orig+=4); *(Dest+1) = *(Orig+1); *(Dest+2) = *(Orig+2); *(Dest+3) = *(Orig+3);
*(Dest+=60) = *(Orig+=4); *(Dest+1) = *(Orig+1); *(Dest+2) = *(Orig+2); *(Dest+3) = *(Orig+3);
*(Dest+=60) = *(Orig+=4); *(Dest+1) = *(Orig+1); *(Dest+2) = *(Orig+2); *(Dest+3) = *(Orig+3);
*(Dest+=60) = *(Orig+=4); *(Dest+1) = *(Orig+1 ; *(Dest+2) = *(Orig+2); *(Dest+3) = *(Orig+3);
*(Dest+=60) = *(Orig+=4); *(Dest+1) = *(Orig+1); *(Dest+2) = *(Orig+2); *(Dest+3) = *(Orig+3);
*(Dest+=60) = *(Orig+=4); *(Dest+1) = *(Orig+1); *(Dest+2) = *(Orig+2); *(Dest+3) = *(Orig+3);
*(Dest+=60) = *(Orig+=4); *(Dest+1) = *(Orig+1); *(Dest+2) = *(Orig+2); *(Dest+3) = *(Orig+3);
*(Dest+=60) = *(Orig+=4); *(Dest+1) = *(Orig+1); *(Dest+2) = *(Orig+2); *(Dest+3) = *(Orig+3);
}

ca en c tu peut pas optimiser d'avantage, mais en asm des suites comme ca tu te regale. enfin c'est qu'un exemple parmis tant d'autres mais tout ca tu le sais et c'est ce que je te reproche. :hum:

concernant le dma tout est ecrit noir sur blanc dans la doc de nintendo. (je sais pas si tu l'a en ta possession mais ca fait longtemp qu'elle tourne sur le net (ne nous cachons pas derriere notre petit doigt je l'ai pas eu officielement))

:)

Brunni
24/04/2006, 22h58
Bon déjà j'avais pas la doc officielle (qqn vient de me la filer à l'instant :D).
enfin c'est qu'un exemple parmis tant d'autres mais tout ca tu le sais et c'est ce que je te reproche. :hum:
:blink:
Je peux pas savoir hein, et honnêtement je pensais que Japi et toi en faisiez par exemple :huh:
En plus aller demander directement à Mike c'est bien mais ça profite à personne d'autre qu'à moi donc bon je comprends pas trop :-*
Ca t'es jamais arrivé de tomber sur un forum où tu vois une question qui est parfaitement celle que tu te poses (surtout que les DMA / copies ASM c'est un sujet assez global à mon avis), mais manque de bol y'a pas de réponse parce qu'ils se la sont donnée en privé, ou alors juste "ok, problème résolu". Quel est l'intérêt d'un forum à ce moment là? :S

Bref, maintenant je vais aller voir dans la doc Nintendo, merci quand même ^^

Japi
24/04/2006, 23h09
moi ce que j'en sais, mais quon me corrige si je fais fausse route, c'est que les DMA sont pas interdits par nintendo puisque sinon, ils auraient pas mis la puce de DMA dans la console.
Apres, il faut juste l'utiliser au bon moment et dans des parties du code où ça gene pas et pour pas que ça chie avec le reste, j'utilise que la 3.

xflash
24/04/2006, 23h39
Salut à tous,


Bon je me permets de poser un petit message sur ce topic que j'ai vu en passant et qui m'a mis la puce à l'oreille.
J'avais déja rencontré ce problème auparavant Brunni, lors de copie DMA3 successives. Des problemes assez bizarres et absolument pas systématiques.
Après avoir relu un peu mon code, je me souviens de plusieurs choses:
-Essayes les différents modes des bits 13 et 12 de DMA3CNT_H. Cela modifie les valeurs de quand le transfert demarre effectivement.
-Essayes d'attendre un peu (moi j'attends jusqu'a Vcount==162), après une copie avant de remanipuler les registres DMA, au moins d'attendre que le flag enable passe a 0, signe que la copie est finie.

Voila en esperant que cela t'aide.

En passant, Salut a tous les anciens et les nouveaux que je connais moins :)

xF

Nrx
24/04/2006, 23h53
Content de te revoir ici xflash :)

Nesgba
24/04/2006, 23h56
ah ben j'ai bien fait de tapper sur brunni ^^ bon retour xflash !! B)

xflash
25/04/2006, 00h07
Oh je suis toujours par ci, par la, mais beaucoup de choses dans ma vie professionnelle m'ont un peu éloigné du dev GBA/NDS, sans pour autant le lacher completement :)
Bon c'est pas un vrai retour hein, :) mais quand je vois des gens dans les memes ennuis que j'ai pu rencontrer a l'epoque , je n'ai pu m'empecher de laisser un chti message.

xf