Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

ASM Blur
Gehe zu Seite Zurück  1, 2, 3  Weiter
 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Profi-Forum
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Eternal_pain



Anmeldungsdatum: 08.08.2006
Beiträge: 1783
Wohnort: BW/KA

BeitragVerfasst am: 28.03.2015, 12:32    Titel: Antworten mit Zitat

Ich nutze am Desktop eine Auflösung von 1920x1080.

Nachdem ich nu ein weilchen versucht habe die ASM Routinen alle halbwegs zu verstehen um mir dann eine eigene zu basteln hab ich es für's erste aufgegeben und verwende Voltas MMX-Fader, um den verwischten Rand (oben und unten) zu verhindern, begrenze ich die vertikalen grenzen auf 1 bis Höhe-1... bleibt dann durchschnittlich bei ~65 Frames

(is mir zu aber bissle zu schnell und werd da noch ein Timer basteln das es 'entspannt' bleibt)

Gleich mal lappi aufstellen und da testen lächeln
_________________
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen MSN Messenger
volta



Anmeldungsdatum: 04.05.2005
Beiträge: 1874
Wohnort: D59192

BeitragVerfasst am: 28.03.2015, 13:05    Titel: Antworten mit Zitat

Hi,
diese MMX-Routine ist eigentlich sehr einfach grinsen
Ich hoffe dies hilft dir sie zu verstehen.
Code:
Asm
  mov eax, [ScrPtr]     '      P=Point;  A-C,P = RGBA
  Add eax, [j]          '(A) (P) (B)
  mov ebx, [byte_zeile] '    (C)
  pxor mm2, mm2
  movd mm0, [eax +ebx]  'C -> mm0
  punpcklbw mm0, mm2    'RGBA -> 00rr00gg00bb00aa
  movd mm1, [eax]       'P -> mm1
  punpcklbw mm1, mm2
  paddw mm0, mm1        'mm0 = C + P
  movd mm1, [eax -4]    'A -> mm1
  punpcklbw mm1, mm2
  paddw mm0, mm1        'mm0 = C + P + A
  movd mm1, [eax +4]    'B -> mm1
  punpcklbw mm1, mm2
  paddw mm0, mm1        'mm0 = C + P + A + B
  psrlw mm0, 2          'mm0 / 4
  packuswb mm0, mm0     '00rr00gg00bb00aa -> RGBA
  movd [eax], mm0       'mm0 -> P
End Asm

_________________
Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 28.03.2015, 13:42    Titel: Antworten mit Zitat

Eternal_pain: Wenn du wissen willst, warum deine Routine so viel langsamer ist: Nein, nicht nur wegen MMX. Du berechnest ständig Dinge neu, die du schon weißt. Multipliaktionen sind (relativ) teuer, trotzdem berechnest du für jeden Pixel mehrmals y * srcPitch bzw (y + 1) * srcPitch.
Dabei bleiben diese Werte die ganze Zeile über konstant! Einmal vor der Schleife berechnen spart dir schon mal diese Verschwendung. Und wenn du die erste Konstante berechnet hast, kannst du die andere ganz einfach mit einer Addition berechnen: y0 = y * srcPitch, yPlus1 = y0 + srcPitch (wobei das noch etwas ist, was ein guter Compiler von selbst tut). Die ganze LoByte/LoWord/etc.-Geschichte scheint mir auch insgesamt sehr ineffektiv, da hier mehrmals werde rumgeshiftet werden.

Ein alter, aber immer noch wahrer Artikel dazu, insbesondere zum ersten Punkt:
http://blog.kebby.org/?p=47
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1208
Wohnort: Ruhrpott

BeitragVerfasst am: 28.03.2015, 16:03    Titel: Antworten mit Zitat

Nachdem ich die ASM-Routine aufgedröselt habe (@Volta: Danke für die Kommentierung) fürchte ich sagen zu müssen: Ihr vergleicht da Äpfel mit Birnen. Während Eternal_pain eine "echte" blur-Funktion geschrieben hat, bei der der Mittelwert von 2x2 (quadratisch) benachbarten Pixeln gebildet wird, ist Voltas Routine ein Fader, der sich an jeweils einer Zeile entlangarbeitet und jeweils den Mittelwert von 3 aufeinanderfolgenden Pixeln bildet - was natürlich deutlich schneller geht.

