![]() |
Alphablending mit MMX / SSE Befehle
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:
[edit=Admin]Code in Tags [delphi ]..[ /delphi] gesetzt. Künftig bitte selber machen. Mfg, Daniel[/edit]
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; |
Re: Alphablending mit MMX / SSE Befehle
Mein letzter Alphablending-Algorithmus sieht so aus:
Code:
Ich musste allerdings feststellen, dass ein Ausmultiplizieren der Funktion keinen Geschwindigkeitsunterschied bringt (bzw. nur im Mikrosekundenbereich für das gesamte Bild).
__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; } 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:
Code:
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.
Result = Alpha * Source + (255 - Alpha) * Target
Result = Alpha * Source + 255 * Target - Alpha * Target Result = Alpha * (Source - Target) + 255 * Target |
Re: Alphablending mit MMX / SSE Befehle
Liste der Anhänge anzeigen (Anzahl: 1)
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:
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. // 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.... 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 |
Re: Alphablending mit MMX / SSE Befehle
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 )
Delphi-Quellcode:
Result := Alpha * (FG - BG) SHR 8 + BG; // für Alpha = 0..255
Gruss OLLI |
Re: Alphablending mit MMX / SSE Befehle
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 |
Re: Alphablending mit MMX / SSE Befehle
@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. |
Re: Alphablending mit MMX / SSE Befehle
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 |
Re: Alphablending mit MMX / SSE Befehle
Kurz-Referenz gibt's in der Ge-packt-Reihe vom mitp-Verlag. Einfach dort mal gucken.
|
Re: Alphablending mit MMX / SSE Befehle
Hallo BenBE!
Danke für den Tipp. Werde danach suchen. Schöni |
Re: Alphablending mit MMX / SSE Befehle
was ist eigentlich alpha blending?
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:49 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz