Benchmark avec synchronisation sur l'affichage

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Benchmark avec synchronisation sur l'affichage

Message par djes »

Voici un benchmark qui utilise une synchronisation sur l'affichage, avec VBL et rasterlines comme au bon vieux temps!

Exe : http://djes.free.fr/purebasic/rasterlines.exe

N'oubliez pas de mettre DirectX9 dans Compilateur -> Options du compilateur -> Bibliothèque sous-système

[Edit] Petite explication : vous allez voir à l'écran un effet (ici, des cercles qui vont de droite à gauche, un peu comme un champ d'étoiles), et deux lignes. Ces deux lignes indiquent le temps que prend l'effet, en se basant sur l'affichage comme base de temps. C'est un vieux truc de démomakers.

L'espace entre les deux lignes correspond au temps pris par l'ordinateur pour calculer et afficher notre effet.

Pour comprendre, il faut se rappeller comment fonctionnent les écrans CRT : l'écran est un tube cathodique, dont la surface est recouverte de phosphore, matériau qui émet de la lumière quand il reçoit un faisceau d'électrons. Ce faisceau est appelé "spot". Le spot parcourt donc la surface de haut en bas, et de gauche à droite. Pour un affichage à 60imgs par seconde, il fait donc cela 60 fois par seconde (simple, non?), c'est ce que vous voyez dans les paramètres d'affichage : 60hz.

Ce que fait ce programme est de synchroniser le code sur la position du spot. Il commence le code en haut après le clearscreen et affiche une première ligne. Ensuite il calcule et affiche les sprites dans le backbuffer, et affiche la nouvelle position du spot : deuxième ligne. Donc on voit que notre effet a demandé un certain temps à notre malheureux PC! Plus vous ferez de calculs, ou afficherez de sprites, plus la deuxième ligne descendra...
Si vous atteignez le bas, vous aurez ce qu'on appelle un "frame drop" : l'ordi ne peut pas tout afficher en moins d'une frame, donc au lieu d'avoir un bel affichage à 60 imgs/secs, vous passez à 30 imgs/secs, d'où l'effet de "saut" assez désagréable que détestent les vrais démomakers!
Si votre écran est à 60Hz, que vous avez moins de la hauteur d'un écran entre les deux lignes, cela signifie que l'effet a pris moins de 16 ms, et que nous avons donc nos 60 imgs/sec et la meilleure fluidité possible! :D

[Edit2] PB 4.60 et nettoyage

Code : Tout sélectionner

;*****************************************************************************
;* RasterLine and vertical blank (VBL) benchmark
;* Realtime visual benchmark. Press space to add "stars". The time is given
;* by the space between blue and green line.
;* By djes (djes@free.fr) 03/24/2009
;* Thanx to Stefan Moebius for VBL sync examples
;* Note : I do not check functions return values : I know it's bad!!!
;* 02/28/2012 : PB 4.60 fix
;*****************************************************************************

Structure D3DRaster_STATUS
  InVBlank.l
  ScanLine.l
EndStructure

Structure Pos
  x.l
  y.l
  Speed.l
EndStructure

;*****************************************************************************

Define.D3DRaster_STATUS Raster
Define.IDirect3DDevice9 D3DDeviceInterface

Global NewList Stars.Pos()

;*****************************************************************************
;wait for the vblank to start - takes all the cpu
;attend le début de la synchro vbl
Procedure VBLWait()
  Shared D3DDeviceInterface, Raster, Exit
  Repeat
    ExamineKeyboard()
    If KeyboardPushed(#PB_Key_Escape)
      Exit=#True
    EndIf
    D3DDeviceInterface\GetRasterStatus(0, @Raster)
  Until Raster\InVBlank=#True Or Exit
EndProcedure

;*****************************
;wait for the vblank to finish - takes all the cpu
;attend la fin de la synchro vbl
Procedure VBLEndWait()
  Shared D3DDeviceInterface, Raster, Exit
  Repeat
    ExamineKeyboard()
    If KeyboardPushed(#PB_Key_Escape)
      Exit=#True
    EndIf
    D3DDeviceInterface\GetRasterStatus(0, @Raster)
  Until Raster\InVBlank=#False Or Exit
EndProcedure

;*****************************
;look for the Raster pos and draw a coloured line
;récupère la position du Raster et y affiche une ligne de la couleur indiquée
Procedure RasterLine(Color.l)
  Shared Raster, D3DDeviceInterface
  StartDrawing(ScreenOutput())
  D3DDeviceInterface\GetRasterStatus(0, @Raster)
  LineXY(0, Raster\ScanLine, 1023, Raster\ScanLine, Color)
  StopDrawing()
EndProcedure

;**************************
Procedure CreateSprites()
  CreateSprite(0, 64, 64)
  StartDrawing(SpriteOutput(0))
  Circle(32, 32, 31, RGB($FF, $FF, $FF))
  StopDrawing()
EndProcedure

;************************
;Open screen and get the device - Ouvre l'écran et récupère le device
Procedure InitDisplay()
  Shared D3DDeviceInterface
  OpenScreen(1024, 768, 32, "", #PB_Screen_NoSynchronization, 60)
  !extrn _PB_Screen_Direct3DDevice
  !MOV dword EAX, [_PB_Screen_Direct3DDevice]
  !MOV dword [v_D3DDeviceInterface],EAX
EndProcedure

;************************
;Check if the user has switched (and that we have lost focus) (ALT-TAB)
;Vérifie si l'utilisateur n'a pas changé d'appli (en nous faisant donc perdre le focus) (ALT-TAB)
Procedure FullScreenCheck()
  
  ;we're lowering our priority - on baisse notre priorité
  SetPriorityClass_(  GetCurrentProcess_(), #NORMAL_PRIORITY_CLASS)
  SetThreadPriority_( GetCurrentThread_() , #THREAD_PRIORITY_NORMAL)
  
  ReleaseMouse(1)
  CloseScreen()
  
  OpenWindow(0, 0, 0, 256, 256, "RasterLines", #PB_Window_Minimize)
  
  ;Wait til our window is coming back to foreground - Attend que notre fenêtre repasse au premier plan
  Repeat
    ;now our events are to be processed with WaitWindowEvent, else IsScreenActive() will never say that our window has the focus again
    ;it should be written in the doc!
    ;maintenant les événements sont à gérer avec WaitWindowEvent, sinon IsScreenActive() ne dit jamais que notre fenêtre a à nouveau le focus
    ;il faudrait mettre ça dans la doc!!!!
    Event = WaitWindowEvent()   
  Until Event = #PB_Event_ActivateWindow
  
  CloseWindow(0)
  
  ReleaseMouse(0)
  ;Better recreate the screen - il vaut mieux recréer l'écran
  InitDisplay()
  ;and the sprites too (have to!) - et les sprites aussi (indispensable)
  CreateSprites()
  
  ;give to the system some time to rest - laisse un peu le temps au système de récupérer
  ;Delay(2000)
  
  ;We're waiting for the synchro a new time - On réattend la synchro
  VBLWait()
  SetPriorityClass_(  GetCurrentProcess_(), #HIGH_PRIORITY_CLASS)
  SetThreadPriority_( GetCurrentThread_() , #THREAD_PRIORITY_ABOVE_NORMAL)     ;warning : keyboard lock
  
  
EndProcedure

Procedure NewStar()
  AddElement(Stars())
  Stars()\x = Random(1024 + 128) - 64
  Stars()\y = Random(768 + 128) - 64
  Stars()\Speed = Random(16) + 1
EndProcedure
  
;*****************************************************************************
;-                                START
;*****************************************************************************

InitSprite()
InitKeyboard()
InitMouse()

InitDisplay()
CreateSprites()

For i = 1 To 5
  NewStar()
Next i

Exit=#False

;we're giving max priority to our process - on donne une priorité maximale à notre processus
SetPriorityClass_(  GetCurrentProcess_(), #REALTIME_PRIORITY_CLASS)
SetThreadPriority_( GetCurrentThread_() , #THREAD_PRIORITY_TIME_CRITICAL)     ;warning : keyboard lock

;*****************************************************************************
;-                                MAIN LOOP
;*****************************************************************************

Repeat
  
  ;wait for the sync - attends la synchro
  VBLWait()
  
  ;flip buffers without the PB's sync - flippe le buffer sans utiliser la synchro PB
  FlipBuffers()
  
  ;during VBL, lower a bit our priority to give time to OS (especially to handle the keyboard)
  ;pendant la VBL, baisse un peu notre priorité pour donner un peu de temps au système (pour gérer le clavier surtout)
  SetPriorityClass_(  GetCurrentProcess_(), #HIGH_PRIORITY_CLASS)
  SetThreadPriority_( GetCurrentThread_() , #THREAD_PRIORITY_NORMAL)
  
  ExamineKeyboard()
  ExamineMouse()
  
  If KeyboardPushed(#PB_Key_Escape)
    Exit=#True
  EndIf
  
  If KeyboardPushed(#PB_Key_Space)
    NewStar()
  EndIf

  
  If Not IsScreenActive()
    FullScreenCheck()   
  EndIf
  
  ;we're waiting for the VBL end (could be better!!!)
  ;on attend la fin de la VBL (à améliorer) pour être sûr de ne pas sauter une frame
  VBLEndWait()
  
  ;we're giving max priority to our process - on donne une priorité maximale à notre processus
  SetPriorityClass_(  GetCurrentProcess_(), #REALTIME_PRIORITY_CLASS)
  SetThreadPriority_( GetCurrentThread_() , #THREAD_PRIORITY_TIME_CRITICAL)     ;warning : keyboard lock
  
  ClearScreen(0)
  
  ;--- BENCHMARK
  ;draw the first Raster line (base of our benchmark)
  RasterLine($FF0000)
  
  ;compute an effect
  ForEach Stars()
    Stars()\x + Stars()\Speed
    If Stars()\x > 1023
      Stars()\x - 1088
    EndIf
  Next
  
  ;display it
  ForEach Stars()
    DisplayTranslucentSprite(0, Stars()\x, Stars()\y, Stars()\Speed<<4)
  Next
  
  ;draw the second RasterLine to see (visually) how much time our fx is taking
  ;the less space between the two lines, the fastest our effect
  ;affiche une RasterLine pour visualiser combien de temps prend notre effet
  RasterLine($FF00)
  ;---- BENCHMARK END 
  
  StartDrawing(ScreenOutput())
  DrawingMode(#PB_2DDrawing_Transparent)
  Text.s = "Press SPACE to add stars ; ESC to quit"
  DrawText(512 - TextWidth(Text)/2, 300, Text, #Blue)
  Text.s = "Stars Nb : " + Str(ListSize(Stars()))
  DrawText(512 - TextWidth(Text)/2, 320, Text, #Red)
  StopDrawing()
  
Until Exit

CloseScreen()

End
Dernière modification par djes le mar. 28/févr./2012 10:44, modifié 9 fois.
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Message par Kwai chang caine »

Comme je sais meme pas de quoi tu cause, comme dab :oops:
J'ai essayé et ça marche pas, y doit encore me manquer un fichier "cake" part :cry:
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Message par djes »

Tu peux me dire ce qui ne marche pas? Erreur à la compil, pas d'affichage?
Avatar de l’utilisateur
flaith
Messages : 1487
Inscription : jeu. 07/avr./2005 1:06
Localisation : Rennes
Contact :

Message par flaith »

Kwai chang caine a écrit :Comme je sais meme pas de quoi tu cause, comme dab :oops:
J'ai essayé et ça marche pas, y doit encore me manquer un fichier "cake" part :cry:
Peut-être en ajoutant "DIRECTX9" dans la bibliothèque sous-système des options du compilateur ?

Sinon j'ai bien les cercles qui bougent de gauche à droite mais j'ai deux lignes (verte et bleue) en haut qui ne bougent pas :?
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Message par djes »

J'aurais peut-être dû faire une explication de texte; je vais la mettre dans le premier post :)
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

pareil chez moi ça compile pas !!

erreur polink "unresolved external symbol '_PB_screen_Direct3Ddevice' "

et erreur compilateur numero 1031
:)
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Message par djes »

Oui il faut mettre en directx9. J'ai édité le premier post.
beauregard
Messages : 1307
Inscription : dim. 08/juil./2007 18:32
Localisation : Toulouse

Re: Rasterlines et synchro VBL

Message par beauregard »

djes a écrit : Si vous atteignez le bas, vous aurez ce qu'on appelle un "frame drop" : l'ordi ne peut pas tout afficher en moins d'une frame, donc au lieu d'avoir un bel affichage à 60 imgs/secs, vous passez à 30 imgs/secs, d'où l'effet de "saut" assez désagréable que détestent les vrais démomakers!

Code : Tout sélectionner

  For i = 0 To #STARS_NB-1
    DisplayTranslucentSprite(0, stars(i)\x, stars(i)\y, stars(i)\speed<<4)
  Next i

c'est fortiche parce que tu n'utilise pas de sprite3D( je vois bien les 2 lignes qui restent en haut de l'écran et bien sûr les beaux disques transparents :) , et malgrès un écran tout pourrie, un lcd 19pouce en 1440*900 à 60Hz, c'est fluide.) faudrait implémenter un code pour connaitre le nombre d'image/s.
config de mon ordi: seven, directx11, Pentium(R) DualCore E5700, RadeonHD 4550 512MB, PureBasic 4.61 x86
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Rasterlines et synchro VBL

Message par djes »

beauregard a écrit :
djes a écrit : Si vous atteignez le bas, vous aurez ce qu'on appelle un "frame drop" : l'ordi ne peut pas tout afficher en moins d'une frame, donc au lieu d'avoir un bel affichage à 60 imgs/secs, vous passez à 30 imgs/secs, d'où l'effet de "saut" assez désagréable que détestent les vrais démomakers!

Code : Tout sélectionner

  For i = 0 To #STARS_NB-1
    DisplayTranslucentSprite(0, stars(i)\x, stars(i)\y, stars(i)\speed<<4)
  Next i

c'est fortiche parce que tu n'utilise pas de sprite3D( je vois bien les 2 lignes qui restent en haut de l'écran et bien sûr les beaux disques transparents :) , et malgrès un écran tout pourrie, un lcd 19pouce en 1440*900 à 60Hz, c'est fluide.) faudrait implémenter un code pour connaitre le nombre d'image/s.
Hum! Si la deuxième ligne ne descend pas en bas, tu es au max de ton écran, à savoir... 60 imgs/sec :) C'est pour ça que c'est -vraiment- fluide.
beauregard
Messages : 1307
Inscription : dim. 08/juil./2007 18:32
Localisation : Toulouse

Re: Rasterlines et synchro VBL

Message par beauregard »

djes a écrit :C'est pour ça que c'est -vraiment- fluide.
là j'ai désactiver ClearScreen, pour bien voir, et de temps en temps la ligne verte descend au 1er quart de l'écran, mais rien de méchant.

ClearScreen actif:
à 300 stars_nb, la ligne verte descend un peu et parait moins stable mais çà va :)

même à 1000 sprites, çà tient la route ! :D et c'est beau....

à 2000 sprites, la ligne est descendus d'un cran, disons au 1er tiers de l'écran, c'est dingue comme c'est toujours aussi fluide !

à 3000 sprites, ligne à la moitié

à 4000, ligne au 2 tiers, c'est le délire ! :)

à 6000, logique, ligne au bas de l'écran, fin de la joyeuse expérience
Image
config de mon ordi: seven, directx11, Pentium(R) DualCore E5700, RadeonHD 4550 512MB, PureBasic 4.61 x86
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Message par djes »

Tu as compris :D
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Message par Kwai chang caine »

Merci DJES 8)
Encore une option de ouf qu'on peut rajouter dans l'IDE
C'est dingue tous les jours ou presque j'suis épaté par toutes les options qu'on pourrais mettre ou cocher dans ce bijoux.
Comme la on ecrit "DirectX9" et ça marche ...C'est magique.

Hier je viens de decouvrir tout seul comme un grand, et sans vous deranger, les CompilerIf j'en suis encore sur le R......euh non Q :D

Bref bien que comme dab, j'sois un peu a la rue dans tous ce genre de code...c'est beau, fluide, de la dentelle
Merci de ton partage
Avatar de l’utilisateur
Huitbit
Messages : 940
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Message par Huitbit »

Hello !

Nickel :P (la sortie avec Echap est un peu capricieuse chez moi)

K2C, je suis plus fort que toi, j'ai fait au moins dix tentatives en écrivant "Direct9x" :lol: :lol: :lol: et en me disant, c'est quoi ce code pourri :lol: :lol: !

Hasta la vasti :lol: !
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

Au risque, une fois de plus (nom de nom!) de passer pour un lourd, ce programme échoue.

Il échoue dans le sens où il me coupe l'écran à un quart de la hauteur comme un samouraï couperait une pomme au sabre.

Par contre, cette coupure est stable. Donc je comprends ce que tu veux démontrer avec ce code.

Seulement, je te dirais que, toi aussi tu aimes bien casser du sucre... Tu critiques dans le sujet "Performance d'un jeu 2D" un code plus avancé, plus performant et plus complet.

Je doute que la synchronisation soit complètement gérée par ce code. J'entends par là que certaines cartes graphiques (et, comme par hasard la mienne!) peuvent éprouver des caprices qu'il faudrait prendre en compte. Mais alors, te dire le ou lesquels: je t'avoue être un gros ignorant à ce sujet.

Maintenant, à moins que tu aies obtenu quelque chose de décevant en matière de fluidité, Ogre gère cette synchronisation. Et si ça n'est pas le cas, il y a une section "Bug Report" pour veiller à ce que la prochaine version soit fiable.

Sincèrement, au lire du titre "Ce que fluide veut vraiment dire", je me pose la question de savoir si consacrer du temps à expliquer quelque chose à l'encontre des pratiques habituelles et pourtant adaptées aux théories habituelles vaut le coup sur le forum.

Il n'y a pourtant pas photo! Ajoute, ne serait-ce que les quatre commandes de direction en ce code. Nous nous rejoindrons alors sur le fait que la fluidité est la conséquence d'un tout: une bonne gestion des commandes, une mise à jour adaptée, un affichage soulagé et une absence permanente de conflit avec l'OS.
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Message par djes »

Ollivier> Rah là là, qu'est-ce que tu es rancunier! Il n'y a strictement aucun rapport entre ton programme et le mien, je ne vois pas ce que tu vas chercher! Je ne l'ai pas fait non plus pour te casser du sucre sur le dos (c'est bien de moi dont je parlais d'ailleurs la dernière fois). Il est vrai que la question que tu te posais sur les performances m'a fait dévier sur la fluidité, qui n'est pas synonyme.

Mon programme permet de mesurer visuellement la performance d'une routine. J'y ai intégré d'autres choses, à titre d'exemple pour les débutants, tout en n'étant pas la panacée. Ainsi je ne teste pas les valeurs de retour des fonctions, c'est très mal!

Si tu n'es pas bête, tu sauras en tirer parti. Tu peux ainsi parfaitement mettre ton code à la place de mes étoiles, pour mesurer grâce au spot si ogre est plus performant que dx7 ou dx9. Ou tu peux continuer à te braquer et faire ton paon, mais dans ce cas je te conseille de relire la netiquette.
Répondre