Ich habe mir einmal den Spaß gemacht, den Fader zur blur-Funktion umzuschreiben:
Code:
Sub blur2()
   Dim As Integer scrWidth, scrHeight, scrPitch, lin, col
   Dim As Byte Ptr ptr1, image
     
   image = ScreenPtr
   ScreenInfo scrWidth, scrHeight,,,scrPitch
   
   For lin = 0 To scrHeight - 2 Step 2
      ptr1 = image + lin * scrPitch
      For col = 0 To scrPitch - 4 Step 2
         Asm
              mov eax, [ptr1]     'zeilenpointer in register eax
              Add eax, [col]      'spaltenposition addieren
              mov ebx, eax        'pointer auf nächste zeile
              Add ebx, [scrPitch] '1 Zeile addieren
              pxor mm2, mm2       'register mm2 auf 0 setzen
              movd mm0, [eax]     'pixel in register mm0 laden
              punpcklbw mm0, mm2  'RGBA -> 00rr00gg00bb00aa /inhalte von mm0 und mm2 verschachtelt in mm0 laden --> mm0 entpacken
              movd mm1, [eax + 4] 'folgendes pixel in register mm1 laden
              punpcklbw mm1, mm2  'mm1 entpacken
              paddw mm0, mm1      'mm1 wordweise (jeweils 16bit) zu mm0 addieren
              movd mm1, [ebx]     'darunterliegendes pixel in register mm1 laden
              punpcklbw mm1, mm2  'mm1 entpacken
              paddw mm0, mm1      'mm1 wordweise zu mm0 addieren
              movd mm1, [ebx + 4] 'nächstes pixel der nächsten zeile in mm1
              punpcklbw mm1, mm2  'mm1 entpacken
              paddw mm0, mm1      'mm1 wordweise zu mm0 addieren
              psrlw mm0, 2        'summe in mm0 durch 4 teilen
              packuswb mm0, mm0   '00rr00gg00bb00aa -> RGBA /inhalt von mm0 byteweise packen
              movd [eax], mm0     'durchschnittswert der 4 pixel zurückschreiben
              movd [eax + 4], mm0 
              movd [ebx], mm0     
              movd [ebx + 4], mm0   
            End Asm
      Next
     
   Next
End Sub


Diese Variante schafft auf meinem betagten Rechenknecht noch 23 FPS.

Etwas schneller, nämlich mit 28 FPS, geht es (ganz ohne Assembler) wenn man ein wenig in die Trickkiste greift:
Code:
Type tStrDescr
   txtPtr As Byte Ptr
   txtLen As UInteger
   txtMem As UInteger
End Type

Sub blur()
   Dim As Integer x, y, lin, iWidth, iHeight
   Dim As Byte erg
   Dim As String u, g
   
   ScreenInfo iWidth, iHeight
   u = ""
   g = ""
   
   Dim As tStrDescr Ptr uPtr = Cast(tStrDescr Ptr,@u)
   uPtr->txtLen = iWidth * 4
   Dim As tStrDescr Ptr gPtr = Cast(tStrDescr Ptr,@g)
   gPtr->txtLen = iWidth * 4
   For lin = 0 To iHeight - 2 Step 2
      uPtr->txtPtr = ScreenPtr + lin * iWidth * 4
      gPtr->txtPtr = ScreenPtr + (lin + 1) * iWidth * 4
      For x = 0 To Len(u) - 5 Step 4
        For y = 0 To 2
            erg = (u[x+y] + u[x+4+y] + g[x+y] + g[x+4+y]) Shr 2
          u[x+y] = erg
          u[x+4+y] = erg
          g[x+y] = erg
          g[x+4+y] = erg
        Next
      Next
   Next
End Sub


Pointeradressierte Strings mag der Compiler offenbar besonders gern. zwinkern

EDIT: Falscher Fehler! verlegen Wenn blur2() so arbeiten soll wie ScreenSoft(), muß es heißen:
Code:
...
 For lin = 0 To scrHeight - 2
      ptr1 = image + lin * scrPitch
      For col = 0 To scrPitch - 4 Step 4
...

Die Sub schafft dann 45 FPS.

Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!


Zuletzt bearbeitet von grindstone am 28.03.2015, 21:21, insgesamt einmal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Eternal_pain



Anmeldungsdatum: 08.08.2006
Beiträge: 1783
Wohnort: BW/KA

BeitragVerfasst am: 28.03.2015, 21:17    Titel: Antworten mit Zitat

Alle mal getestet lächeln

Code:

                'blur_mmx() 'by grindstone             ' ~33-43FPS 1980x1020 (optisch scheint da was falsch vom effekt)
                'blur_grind() 'by grindstone           ' absturz
                'fader_MMX (screenptr) 'by volta        ' ~60-70FPS 1980x1020


Code:
   For lin = 0 To scrHeight - 2 Step 2      'note: 1 von 4 pixel werden zusammengeführt während
      ptr1 = image + lin * scrPitch         'die anderen 3 davon unberührt bleiben das ist optisch etwas unschön
      For col = 0 To scrPitch - 4 Step 2
         Asm
'...


Edit:
Code:
For col = 0 To scrPitch - 4 Step 4

wirkt schon besser und erreicht ~90-100FPS


Beim versuch Jojo's Rat zu folgen und damit meine eigene noch ein mal etwas zu verbessern scheint mir wohl ein Denkfehler unterlaufen zu sein denn beim splitten der RGB werte und dem verrechnen scheint irgendwie was falsch zu laufen, sehe den Fehler aber irgendwie nicht....

Code:
Sub ScreenSoft() 'by eternalpain
   
    static as Integer       scrWidth, scrHeight, scrPitch
    static as integer ptr   scradr
    Static as Integer       red, green, blue
    static as Integer       pix(0 to 3)
    Static as Integer       XR, YD, y0, y1, x1
   
    Dim rgbadr as byte ptr
   
    If scrPitch=0 Then
        ScreenInfo scrWidth, scrHeight,,,scrPitch
        scrPitch shr = 2
        scradr = screenptr
        scrWidth -= 1 : scrHeight -= 1
    End If
   
   
    For y as Integer = 0 to scrHeight
        If (y < scrHeight) Then YD=1 Else YD = 0 : pix(2) = 0 : pix(3) = 0 : y1 = y0+scrPitch
       
        y0 = y*scrPitch
   
    For x as Integer = 0 to scrWidth
        red = 0 : green = 0 : blue = 0 : x1 = x+1
       
        pix(0) = scradr[x + y0]
       
        If (x1 < scrWidth ) Then XR=1 Else XR = 0 : pix(1) = 0 : pix(3) = 0

        If XR Then pix(1) = scradr[x1 + y0]
       
        If YD Then
            pix(2) = scradr[x + y1]
            If XR Then pix(3) = scradr[x1 + y1]
        End If
           
        For l as Integer = 0 to 3
            rgbadr = cast(ubyte ptr,@pix(l))
            red   += rgbadr[2]
            green += rgbadr[1]
            blue  += rgbadr[0]
        Next l
       
        red   shr = 2
        green shr = 2
        blue  shr = 2
       
        scradr[x + y0] = rgb(red,green,blue)
    Next x
    Next y

End Sub

_________________
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen MSN Messenger
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1208
Wohnort: Ruhrpott

BeitragVerfasst am: 28.03.2015, 21:26    Titel: Antworten mit Zitat

@Eternal_pain: Welchen Effekt möchtest du haben? Soll das Bild nur weichgezeichnet werden, oder soll es langsam verschwinden?

Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Eternal_pain



Anmeldungsdatum: 08.08.2006
Beiträge: 1783
Wohnort: BW/KA

BeitragVerfasst am: 28.03.2015, 21:36    Titel: Antworten mit Zitat

Der optisch unschöne Effekt war wohl der Fehler in der For/Next bzw Step, hatte eben nur einen korrigiert, nachdem ich beide korrigiert hatte sah es richtig aus, hatte dafür aber auch einen Einbruch um rund ~50FPS gebracht zwinkern

Blur brauch man öffters mal, allerdings habe ich mich in diesem Fall nur dafür entschieden weil es eben diesen Effekt hat das die Punkte bzw Linien
langsam verschwinden, oder eben 'Faden/Ausblenden'

Ich glaube bei XP gab es mal ähnliche Standard-Bildschirmschoner, das mit den fliegenden Dreiecken oder so?! (kann mich nicht mehr so ganz erinnern zwinkern)
_________________
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen MSN Messenger
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1208
Wohnort: Ruhrpott

BeitragVerfasst am: 28.03.2015, 21:54    Titel: Antworten mit Zitat

Zitat:
hatte dafür aber auch einen Einbruch um rund ~50FPS gebracht
Ist klar, die Sub muß ja jetzt auch die doppelte Anzahl von Zeilen bearbeiten.

Aber wenn du sagst, daß die anderen 3 Pixel unberührt bleiben, hast du die Arbeitsweise der Assemblerroutine noch nicht verstanden. Der Pointer ptr1 zeigt auf die obere linke Ecke eines 2x2 Pixel großen Quadrates. Die Assemblerroutine holt sich dei Farbwerte aller 4 Pixel, addiert sie, teilt sie durch 4 und schreibt den Durchschnittswert in alle 4 Pixel zurück. Wenn es "nur" ums Weichzeichnen geht, reicht es, jede 2. Zeile ("Step 2") und jede 2. Spalte ("Step 8") anzuspringen. Nach einem Durchlauf ändert sich das Bild dann allerdings auch nicht mehr.

Guß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!


Zuletzt bearbeitet von grindstone am 28.03.2015, 22:05, insgesamt einmal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
RockTheSchock



Anmeldungsdatum: 04.04.2007
Beiträge: 138

BeitragVerfasst am: 28.03.2015, 22:02    Titel: Antworten mit Zitat

Euch ist schon klar, dass der ursprüngliche Algorithmus von eternal pain eine art fading factor enthält, indem das berechnete durchnitsspixel quasi durch 2 geteilt wird. Also 4 pixel werden addiert und statt durch 4 durch 8 geteilt. Mit dem shift left um 2 bzw 3 bits. D.h in der blur2 prozedur muss das entsprechend geändert werden

Code:
psrlw mm0, 2        'summe in mm0 durch 4 teilen

Code:
psrlw mm0, 3        'summe in mm0 durch 8 teilen
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1208
Wohnort: Ruhrpott

BeitragVerfasst am: 28.03.2015, 22:12    Titel: Antworten mit Zitat

Beim Teilen durch 8 verschwindet das Bild viel zu schnell. Der Fadingfaktor ist dadurch gegeben, daß durch die geringere Schrittweite das gerade heruntergerechnete Pixel wieder als Ausgangswert genommen wird.

Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
volta



Anmeldungsdatum: 04.05.2005
Beiträge: 1874
Wohnort: D59192

BeitragVerfasst am: 29.03.2015, 13:18    Titel: Antworten mit Zitat

@grindstone
@Eternal_pain
Wichtg:
Be MMX-Code muss am schluss die 'emms' Anweisung stehen!!!
Code:
 .......
 asm emms
End Sub
Damt werden die MMX - Register für die FPU frei gegeben, sonst kann es zu Abstürzen kommen.
_________________
Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 29.03.2015, 18:07    Titel: Antworten mit Zitat

Ein weiterer Grund, stattdessen SSE zu verwenden. zwinkern
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1208
Wohnort: Ruhrpott

BeitragVerfasst am: 29.03.2015, 19:07    Titel: Antworten mit Zitat

Nur aus Spaß am Programmieren: Hier noch ein reiner Fader ohne Unschärfe. lächeln
Code:
Sub fade()
   Dim As Integer scrWidth, scrHeight, scrPitch, lin, col
   Dim As Byte Ptr ptr1
    
   ScreenInfo scrWidth, scrHeight,,,scrPitch
   For ptr1 = ScreenPtr To ScreenPtr + scrHeight * scrPitch - 1 Step 4
      Asm
         mov eax, [ptr1]     'zeilenpointer in register eax
         pxor mm2, mm2       'register mm2 auf 0 setzen
         movd mm0, [eax]     'pixel in register mm0 laden
         punpcklbw mm0, mm2  'RGBA -> 00rr00gg00bb00aa /inhalte von mm0 und mm2 verschachtelt in mm0 laden --> mm0 entpacken
         movd mm1, [eax]     'pixel in register mm1 laden
         punpcklbw mm1, mm2  'entpacken
         psllw mm0, 8         '*64
         psubw mm0, mm1       '-1
         psrlw mm0, 8         '/64
         packuswb mm0, mm0   '00rr00gg00bb00aa -> RGBA /inhalt von mm0 byteweise packen
         movd [eax], mm0     'wert zurückschreiben
      End Asm
      Asm emms
   Next
End Sub


Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1208
Wohnort: Ruhrpott

BeitragVerfasst am: 31.03.2015, 13:14    Titel: Antworten mit Zitat

Frage an die Experten: Was ist mit den vorherigen Inhalten der verwendeten Register? Die müssten doch eigentlich am Anfang der Assemblersequenz auf den Stack gelegt und am Ende wieder zurückgeholt werden. Oder kümmert sich der Compiler darum?

Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
volta



Anmeldungsdatum: 04.05.2005
Beiträge: 1874
Wohnort: D59192

BeitragVerfasst am: 31.03.2015, 14:26    Titel: Antworten mit Zitat

Hi,
ncht unbedingt!
FB speichert alles in Variablen (Data-Bereich).
Werte mit denen Prozeduren gefüttert werden, werden auf dem Stack übergeben.
Wichtig ist nur das esp-Register (Stackpointer) zu sichern.
Wenn du ein Programm mit der Option -R kompilierst, kannst du dir das in der asm-Datei ansehen.
_________________
Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1208
Wohnort: Ruhrpott

BeitragVerfasst am: 31.03.2015, 15:19    Titel: Antworten mit Zitat

Stimmt. Ist ja eine Sub und kein Interrupt. Ich bin da wohl ein bisschen Microcontrollergeschädigt... lächeln

Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1208
Wohnort: Ruhrpott

BeitragVerfasst am: 03.04.2015, 12:45    Titel: Antworten mit Zitat

So, ich habe die blur-Routine noch ein bisschen getuned. lächeln Bei mir (XP/Pentium 4/3GHz) schafft sie bei 1280 x 1024 Pixel jetzt 70 FPS.
Code:
Sub blur4()
   Dim As Integer scrWidth, scrHeight, scrPitch
   Dim As Byte Ptr image
    
   image = ScreenPtr
   ScreenInfo scrWidth, scrHeight,,,scrPitch
   
   scrWidth -= 1
   scrHeight -= 1
     
   Asm
     mov edx,[scrHeight]     'zeilenzähler
     mov ecx,[scrWidth]      'spaltenzähler
     pxor mm0, mm0           'register mm0 auf 0 setzen
     mov eax,[image]         'bildpointer
     mov ebx,eax
     Add ebx,[scrPitch]      'zeiger auf nächste zeile
     hloop: 'zeilenschleife
        movd mm1,[eax]        '1. pixel links oben holen
        punpcklbw mm1, mm0    'RGBA -> 00rr00gg00bb00aa /inhalte von mm0 und mm1 verschachtelt in mm1 laden --> mm1 entpacken
        movd mm3,[ebx]        '1. pixel links unten
        punpcklbw mm3, mm0    'entpacken
        wloop: 'spaltenschleife
           movd mm2,[eax + 4]  'nächstes rechtes oberes pixel holen
           punpcklbw mm2, mm0  'entpacken
           movd mm4,[ebx + 4]  'nächstes rechtes unteres pixel holen
           punpcklbw mm4, mm0  'entpacken
           paddw mm1,mm2       'summe bilden
           paddw mm1,mm3       '
           paddw mm1,mm4       '
           psrlw mm1, 2        '/4 --> = durchschnitt (linkes oberes pixel)
           movq mm3,mm1        'in linkes unteres pixel kopieren (für nächsten durchlauf)
           movq mm2,mm1        'zum packen nach mm2 kopieren
           packuswb mm2, mm2   '00rr00gg00bb00aa -> RGBA /inhalt von mm2 byteweise packen
           movd [eax],mm2      'oberes linkes pixel zurückschreiben
           movd [ebx],mm2      'unteres linkes pixel zurückschreiben
           Add eax,4           'pointer auf nächstes pixel
           Add ebx,4
         Loop wloop            'nächste spalte
          movd [eax + 4],mm2    'zeilenende -> oberes rechtes pixel zurückschreiben
          movd [ebx + 4],mm2    'unteres rechtes pixel zurückschreiben
          mov ecx,[scrWidth]    'bildbreite für nächsten durchlauf laden
          Sub edx,1             'nächste zeile
       jnz hloop
     emms
   End Asm
