AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi Alphablending mit MMX / SSE Befehle
Thema durchsuchen
Ansicht
Themen-Optionen

Alphablending mit MMX / SSE Befehle

Ein Thema von schty · begonnen am 13. Dez 2003 · letzter Beitrag vom 2. Jun 2005
Antwort Antwort
schty

Registriert seit: 13. Dez 2003
5 Beiträge
 
Delphi 6 Personal
 
#1

Alphablending mit MMX / SSE Befehle

  Alt 13. Dez 2003, 12:01
Hier gibt's meine 'weiterentwickelte' alpha-blending procedure (sehe unten). Das Original "CombineMem" findet man im Freeware Komponenten-Source "Graphics32" von Alex Denissov.

// Result = Alpha * (Foreground - Background) + Background

Die Ergebnisse fuer R, G und B Werte werden parallel berechnet mit inline MMX / SSE Assembler-Befehle.

Weiss jemandem weitere Optimierungen oder sogar noch schnellere Algorithmen fuer Alphablending?

MfG,
Arjan


Delphi-Quellcode:
procedure AlphaBlend(PenColor:TColor32; DIB:PColor32; Alpha:DWORD);
asm
    MOVD MM1, EAX
// MM1 = 00 00 00 00 ** Fr Fg Fb
    MOVD MM2,[EDX]
// MM2 = 00 00 00 00 ** Br Bg Bb
    PUNPCKLBW MM1, MM0
// MM1 = 00 ** 00 Fr 00 Fg 00 Fb
    MOVD MM3, ECX
// MM3 = 00 00 00 00 00 00 00 AA
    PUNPCKLBW MM2, MM0
// MM2 = 00 ** 00 Br 00 Bg 00 Bb
    PSHUFW MM3, MM3, 0
// MM3 = 00 AA 00 AA 00 AA 00 AA
    PSUBW MM1, MM2
    PSLLW MM2, 8
    PMULLW MM1, MM3
    PADDW MM1, MM2
    PSRLW MM1, 8
    PACKUSWB MM1, MM0
    MOVD [EDX],MM1
end;
[edit=Admin]Code in Tags [delphi ]..[ /delphi] gesetzt. Künftig bitte selber machen. Mfg, Daniel[/edit]
  Mit Zitat antworten Zitat
OregonGhost

Registriert seit: 8. Jun 2002
Ort: Lübeck
1.216 Beiträge
 
Delphi 3 Professional
 
#2

Re: Alphablending mit MMX / SSE Befehle

  Alt 13. Dez 2003, 13:57
Mein letzter Alphablending-Algorithmus sieht so aus:
Code:
__asm {
   pxor MM7, MM7;    // Zero MM7
   movd MM0, dtarget;      // Get Target
   movd MM1, dsource;      // Get Source
   movd MM2, dalpha;      // Alpha packed
   movd MM3, d255;   // 255 für jedes Byte
   punpcklbw MM0, MM7;// Target unpacked
   punpcklbw MM1, MM7;// Source unpacked
   punpcklbw MM2, MM7;// Alpha unpacked
   punpcklbw MM3, MM7;// 255 unpacked
   
   pmullw MM1, MM2; // Multiply source with alpha
   pmullw MM3, MM0; // Multiply target with 255
   pmullw MM0, MM2; // Multiply target with alpha
   psubusw MM3, MM0;// subtract a*tr from ...
   paddusw MM1, MM3; // Add target*255 to source*alpha
   psrlw MM1,8; // Right shift target by 8 (divide by 256)

   packuswb MM1, MM7; // pack target to MM7
   movd dtarget, MM1;
   EMMS;
}
Ich musste allerdings feststellen, dass ein Ausmultiplizieren der Funktion keinen Geschwindigkeitsunterschied bringt (bzw. nur im Mikrosekundenbereich für das gesamte Bild).

Da meine Routine mehr Anweisungen verwendet, müsste sie langsamer sein als deine - Wie schnell ist denn deine?
Meine braucht für ein 256x256-Bild (mit Perpixelalpha und zusätzlichem konstantem Alpha) etwa 4650µs auf meinem Athlon XP 2100+.


Um auf deine Frage zu kommen, noch schneller geht's wahrscheinlich nur, wenn du die Arbeit den 3D-Chip machen lässte ;c)


Was ich noch anmerken möchte: Auf die Formel
Zitat:
Result = Alpha * (Foreground - Background) + Background
bin ich auch gekommen, und sie ist korrekt für Werte zwischen 0 und 1. Wenn du aber Werte von 0 bis 255 hast, sieht das ganze so aus:
Code:
Result = Alpha * Source + (255 - Alpha) * Target
Result = Alpha * Source + 255 * Target - Alpha * Target
Result = Alpha * (Source - Target) + 255 * Target
Und das finde ich in deinem Code nicht wieder. Wenn ich mich recht entsinne, habe ich es mal mit "deiner" Formel ausprobiert und es hat zu unbefriedigenden Ergebnissen geführt.
Oregon Ghost
---
Wenn NULL besonders groß ist, ist es fast schon wie ein bisschen eins.
  Mit Zitat antworten Zitat
schty

Registriert seit: 13. Dez 2003
5 Beiträge
 
Delphi 6 Personal
 
#3

Re: Alphablending mit MMX / SSE Befehle

  Alt 13. Dez 2003, 16:55
Was die absolute Geschwindigkeit angeht, zum Vergleich mit deiner Code, kann ich noch keine genaue Aussagen machen, dafuer fehlt mir noch ein Testprogramm.... ich bin etwas unsicher ueber die Instruction Pairing und SSE Optimierungen usw., ich bin keine Experte. z.B. laut Intel sollte man mit PSHUFW (SSE) gegenueber nur MMX-Befehle 2 Befehle einsparen koennen, ich habe aber nur einer eingespart:

Delphi-Quellcode:
 
// mit PSHUFW (SSE):
 MOVD MM3, ECX
// MM3 = 00 00 00 00 00 00 00 AA 32 BITS -> 64 BITS Alpha
 PSHUFW MM3, MM3, 0
// MM3 = 00 AA 00 AA 00 AA 00 AA

// in MMX sieht das so aus:
 MOVD MM3, ECX
 PUNPCKLWD MM3, MM3
 PUNPCKLQD MM3, MM3

// Was ich eigentlich will ist alles in 1 Befehl, aber das habe ich mit Delphi nicht geschaft:
  PSHUFW MM3, [ECX], 0
// Das geht so nicht, weil mann muss 64 bits (aligned?) uebertragen....
Nun, relativ gesehen bin ich doch um die 50% schneller (auch abhaengig vom Linienlaenge) als der "Graphics32-MMX-Referenz", das hat teilweise aber auch mit der Loop-optimierung zu tun.

Ah, du hast recht. Der Faktor 256 ist nicht im Formel aufgelistet, sondern wird im Code mit den PSSLW (x256) und PSRLW (/256) Befehle geloest. Ich muss sagen dass die Ergebnisse kwalitativ doch ziemlich gut sein koennen, abhaengig vom Anruf.

Im Attachment n' schlechter GIF (in wirklichkeit arbeitet das Programm Bildfehlerfrei) von einem 4xAA Beispiel, also fuer jeden "Punkt" wird "Alphablend" 4x angerufen, vergleichbar mit "DrawLineFS in Graphics32").

Arjan
Miniaturansicht angehängter Grafiken
alphablend_example.gif  
  Mit Zitat antworten Zitat
OLLI_T

Registriert seit: 13. Okt 2003
Ort: Nähe Wetzlar / Hessen
143 Beiträge
 
Delphi 5 Enterprise
 
#4

Re: Alphablending mit MMX / SSE Befehle

  Alt 13. Dez 2003, 17:29
Hallo Arjan!

Leider kennt mein Delphi 5 keine MMX Assembler Anweisungen. Mit welcher Delphi Version arbeitest Du? Dein Funktion gefällt mir nämlich sehr gut! Ich denke mehr lässt sich daran nicht optimieren. Allenfalls ab einer beliebiegen Schwelle 1 addieren, um den kleinen Fehler, der durch SHR 8 gemacht wird, zu kompensieren.

@OregonGhost:

Deine "Formelsammlung" ist leider nicht richtig. Du hast generell vergessen, durch 255 zu dividieren (optimiert SHR 8 )

Result := Alpha * (FG - BG) SHR 8 + BG; // für Alpha = 0..255
Gruss

OLLI
No Pain No Gain!
  Mit Zitat antworten Zitat
schty

Registriert seit: 13. Dez 2003
5 Beiträge
 
Delphi 6 Personal
 
#5

Re: Alphablending mit MMX / SSE Befehle

  Alt 14. Dez 2003, 02:29
Hallo OLLI!

Schoenen Dank fuer deine Interesse und Bemerkungen. Tatsaechlich sollte man fuer sehr exakte Ergebnisse noch einer dazu zaehlen....

Ab Delphi 6 kann man MMX, SSE (integer&float) und ich glaube auch SSE2 direkt im inline-Assembler nutzen! Aber pas auf: die Kombination van MMX und SSE Integer Befehle wird nur ab Pentium III / Athlon CPU unterstuetzt. SSE Float und SSE2 sind nicht AMD-Compatible (dafuer gibt's 3D Now), aber vielleicht doch wieder mit den neuen Athlon XP's (3d Now Pro)?.

Arjan
  Mit Zitat antworten Zitat
OregonGhost

Registriert seit: 8. Jun 2002
Ort: Lübeck
1.216 Beiträge
 
Delphi 3 Professional
 
#6

Re: Alphablending mit MMX / SSE Befehle

  Alt 14. Dez 2003, 19:29
@OLLI_T: halbrichtig.
Das Ergebnis meiner Formel ist in der Tat ein Wert zwischen 0 und 65535, der noch durch 256 geteilt werden muss. Wenn du in meinen Code schaust, wirst du feststellen, dass ich das durchaus getan habe, aber das ist nicht der Punkt. Die Multiplikation muss an dieser Stelle mit 255 und nicht mit 256 erfolgen, zumindest wenn man die Formel so verwendet wie ich sie verwendet habe, um korrekte Ergebnisse zu erzielen (auch wenn der Unterschied marginal ist).

Ich benutze übrigens dafür Visual C++ 6 SP5 mit Processor Pack, weil meine Delphi-Version(en) leider nicht die erweiterten Instruktionen unterstützen.
Oregon Ghost
---
Wenn NULL besonders groß ist, ist es fast schon wie ein bisschen eins.
  Mit Zitat antworten Zitat
schöni

Registriert seit: 23. Jan 2005
Ort: Dresden
445 Beiträge
 
Delphi 7 Personal
 
#7

Re: Alphablending mit MMX / SSE Befehle

  Alt 1. Jun 2005, 21:30
Hallo!

Bei dieser Problematik frag ich gleich mal hier, wo man zu MMX- und SSE Befehlssatz ein gutes Handbuch findet. Ich kann nämlich mit den MMX und SSE Zeug gar nix anfangen. Ich muß mich da erst mal schlau machen.

Danke für Eure Hilfe

Schöni
Damit der Topf nicht explodiert, lässt man es ab und zu mal zischen.
  Mit Zitat antworten Zitat
Benutzerbild von BenBE
BenBE

Registriert seit: 3. Apr 2005
Ort: Jahnsdorf
48 Beiträge
 
Delphi 5 Enterprise
 
#8

Re: Alphablending mit MMX / SSE Befehle

  Alt 1. Jun 2005, 22:42
Kurz-Referenz gibt's in der Ge-packt-Reihe vom mitp-Verlag. Einfach dort mal gucken.
Benny Baumann
Je komplexer das System, desto kleiner die Fehler; je kleiner die Fehler, desto häufiger ihr Auftreten!
  Mit Zitat antworten Zitat
schöni

Registriert seit: 23. Jan 2005
Ort: Dresden
445 Beiträge
 
Delphi 7 Personal
 
#9

Re: Alphablending mit MMX / SSE Befehle

  Alt 1. Jun 2005, 23:43
Hallo BenBE!

Danke für den Tipp. Werde danach suchen.

Schöni
Damit der Topf nicht explodiert, lässt man es ab und zu mal zischen.
  Mit Zitat antworten Zitat
snapman
(Gast)

n/a Beiträge
 
#10

Re: Alphablending mit MMX / SSE Befehle

  Alt 2. Jun 2005, 00:05
was ist eigentlich alpha blending?
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:10 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz