movq lahm?



  • Hi,

    bin noch Anfänger in asm und wollte mit ein bissel inline-Assembler ( in VC++ ) mit MMX in DirectDraw Alphablending realisieren. Dazu hab ich folgende Funktion gebastelt:

    void Surface::BlendDark (const unsigned long color)
    {
    	unsigned char * data;
    	unsigned long pitch;
    
    	this->Lock(&data,pitch);
    
    	pitch -= width * 4;
    
    	_asm
    	{
    		mov ebx, data
    		mov ecx, this
    		add ecx, height
    		mov ecx, dword ptr[ecx]
    		movd mm0, color
    		psllq mm0, 32
    		movd mm2, color
    		por mm0, mm2
    
    		LoopY:
    
    		mov eax, this
    		add eax, width
    		mov eax, dword ptr[eax]
    		shr eax, 1
    
    		LoopX:
    
    		movq mm1, dword ptr[ebx]
    		psubusb mm1, mm0
    		movq dword ptr[ebx], mm1
    
    		add ebx, 8
    
    		dec eax
    		jnz LoopX
    
    		add ebx, pitch
    
    		dec ecx
    		jnz LoopY
    
    		emms
    	}
    
    	this->Unlock();
    }
    

    So, das klappt auch, es gibt nur ein Problem: Ich hab 2 - 3 fps 🙄
    Und was mir dabei aufgefallen ist, dass

    movq mm1, dword ptr[ebx]
    [...]
    movq dword ptr[ebx], mm1
    

    am meisten Zeit schlucken, wenn ich die beiden auskommentieren, hab ich gleich 600-700 fps mehr? 😮 Was mach ich da falsch bzw. wie macht man das richtig? 😕



  • Liegt die Surface vielleicht im Grafikspeicher? Diesen auslesen ist immer lahm.



  • Ja aber durchs Locken sollte sie doch theoretisch in den Systemspeicher geladen werden (?). Aber selbst wenn ich die Surface nicht im Grafikspeicher erzeuge, kommt dasselbe raus. 😞



  • Das wird nicht in den Systemspeicher kopiert beim Locken, das wäre ja noch langsamer. Hast du dir über's Alignment schon mal Gedanken gemacht? Wenn das nicht alles auf 8 Byte aligned ist, kann's auch sehr langsam sein.



  • Hmm, habs mal mit nem "normalen" Pointer probiert, hab damit immerhin ca. 90. 🙄

    Hast du dir über's Alignment schon mal Gedanken gemacht? Wenn das nicht alles auf 8 Byte aligned ist, kann's auch sehr langsam sein.

    Ja, ist der BackBuffer( 800x600 ), sollte also ein Vielfaches von 8 sein.

    Also kann man das nicht irgendwie beschleunigen? 😞



  • Es kommt nicht darauf an das 800c600 ein vielfaches von 8 ist sondern ob die Speicherstelle bei der der erste Wert liegt durch 8 ohne Rest teilbar ist das und somit das Lesn der8 Bytes die auf einmnal vom System gelesen werden mit einem Zugriff stattfinden und nicht mit mindestens 2 inclusive Schiebeoperationen



  • Naja, hat sich jetzt erledigt, bei DirectDraw kann man Fadein/out durch das GammaControl ganz einfach realisieren, da brauch ich das nicht so zu machen. 🙂


Anmelden zum Antworten