End Sub


Gruß
grindstone

EDIT: Noch etwas Feintuning. Schafft jetzt 84 FPS. happy
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
RockTheSchock



Anmeldungsdatum: 04.04.2007
Beiträge: 138

BeitragVerfasst am: 08.04.2015, 00:36    Titel: Blur mit SSE2 Befehlen Antworten mit Zitat

Und das geht noch schneller.

Das movdqu auf den Bildspeicher in der inneren Schleife kann man evt. noch ändern in movdqa. Bringt aber nur ein paar fps. Da ich nicht sicher bin ob der Bildspeicher immer 16 byte aligned ist, ist es sicherer so.
Code:
Sub blur5()
   Dim mask(15) as UByte => { 12,13,14,15,8,9,10,11,4,5,6,7,0,1,2,3 }
   Dim mask2(15) as UByte => { 1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0 }
   
   Dim As Integer scrWidth, scrHeight, scrPitch
   Dim As Byte Ptr image

   image = ScreenPtr
   ScreenInfo scrWidth, scrHeight,,,scrPitch


   'scrWidth -= 1
   scrHeight -=  1

   Asm
      movdqu  xmm3,[mask]      'unaligned mov da sonst unsicher
      movdqu  xmm4,[mask2]     'da 16 byte Boundaries bei Variablen nicht garantiert sind

      mov edx,[scrHeight]      'zeilenzähler
      mov ecx,[scrWidth]       'spaltenzähler

      mov eax,[image]          'bildpointer
      mov ebx,eax
      Add ebx,[scrPitch]       'zeiger auf nächste zeile
      hloop2:                    'zeilenschleife
         wloop2:                 'spaltenschleife
            movdqu  xmm1,[eax] 'lade 4 pixel von oberer Zeile
            movdqu  xmm2,[ebx] 'lade 4 pixel aus unterer Zeile
      
            pavgb  xmm1, xmm2  'berechne durchnittswerte  avg(oben,unten) byteweise   
            
            movdqu  xmm2,xmm1   'kopiere die berechneten Pixeldurschnittswerte in xmm2
            pshufb xmm2,xmm3    'und vertausche jeweils die benachbarten Pixeldurschnittswerte
            
            pavgb  xmm1, xmm2   'berechne aus den 2 Durchschnittswerten von jeweils 2 Pixeln 
                                'den gesamtdurchschnitt von 4 Pixeln also
                                'xmm1 = avg(avg(linksoben,linksunten),avg(rechtssoben,rechtssunten))   
            
      
            psubusb xmm1,xmm4   'fader effect
      
            
            movdqu [eax],xmm1   '4 obere pixel zurückschreiben
            movdqu [ebx],xmm1     '4 untere pixel zurückschreiben
      
            Add eax,16         'pointer auf nächste 4 pixel
            Add ebx,16     
            Sub ecx,4          '4 Pixel weiter
         jnz wloop2            'nächste spalte

   
         mov ecx,[scrWidth]    'bildbreite für nächsten durchlauf laden
         dec edx              'nächste zeile
               
      jnz hloop2
   End Asm
End Sub
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Eternal_pain



Anmeldungsdatum: 08.08.2006
Beiträge: 1783
Wohnort: BW/KA

BeitragVerfasst am: 09.04.2015, 18:35    Titel: Antworten mit Zitat

Also der letzte ist von der Gerschwindigkeit vermutlich fast unschlagbar mit nahezu 300FPS, allerdings glaube ich das dort noch ein schwerer fehler drinne steckt weil es nach einigen Sekunden regelrecht einbricht, runter auf 65FPS auch nach einem neustart... und von der optik her nicht ganz so schick... aber hut ab, gefällt mir lächeln
_________________
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen MSN Messenger
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1208
Wohnort: Ruhrpott

BeitragVerfasst am: 10.04.2015, 01:01    Titel: Antworten mit Zitat

Muß die Maske für pshufb nicht lauten: { 11,10,9,8,15,14,13,12,3,2,1,0,7,6,5,4 } ?

Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Profi-Forum Alle Zeiten sind GMT + 1 Stunde
Gehe zu Seite Zurück  1, 2, 3  Weiter
Seite 2 von 3

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz