Les membres ayant 30 points peuvent parler sur les canaux annonces, projets et hs du chat.
La shoutbox n'est pas chargée par défaut pour des raisons de performances. Cliquez pour charger.

Forum Casio - Vos tutoriels et astuces


Index du Forum » Vos tutoriels et astuces » [Prizm] - Rafraichissement de l'écran
Nemhardy Hors ligne Grand maître des Traits d'Esprit Points: 1242 Défis: 54 Message

[Prizm] - Rafraichissement de l'écran

Posté le 16/04/2014 18:50

Un petit post pour vous exposer pour l'instant quelques réflexions et pistes de recherche par rapport au rafraichissement de l'écran sur Prizm, qui est un des facteurs rendant l’exécution de programmes "lente". Rien de bien concret pour l'instant, mais je partage juste des idées/explications pour avoir des éventuels retours.

Il y a quelques temps, avec Lancelot, nous avions discuté de la faisabilité d'une fonction équivalente à Bdisp_PutDisp_DD() (ou la fonction permettant de transférer le contenu de la VRAM à l'écran et donc de l'afficher). Le "truc" c'est que la quantité d'informations à envoyer à l'écran est assez énorme : la VRAM est un buffer de 165ko environ (au passage plus que ce qu'un malloc peut allouer comme espace ). Le syscall évoqué plus haut pratique donc une copie en utilisant le principe de DMA, soit un accès direct à la mémoire. Cela permet de "décharger" le processeur qui ne s'occupe que de lancer le transfert (et éventuellement de contrôler le bon déroulement de celui-ci). Cependant, ce syscall est en quelque sorte bloquant, c'est à dire que tant que le transfert n'est pas terminé, et bien, le programme est en pause. Ce n'est pas une ineptie totale de Casio, mais quelque chose d'assez logique/sécuritaire car il serait fâcheux de ré-entrer dans des fonctions de dessin qui modifieraient le contenu de la VRAM avant même que celle-ci ait fini d'être transférée, ou même de relancer un transfert alors qu'un autre est déjà en cours... Cela peut néanmoins s'avérer gênant car le temps de transfert est assez conséquent.

ProgrammerNerd, auteur notamment du port d'Open JackRabbit ou du lecteur Mpeg2 que vous pouvez voir dans cette news, a développé une fonction permettant de résoudre quelque-peu ce problème. Il a écrit un "set" de fonctions (qui est d'ailleurs une sorte de "traduction" en C de la fonction en ASM que l'on peut voir dans la doc de SimLo, donc plus simple à mettre en place) qui se décompose en deux fonctions : l'une permettant simplement de lancer le transfert, et l'autre permettant de bloquer le programme en attendant la fin du transfert. Le transfert n'est donc théoriquement pas plus rapide, car utilisant la même unité de DMA, mais... enfin, j'explique ça dans la suite.

Je vous mets ici le code tel qu'il est dans le lecteur Mpeg2

[green]// Module Stop Register 0[/green]
[brown]#define MSTPCR0 (volatile unsigned *)0xA4150030[/brown]
[green]// DMA0 operation register[/green]
[brown]#define DMA0_DMAOR (volatile unsigned short*)0xFE008060[/brown]
[brown]#define DMA0_SAR_0 (volatile unsigned *)0xFE008020[/brown]
[brown]#define DMA0_DAR_0 (volatile unsigned *)0xFE008024[/brown]
[brown]#define DMA0_TCR_0 (volatile unsigned *)0xFE008028[/brown]
[brown]#define DMA0_CHCR_0 (volatile unsigned *)0xFE00802C[/brown]
/* DMA register offsets
destination address register_0*/
[green]//[brown]#define DAR_0 0x04[/brown][/green]
[green]// transfer count register_0[/green]
[green]//[brown]#define TCR_0 0x08[/brown][/green]
[green]// channel control register_0[/green]
[green]//[brown]#define CHCR_0 0x0C[/brown][/green]
[brown]#define LCD_BASE 0xB4000000[/brown]
[brown]#define VRAM_ADDR 0xA8000000[/brown]
[brown]#define SYNCO() __asm__ volatile([gray]"SYNCO\n\t":::"memory"[/gray]);[/brown]
[brown]#define PRDR *(volatile unsigned char*)0xA405013C[/brown]
[brown]#define LCDC *(volatile unsigned short*)0xB4000000[/brown]

[brown]#define LCD_GRAM_X 0x200[/brown]
[brown]#define LCD_GRAM_Y 0x201[/brown]
[brown]#define LCD_GRAM 0x202[/brown]
[brown]#define LCD_WINDOW_LEFT 0x210[/brown]
[brown]#define LCD_WINDOW_RIGHT 0x211[/brown]
[brown]#define LCD_WINDOW_TOP 0x212[/brown]
[brown]#define LCD_WINDOW_BOTTOM 0x213[/brown]

void DmaWaitNext(void)
{
    [b][blue]while[/blue][/b](1){
    [b][blue]if[/blue][/b]((*DMA0_DMAOR)&4)[green]//Address error has occured stop looping[/green]
    [b][blue]break[/blue][/b];
    [b][blue]if[/blue][/b]((*DMA0_CHCR_0)&2)[green]//Transfer is done[/green]
    [b][blue]break[/blue][/b];
    }
    SYNCO();
    *DMA0_CHCR_0&=~1;
    *DMA0_DMAOR=[maroon]0[/maroon];
}
void DoDMAlcdNonblock(void)
{
    Bdisp_WriteDDRegister3_bit7(1);
    Bdisp_DefineDMARange(6,[maroon]389[/maroon],[maroon]0[/maroon],[maroon]215[/maroon]);
    Bdisp_DDRegisterSelect(LCD_GRAM);

    *MSTPCR0&=~(1<<21);[green]//Clear bit 21[/green]
    *DMA0_CHCR_0&=~1;[green]//Disable DMA on channel 0[/green]
    *DMA0_DMAOR=[maroon]0[/maroon];[green]//Disable all DMA[/green]
    *DMA0_SAR_0=VRAM_ADDR&0x1FFFFFFF;[green]//Source address is VRAM[/green]
    *DMA0_DAR_0=LCD_BASE&0x1FFFFFFF;[green]//Desination is LCD[/green]
    *DMA0_TCR_0=(216*384)/16;[green]//Transfer count bytes/32[/green]
    *DMA0_CHCR_0=[maroon]0[/maroon]x00101400;
    *DMA0_DMAOR|=[maroon]1[/maroon];[green]//Enable DMA on all channels[/green]
    *DMA0_DMAOR&=~6;[green]//Clear flags[/green]
    *DMA0_CHCR_0|=[maroon]1[/maroon];[green]//Enable channel0 DMA[/green]
}


C'est pas très joli je vous l'accorde (en mettant en parallèle avec la doc de SimLo et les commentaires, on arrive à comprendre quelques trucs, mais après, le principe est juste de lancer un transfert, donc rien de bien passionnant). Quoi qu'il en soit, la fonction DoDMAlcdNonblock(); permet de lancer le transfert et DmaWaitNext() comme son nom l'indique permet de "bloquer" le programme jusqu'à la fin du transfert précédent.

Présentée comme ça, la fonction n'est pas très intéressante, car elle se base uniquement sur la VRAM et oblige donc à attendre la fin du transfert précédent pour pouvoir dessiner dedans. Néanmoins, on voit clairement que l’adresse de la VRAM est juste mise dans un registre comme adresse de source pour la copie : il me semble donc envisageable d'utiliser 2 buffers et de les copier en alternance : ainsi, l'un est en train d'être copié tandis que l'autre est en train d'être remplis. Le soucis majeur serait la taille de ce buffer relativement conséquente, mais il faut savoir qu'il existe une zone de la mémoire destinée à contenir la copie de la VRAM (donc de même taille que cette dernière) crée suite à l'appel de SaveVRAM_1() qui est potentiellement exploitable (j’attends une réponse sur Cemetech pour en savoir plus et confirmer/infirmer la chose). Cela aurait quelques inconvénients (comme le fait de devoir travailler en (char*) et non plus en (short*), l'adresse 0 de la zone étant impaire) mais je pense que le potentiel semblant de "multithreading" (on copie d'un côté et dessine de l'autre) peut être assez "rentable" pour faire abstraction de ces défauts.

On peut envisager un programme fonctionnant ainsi :

while(jeu) {
    calcul()
    dessin()
    DmaWaitNext()
    DoDMAlcdNonblock()
}


Où les adresses des buffers vidéos utilisées dans la fonction de dessin et de rafraichissement seront alternativement échangées : calcul() et dessin() seront donc potentiellement appelée alors que le transfert est toujours en cours, ce qui n'est pas possible avec le syscall de base !
Le DmaWaitNext() reste important car empêchant les transferts de se chevaucher .

Une autre piste que l'on peut envisager est le fait de pouvoir restreindre la zone de la VRAM à copier pour, par exemple, dans le cadre d'un RPG, actualiser uniquement les zones qui doivent être actualisées (mouvement des persos) et ne pas toucher au décor par exemple (je n'ai pas fait de tests à ce niveau là, donc plus hypothétique peut être), ce qui aurait, je pense le mérite d’accélérer à nouveau les transferts.





1, 2 Suivante
Lancelot Hors ligne Membre Points: 1274 Défis: 160 Message

Citer : Posté le 16/04/2014 19:08 | #


Sympa et vraiment bien !

ça a l'air prometteur ! Je teste durant cette fin de semaine.

Il y a t'il de grosses différences ?
Calculatrices : Casio 35+ SH4 (modifiée 75) et fx-CG 20 PRIZM
Projets que je soutiens
Des exemples parmi tant d'autres
Pokémon Jade de Dododormeur
Zelda de Smashmaster
Super Geek Brothers de Siapran
Mes Programmes
Mes Programmes
Mes Projets
Mes Projets
ColorLib
Add-ins Jetpack Joyride et Pac-Man sur PRIZM (les 2 non commencés mais en réflexion)
A la recherche des sprites jetpack Joride si quelqu'un les a en couleur
Nemhardy Hors ligne Grand maître des Traits d'Esprit Points: 1242 Défis: 54 Message

Citer : Posté le 16/04/2014 19:16 | #


A vrai dire, si tu utilises la fonction que j'ai donné comme telle, je doute que l'on constate grand chose, car tout ce qu'elle fait c'est lancer le transfert de la VRAM vers l'écran, tu es donc obligé d'attendre la fin du transfert. Ensuite j'ai pas encore fais trop de tests (j'y ai surtout réfléchi dans le bus ce matin ), mais je pense qu'en passant à un double buffering, on devrait voir des différences (je vais tester ça dans la soirée ). Pour l'instant, c'est pas très concret comme je l'ai dis, j'exposais juste ce que j'en avais retiré, mais il y a peut-être des bêtises vu qu'il y a un peu d'interprétation personnelle quand même, donc test-&-see !
Dark storm En ligne Labélisateur Points: 11634 Défis: 176 Message

Citer : Posté le 16/04/2014 19:30 | #


Si j'ai bien compris, le principe est d'écrire dans la VRAM_2 en attendant que la VRAM_1 soit envoyée à l'écran. Dans ce a,s on ne résout pas totalement le problème de la rapidité, vu que l'on gagne le temps qu'il faut pour écrire dans la VRAM_2, mais qu'on est toujours limité par la vitesse d'écriture sur l'écran.
Finir est souvent bien plus difficile que commencer. — Jack Beauregard
Nemhardy Hors ligne Grand maître des Traits d'Esprit Points: 1242 Défis: 54 Message

Citer : Posté le 16/04/2014 19:38 | #


Oui c'est ça, le gain ne se fait pas sur la copie, mais sur le fait d'avancer le programme alors que l'écran est copié, mais je suppose que ça peut déjà permettre de gagner quelques fps ... (car si on peut copier tout un écran dans la mémoire vidéo prend une certaine durée aussi) Enfin, seuls des tests nous renseigneront précisément !
De toute manière, de ce que j'ai pu lire, la copie par DMA est la manière la plus rapide de copier une telle quantité de données et je doute qu'on puisse faire mieux de mon point de vue :-/
Ensuite, il y a l'histoire d'actualiser seulement une partie de l'écran, et je pense que là, ça peut être plus conséquent, encore faut-il que le jeu le permette ;).

Lancelot Hors ligne Membre Points: 1274 Défis: 160 Message

Citer : Posté le 17/04/2014 20:30 | #


J'ai voulut commencer à faire des testes mais il ne manque les fonctions :
Bdisp_WriteDDRegister3_bit7(1);
Bdisp_DefineDMARange(6,389,0,215);
Bdisp_DDRegisterSelect(LCD_GRAM);

Quelqu'un sait où les trouver ?
Calculatrices : Casio 35+ SH4 (modifiée 75) et fx-CG 20 PRIZM
Projets que je soutiens
Des exemples parmi tant d'autres
Pokémon Jade de Dododormeur
Zelda de Smashmaster
Super Geek Brothers de Siapran
Mes Programmes
Mes Programmes
Mes Projets
Mes Projets
ColorLib
Add-ins Jetpack Joyride et Pac-Man sur PRIZM (les 2 non commencés mais en réflexion)
A la recherche des sprites jetpack Joride si quelqu'un les a en couleur
Nemhardy Hors ligne Grand maître des Traits d'Esprit Points: 1242 Défis: 54 Message

Citer : Posté le 17/04/2014 20:34 | #


Yep C'est juste les syscalls à ajouter, je te fais ça si tu veux


Ajouté le 17/04/2014 à 20:44 :
Tiens les que voici (ça veut rien dire mais ça sonne pas trop mal x) )

unsigned short Bdisp_WriteDDRegister3_bit7( int value )  
{
     __asm__("mov.l syscall_adress_DMA1, r2\n"
         "mov.l DMA_WriteDDreg, r0\n"
         "jmp @r2\n"
         "nop\n"
         "syscall_adress_DMA1: .long 0x80020070\n"
         "DMA_WriteDDreg: .long 0x01A6");
}

void Bdisp_DefineDMARange(int un, int deux, int trois, int quatre)
{
     __asm__("mov.l syscall_adress_DMA2, r2\n"
         "mov.l DMA_DefineRange, r0\n"
         "jmp @r2\n"
         "nop\n"
         "syscall_adress_DMA2: .long 0x80020070\n"
         "DMA_DefineRange: .long 0x01A3");
}

void Bdisp_DDRegisterSelect( int registerno )
{
     __asm__("mov.l syscall_adress_DMA3, r2\n"
         "mov.l DMA_RegisterSelect, r0\n"
         "jmp @r2\n"
         "nop\n"
         "syscall_adress_DMA3: .long 0x80020070\n"
         "DMA_RegisterSelect: .long 0x01A2");
}

Lancelot Hors ligne Membre Points: 1274 Défis: 160 Message

Citer : Posté le 17/04/2014 20:52 | #


Merci
Calculatrices : Casio 35+ SH4 (modifiée 75) et fx-CG 20 PRIZM
Projets que je soutiens
Des exemples parmi tant d'autres
Pokémon Jade de Dododormeur
Zelda de Smashmaster
Super Geek Brothers de Siapran
Mes Programmes
Mes Programmes
Mes Projets
Mes Projets
ColorLib
Add-ins Jetpack Joyride et Pac-Man sur PRIZM (les 2 non commencés mais en réflexion)
A la recherche des sprites jetpack Joride si quelqu'un les a en couleur
Nemhardy Hors ligne Grand maître des Traits d'Esprit Points: 1242 Défis: 54 Message

Citer : Posté le 17/04/2014 21:10 | #


J'ai fait deux-trois tests pour l'instant et j'ai quelques soucis avec l'utilisation du deuxième buffer de sauvegarde... Je pense que je vais d'abord me concentrer sur le fait de réactualiser seulement une partie de l'écran pour l'instant (voir si c'est possible déjà), histoire de bien comprendre le fonctionnement du DMA de mon côté. Enfin, je regarde ça progressivement, mais la semaine prochaine je ne suis pas là (ou du moins sans PC) donc j'y réfléchis et les tests suivront.

Ajouté le 18/04/2014 à 22:50 :
Après quelques tests, il semblerait que le système de double buffer soit assez efficace !
Je suis en train de faire quelques tests en adaptant le système à CubeField de PierrotLL, et j'ai l'impression (je suis toujours sur émulateur pour l'instant, mais sur un très vieux PC donc à voir...) que le jeu est relativement plus fluide !
Le "soucis" pour l'instant c'est que la mémoire allouée pour le buffer est allouée à la main (j'ai calculé une adresse potable) vers la fin de la stack addin; pour CubeField ça devrait aller car le jeu n'est pas très gourmand en mémoire, mais il faut avancer sur ce point là.

Après réflexion par rapport aux propos de Dark Storm plus haut, je me dis que le temps d'écriture dans la VRAM est assez significatif au niveau des FPS : par exemple, dans CubeField, il y a une chute de FPS quand on arrive dans des zones avec beaucoup de "cubes" : la quantité d'informations à transférer de la VRAM à l'écran ne varie pas et donc théoriquement, les temps de transfert ne varient pas non plus (enfin, j'imagine) : c'est donc le "dessin" de ces objets qui influe sur les FPS : le gain de FPS devrait alors pouvoir être envisagé en "multithreadant" les opérations (veut pas dire grand chose mais bon...) .
Enfin, je continue les essais.
Dark storm En ligne Labélisateur Points: 11634 Défis: 176 Message

Citer : Posté le 18/04/2014 23:07 | #


C'est cool, au moins ça avance

Pour la nième fois : Faut que je me procure une Prizm
Finir est souvent bien plus difficile que commencer. — Jack Beauregard
Gollum Hors ligne Membre Points: 1262 Défis: 2 Message

Citer : Posté le 18/04/2014 23:10 | #


je me demande, si on overclock la prism, le processeur sera peut etre assez puissant pour rafraîchir tout l ecran , non ?i

Ajouté le 18/04/2014 à 23:10 :
je me demande, si on overclock la prism, le processeur sera peut etre assez puissant pour rafraîchir tout l ecran , non ?i
https://telegram.me/BrokenClock
Je suis de l'autre coté de la manche maintenant. Yay.
Nemhardy Hors ligne Grand maître des Traits d'Esprit Points: 1242 Défis: 54 Message

Citer : Posté le 18/04/2014 23:17 | #


Le souci n'est pas de savoir si il peut rafraichir tout l'écran, mais si il peut le faire "vite". L'overclocker est en effet bien utile pour la vitesse, mais c'est pas Versailles non plus. Donc, si on peut grappiller quelques IPS par-ci par-là, faut pas se gêner !
De plus je me demande ce qu'accélère réellement l'overclocking; de ce que j'ai cru comprendre, le transfert évoqué plus haut est effectué par une unité plus ou moins indépendante des calculs du processeurs, donc je ne sais pas si ça joue uniquement sur l'écriture dans la VRAM/autre ou aussi dans les transferts...
Dark storm En ligne Labélisateur Points: 11634 Défis: 176 Message

Citer : Posté le 18/04/2014 23:25 | #


L'overclocking accelère la fréquence du processeur. Il effectue donc plus de calculs par seconde : on gagne du temps pour les fonctions de dessin par exemple.
Toutefois, avec le système de DMA, on est limité par la fréquence du processeur du DMA justement.

Donc en effet, on peut grapiller à droite à gauche, mais on peut pas non plus en faire une bête de course
Finir est souvent bien plus difficile que commencer. — Jack Beauregard
Nemhardy Hors ligne Grand maître des Traits d'Esprit Points: 1242 Défis: 54 Message

Citer : Posté le 18/04/2014 23:58 | #


Bilan d'un premier test avec CubeField [ips min/ips max] (j'ai testé avec CubeField car c'est un jeu dont le code au niveau graphismes est "relativement simple" à adapter à ce principe, et puis je l'aime bien aussi ).
Add-in "officiel" de PLL (juste modifié pour afficher les ips) :
- calto non OC [9/16]
- calto OC [14/25]

Add-in utilisant le principe décrit plus haut :
- calto non OC [13/19]
- calto OC [20/30]

Certes comme le dit Dark Storm, ça n'en fait pas une bête de course (de toute manière on en fera jamais une vraie bête de course à mon avis), mais il y a un gain qui n'est pas insignifiant non-plus de mon point de vue.
Je vous mets les sources dans la soirée et les deux add-ins aussi si vous voulez comparer.

Dark storm En ligne Labélisateur Points: 11634 Défis: 176 Message

Citer : Posté le 19/04/2014 00:00 | #


Joli boulot Nem'

C'est déjà pas mal d'avoir réussi à grapiller 3-4 ips avec cette méthode.
Finir est souvent bien plus difficile que commencer. — Jack Beauregard
Nemhardy Hors ligne Grand maître des Traits d'Esprit Points: 1242 Défis: 54 Message

Citer : Posté le 19/04/2014 12:35 | # | Fichier joint


Oups, j'avais oublié, je vous mets les deux add-ins en PJ (CubeClass est la version originale et CubeDMA la version modifiée).
Attention, CubeDMA est potentiellement instable, c'est simplement une version de test du principe : en effet, l'adresse du buffer est allouée à la main dans la stack add-in, j'ai laissé 300ko à l'add-in, ce qui est suffisant je pense, mais on ne sait jamais (ma calto a parfaitement tenu le choc, pas de soucis personnellement)...
Ah oui, cubeDMA affiche au lancement un écran strié bizarre, faut juste appuyer sur EXE pour continuer normalement.

Je vous met le code dans un dépot Git comme ça vous pouvez comparer les deux commits et voir ce qui a changé plus simplement . C'est pas propre du tout, mais encore une fois, j'étais pressé de voir si il y aurait des résultats, ce n'est pas destiné à rester comme ça.

Edit : Finalement, je trouve un peu dangeureux après relecture de certaines doc par rapport à l'allocation à la main de mémoire (si la valeur d'un pointeur est modifiée par inadvertance :-/ ) ...
Je pense avoir une solution par rapport au buffer de sauvegarde de la mémoire !

Ajouté le 19/04/2014 à 23:13 :
[Warning] Je me rend compte que j'écris beaucoup pour dire une quantité d'information utile pas très très importante... Perso si j'étais lecteur, ça me dérangerait pas trop car j'aime bien voir la démarche des gens dans ce genre de problèmes (ce que je décris plus qu'autre chose en fait), mais après, je sais pas si ça intéresse grand monde [/Warning]

Quelques "nouvelles" des avancés de la soirée : comme évoqué à plusieurs reprises plus haut, le problème de l'utilisation de cette méthode venait de l'utilisation de la mémoire. La solution pour laquelle j'avais opté précédemment était d'utiliser une zone mémoire de manière pas du tout protégée dans la stack Add-in (l'espace où les Add-Ins sont "autorisés" à stocker leurs variables en gros). Outre le problème de sécurité (qui aurait sans doute pu être contourné en allouant classiquement un tableau dans la stack (mais je n'ai pas trop fait de tests à ce niveau là) ), vient le problème de l'espace occupé par le buffer ( 165ko, soit un peu plus de 30% de la stack Add-In).

J'avais parlé plus haut de la possibilité d'utiliser la zone utilisée uniquement pour les fonctions de sauvegarde de la VRAM (que personnellement je n'avais jamais utilisées), de la même taille que la VRAM donc (en gros tout pile ce qu'il nous faut quoi ). Après plusieurs tests, j'ai l'impression que la zone utilisée doit être alignable sur des int. Il faudra donc déborder de la zone évoquée précédemment qui n'est alignable que sur des char. J'ai préféré pour l'instant déborder "en amont" de la zone d'un octet car ça empiète sur une zone dont je comprend l’intérêt et il ne me semble pas dangereux du tout d'y écrire (d'après la doc, elle sert à stocker des bouts de VRAM qui sont effacés avec l'appel des fonctions pour faire apparaître des PopUp's, fonctions peu utilisées d'ailleurs dans les jeux).

Le soucis numéro deux, c'est que la calculatrice semble ne pas trop aimer qu'on écrive dans cette zone : après l’exécution de l'Add-In sur émulateur, certaines touches ne réagissaient plus correctement... Je ne savais pas trop comment aborder le problème car je ne comprend pas totalement le mécanisme de "Process-switching" de Casio. Finalement, il s'est avéré qu'en copiant le contenu initial de la zone, préalablement sauvegardé avant qu'on y touche, dans cette même zone, la calculatrice ne semble pas se rendre compte que l'on a écrit dans cette zone et l'Add-In quitte correctement. Le soucis de cette méthode c'est qu'il y a à nouveau une sauvegarde de la zone, impliquant un nouveau buffer de 165ko etc...

J'ai donc fait une sorte de "dump" de la zone que l'on va toucher (dans un fichier crée sur la calculatrice), et le restaure juste avant de quitter l'Add-In : la méthode fonctionne bien (toujours sur émulateur), quoiqu'un peu lente à la restauration et à l'écriture initiale du dump. Il faut donc faire des tests maintenant pour voir si ce genre de dump peut être considéré comme "universel", c'est à dire peut être utilisé de manière générale pour les Add-Ins se basant sur ce principe, et donc distribué une fois par les développeurs et ensuite utilisé à demande; ou alors si il a besoin d'être fait à chaque démarrage d'Add-In pour une restauration finale (ce qui m'étonnerait un peu, je pencherait plus pour l'aspect "universel") ou autre...

Quoi qu'il en soit, ça progresse !

On a maintenant quelque chose capable de faire gagner jusqu'à 5 fps (oui c'est pas forcément beaucoup, et ne sera peut être pas généralisé, mais il faut être un peu content parfois ) et qui en principe n'imposera pas une trop grande utilisation de mémoire (quasi-nulle au niveau de la RAM en fait si les bêtises que je raconte plus haut s'avèrent être vraies et utiles, et à ce moment là, un peu plus de ROM, mais on en a pas mal sur Prizm (16Mo), donc ça peut aller je pense) par rapport à une utilisation classique !

EDIT : Je fais une pause d'une semaine étant donné que je pars avec le lycée, et donc pas de PC (enfin, Planète-Casio depuis le portable mais pas d'ordi quoi ).
Dark storm En ligne Labélisateur Points: 11634 Défis: 176 Message

Citer : Posté le 20/04/2014 10:00 | #


Ben c'est pas mal tout ça
Encore un peu, et tu fera presque mieux que Kristaba en terme de pavé

A la nostalgie des pavés de ce dernier...
Finir est souvent bien plus difficile que commencer. — Jack Beauregard
Nemhardy Hors ligne Grand maître des Traits d'Esprit Points: 1242 Défis: 54 Message

Citer : Posté le 27/04/2014 19:57 | #


Bon, j'ai pas trop du tout pu avancer cette semaine, mais les tests que j'avais fait dimanche dernier ne c'étaient pas montré très concluants quant à la stabilité de la méthode d'écriture dans le buffer de sauvegarde de la VRAM, la calculatrice plantant régulièrement...

Il semble en fait que la doc de SimLo n'était pas trop complète et exacte sur l'adresse de la zone, ni même sur le fonctionnement de la mémoire autour de cette zone : il y aurait en fait probablement par là une zone qui remplirait le rôle de heap système (c'est à dire pour des allocations de mémoire demandée par certains syscalls et opérations systèmes, comme l'appel de SaveVRAM(); par exemple). L'adresse précisée dans la doc ne serait donc forcément pas la bonne à chaque exécution. Cela est d'autant plus problématique que l'on peut trouver des tables de pointeurs par exemple dans la zone dans laquelle j'écrivais précédemment, ce qui n'est pas bon du tout étant donné que le système fait des manips avec ces derniers.

A partir de là, j'envisage deux solutions : soit on se re-retourne vers la stack et donc la limitation de mémoire disponible pour l'add-in, soit on essaye de localiser à chaque exécution la zone allouée à la sauvegarde de la VRAM et enregistrant par exemple une séquence de x octets spécifiques dans la VRAM puis en sauvegardant celle ci pour réserver l'espace, et en parcourant ensuite la zone de heap système pour retrouver les octets correspondants à cette séquence, et donc l'adresse d'une zone potentiellement utilisable (il faut faire des tests pour voir si c'est réalisable).

Donc pour l'instant, l'utilisation pour des add-in pas trop demandeurs en mémoire statique (exemple : CubeField) est envisageable à partir du moment où celle-ci est déclarée "légalement" au compilateur (sans lui donner une adresse en espérant que le programme n'ira pas jusque là ), et l'alternative se basant toujours sur la sauvegarde de la VRAM est encore envisageable, mais j'ai encore quelques doutes sur sa fiabilité pour l'instant et il faut faire des essais de mise en œuvre.

Let's test again !

#MessageAUilitéRéduite

Ajouté le 30/04/2014 à 18:46 :
Hop, It's me again !

Donc, pour l'instant, compte tenu de la stabilité réduite de la solution avec le buffer de la VRAM sauvée, j'ai préféré avancer avec quelque chose de plus "légal" et sûr pour l'instant.
Un gros bloc de 165ko (mas o menos) est donc réservé dans la RAM addin. J'ai passé un moment à avoir quelque chose qui ne fonctionnait tout simplement pas au moment de l'envoi à l'écran (on avait un bel écran bleu (microsoft inside ? ) quelles que soient les données dans la mémoire...), il est apparu finalement que cela semble venir du fait que la RAM de l'addin est virtualisée au lancement de ce dernier. Je n'en comprend pas bien l’intérêt ni le principe en détail, mais alors que la RAM addin s'étend normalement de 0x88160000 à 0x881D0000 à peu près (zone depuis laquelle un transfert fonctionne comme prévu), on se retrouve avec des adresses durant l’exécution allant de 0x08100000 à 0x08170000 et le transfert ne semblait pas fonctionner à ce moment là...

Il est apparu aussi que les adresses "virtualisées" semblent pointer vers les mêmes données que les adresses "classiques" (vers la même zone physique de la mémoire flash), ou du moins, les données restent identiques durant l’exécution du programme d'après un ou deux tests (je m'arrête pour l'instant à cette hypothèse car je ne comprend pas bien le processus, si quelqu'un en sait plus quant à cette notion de virtualisation...).

On peut facilement passer d'une adresse "virtualisée" à une adresse "classique" (je ne sais pas si ce sont les bons termes) en augmentant la première de 0x80060000, et un transfert et réalisable depuis l'adresse "transformée". La réservation "légale" de la zone où écrire est donc possible et opérationnelle, je pense poster un semblant de bibliothèque dans la soirée, dès que mes fichiers seront vidés de tout ce qui relève de débogage.

Finalement, la mémoire disponible sera un peu plus faible pour les programmes qui utiliseront cette méthode, mais pour des jeux tels CubeField (pour changer ) qui ne sont pas très gourmands en mémoire (en plus CubeField ne fait quasiment que de l'allocation dynamique et tape donc dans un autre buffer).
Il restera donc les 131ko de la heap (rien de perdu donc pour ce qui concerne les malloc et compagnie) ainsi que 358ko qui resteront disponibles dans la RAM addin, ce qui est relativement confortable pour des petits jeux qui peuvent nécessiter d'être rapides et utilisant l'allocation dynamique.
Lephenixnoir En ligne Administrateur Points: 24219 Défis: 170 Message

Citer : Posté le 30/04/2014 18:49 | #


Pour faire court...
Bravo !
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Lancelot Hors ligne Membre Points: 1274 Défis: 160 Message

Citer : Posté le 30/04/2014 19:23 | #


Super joli travail
Calculatrices : Casio 35+ SH4 (modifiée 75) et fx-CG 20 PRIZM
Projets que je soutiens
Des exemples parmi tant d'autres
Pokémon Jade de Dododormeur
Zelda de Smashmaster
Super Geek Brothers de Siapran
Mes Programmes
Mes Programmes
Mes Projets
Mes Projets
ColorLib
Add-ins Jetpack Joyride et Pac-Man sur PRIZM (les 2 non commencés mais en réflexion)
A la recherche des sprites jetpack Joride si quelqu'un les a en couleur
Nemhardy Hors ligne Grand maître des Traits d'Esprit Points: 1242 Défis: 54 Message

Citer : Posté le 01/05/2014 00:19 | #


Oups, s'cusez moi, j'ai peut-être parlé peu tôt ... En fait, jusqu'à présent, tout mes tests se faisaient sur émulateur (plus pratique et censé bien émuler la calto, même à un niveau un peu plus bas), et là, au moment de faire des tests sur la vraie... ben ce qui marche niquel sur émulateur ne marche pas du tout comme escompté sur la vraie (ça marche un peu, mais le comportement est ... étrange)... Donc je continue de creuser et tiendrai le topic au courant .

Ajouté le 22/02/2015 à 19:19 :
Hop, du nouveau ! On a trouvé récemment un syscall permettant de récupérer de manière propre l'adresse de la seconde VRAM dont on parlait plus tôt (celle utilisée avec les Save_VRAM), et apparemment ça à l'air plutôt stable avec. Je n'ai pas testé sur vraie machine car j'ai le bac blanc cette semaine et au cas où il se passerait quelque chose.

Il y a juste un petit "problème" mais qui se règle(ra) facilement c'est que l'adresse renvoyée n'est pas toujours alignable sur un short (et encore moins un int), donc ça impliquera peut être de "manger" un pixel à l'une des extrémités de l'écran pour rester propre...

Quoi qu'il en soit, si ça me refait pas le coup du *ça marche sur émulateur mais pas sur la machine*, je pense qu'on pourra enfin avoir quelque chose de bien sans consommer plus de mémoire ! (enfin quasiment, car pas grand monde utilise les sauvegardes de VRAM ).
1, 2 Suivante

LienAjouter une imageAjouter une vidéoAjouter un lien vers un profilAjouter du codeCiterAjouter un spoiler(texte affichable/masquable par un clic)Ajouter une barre de progressionItaliqueGrasSoulignéAfficher du texte barréCentréJustifiéPlus petitPlus grandPlus de smileys !
Cliquez pour épingler Cliquez pour détacher Cliquez pour fermer
Alignement de l'image: Redimensionnement de l'image (en pixel):
Afficher la liste des membres
:bow: :cool: :good: :love: ^^
:omg: :fusil: :aie: :argh: :mdr:
:boulet2: :thx: :champ: :whistle: :bounce:
valider
 :)  ;)  :D  :p
 :lol:  8)  :(  :@
 0_0  :oops:  :grr:  :E
 :O  :sry:  :mmm:  :waza:
 :'(  :here:  ^^  >:)

Σ π θ ± α β γ δ Δ σ λ
Veuillez donner la réponse en chiffre
Vous devez activer le Javascript dans votre navigateur pour pouvoir valider ce formulaire.

Si vous n'avez pas volontairement désactivé cette fonctionnalité de votre navigateur, il s'agit probablement d'un bug : contactez l'équipe de Planète Casio.

Planète Casio v4.3 © créé par Neuronix et Muelsaco 2004 - 2024 | Il y a 60 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd