PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Wieso ist glRealPixels sooooo langsam?


Bertl
2002-09-21, 13:51:12
Meine Applikation laeuft zur Zeit auf Wildcat 6210 und da dauert ein glReadPixel von 720x576x32bit etwa 3 ms.

Ich teste zur Zeit eine Radeon 9700 und die Performance der Karte ist wirklich super, abgesehen von ein paar kleinen Renderfehlern :-)))

Aber leider dauert das glReadPixels etwa 200 ms!!!!! Es ist der gleiche Code und die gleiche Maschine! Ich hab nur die Wildcat 6210 gegen die Radeon getauscht (und natuerlich die Treiber installiert :-)

Gibts eine schnellere Moeglichkeit (etwa 100 mal schneller :-) den Framebufferinhalt auf der Radeon 9700 ins Ram zu bekommen?

Bertl

Demirug
2002-09-21, 14:49:18
Ich kann dir zwar mit deinem spezifischen Problem nicht helfen, aber eine allgemeine Anmerkung zu dem Komplex will ich dir doch geben.

Das Rücklesen des Framebuffers von der CPU aus ist auf allen Consumerkarten recht langsam weil das AGP-Interface dieser Chips dafür nicht ausgelegt ist das man Daten von Grafikkarten-Ram wieder zurück in den "normalen" Arbeitsspeicher kopiert.

Bertl
2002-09-21, 14:59:16
Nun ja, sowas hab ich mir schon gedacht :-(

Glaubst du, dass das eine "Hardwarelimitierung ist" oder kann ein besserer Treiber helfen?

Gibts einen anderen Weg den Framebuffer zu bekommen? Ich hab zum Beispiel schon in eine Textur gerendert und mit glGetTexImage gelesen, aber das hat bei 512x256x32bit 6ms gedauert. 6ms sind nicht schlecht (immer noch zu langsam :-), aber ich brauch mindestens 720x576x32bit (oder 720x288x32bit) und das heisst, dass meine Textur mindestens 1024x512 Pixel gross sein muss :-((( Dann bin ich wieder auf 24ms. Ein glGetSubTexImage gibts leider nicht :-)

Eine funktionierende Loesung liegt bei < 4ms fuer 720x288x32bit.

Bertl

Demirug
2002-09-21, 15:03:08
AFAIK ist das eine Hardwarelimitierung da man einiges an Transitoren sparen kann wenn man keinen schnellen rückkanal einbaut.

Was machts du überhaupt das es erfordert den Framebuffer zurückzulesen?

Bertl
2002-09-21, 15:28:07
Ich arbeite in meiner Firma an der Enwicklung von Echtzeit Render Software fuer den Fernsehmarkt. Viz heisst das Ding und wenn du z.B. NTV, N24, Premiere, Sat1, ORF, CNN, CBS, SKY ..... schaust, kannst du meine Software (nun ich hab sie nicht alleine geschrieben :-) On Air sehen.

Die Software ist unter OpenGL und C++ geschreiben und laeuft auf SGI Onyx2 IR2/3/4 und Windows (Wildcat 6210). Der Output muss Digitial Video (Pal, NTSC) sein und das macht die Onyx sozusagen selber (GVO Board - Graphics to Video Option) und am PC lesen wir den Framebuffer und schreiben ihn 50 mal in der Sekunde (oder 60 bei NTSC) per PCI in eine Digital Video IO Karte (Digital Voodoo oder ClipStation). Das funktioniert auch recht gut, aber wir sind natuerlich immer auf der Suche nach neuer schneller Hardware und da ist die Radeon 9700 wirklich beeindruckend! Wenn nur das ReadPixels schneller waere :-)

Bertl

ow
2002-09-21, 17:55:58
Schon mal eine Geforce Karte probiert?

Demirug
2002-09-21, 18:18:04
ow,

AFAIK habe die Geforce Karten das gleiche Problem.

Bertl
2002-09-21, 18:59:25
Stimmt! GForce 2/3/4 haben das gleiche Problem. Es scheint, dass alle "Gamer Karten" das glReadPixels extrem langsam ausfuehren.

Bertl

zeckensack
2002-09-21, 19:09:52
Das Datenformat muß halbwegs stimmen.
'Raketenschnell' wie in der Werbung wird es nicht werden, aber versuch's mal so:

glReadPixels(x,y,w,h,GL_RGBA,GL_UNSIGNED_BYTE,blablub);

Ist zumindest bei mir wesentlich (!) schneller als GL_RGB (ohne A).

Versuch auch mal GL_BGRA_EXT oder sowas.

ow
2002-09-21, 19:15:48
Von der SPEC gab´s mal einen Test (GLperf 3.1.2), der die Geschwindigkeit verschiedener Funktionen testet.

Hier die ReadPixels für eine Kyro1 (115/115) auf XP1700:

1560000 pixels per second with ReadPixels -- ReadPixels (Immediate, RGB, ubyte, 16x16)
Test Type ReadPixelsTest
GLperf Script File Name ReadPixl.rgb 0.3
Print Mode Delta True
Print Mode Delta from Default State False
Print Mode Microseconds False
Print Mode Pixels Per Second True
GLperf Version 3.1.2
Execute Mode Immediate
Number of Objects 1
Vertices Unrolled in Inner Loop 1
Function Pointers Used in Inner Loop Off
Modulo 4096 of Data Alignment 0
Month 3
Day 31
Year 2002
Host PC
Operating System Microsoft Win32s with Windows 3.1
Operating System Version Version 4.10 (Build 67766222: )
Host Vendor unknown
Host Model unknown
Host CPU AMD Athlon(tm) XP processor 1700+
Host CPU Count unknown
Host Memory Size 255
Host Primary Cache Size unknown
Host Secondary Cache Size unknown
Window System Win32
Driver Version unknown
OpenGL Vendor IMAGINATION TECHNOLOGIES
OpenGL Version 1.2.1
OpenGL Extensions GL_ARB_multisample GL_ARB_multitexture GL_ARB_texture_compression GL_ARB_texture_env_add GL_ARB_texture_env_combine GL_ARB_texture_env_dot3 GL_EXT_abgr GL_EXT_bgra GL_EXT_compiled_vertex_array GL_EXT_draw_range_elements GL_EXT_packed_pixels GL_EXT_secondary_color GL_EXT_separate_specular_color GL_EXT_stencil_wrap GL_EXT_texture3D GL_EXT_texture_compression_s3tc GL_EXT_texture_env_add GL_EXT_texture_env_combine GL_EXT_texture_filter_anisotropic GL_EXT_vertex_array GL_S3_s3tc WGL_ARB_extensions_string WGL_EXT_swap_control
OpenGL Renderer PowerVR KYRO
OpenGL Client Vendor IMAGINATION TECHNOLOGIES
OpenGL Client Version 1.2.1
OpenGL Client Extensions GL_ARB_multisample GL_ARB_multitexture GL_ARB_texture_compression GL_ARB_texture_env_add GL_ARB_texture_env_combine GL_ARB_texture_env_dot3 GL_EXT_abgr GL_EXT_bgra GL_EXT_compiled_vertex_array GL_EXT_draw_range_elements GL_EXT_packed_pixels GL_EXT_secondary_color GL_EXT_separate_specular_color GL_EXT_stencil_wrap GL_EXT_texture3D GL_EXT_texture_compression_s3tc GL_EXT_texture_env_add GL_EXT_texture_env_combine GL_EXT_texture_filter_anisotropic GL_EXT_vertex_array GL_S3_s3tc WGL_ARB_extensions_string WGL_EXT_swap_control
GLU Version 1.2.2.0 Microsoft Corporation
GLU Extensions GL_EXT_bgra
Direct Rendering False
Double Buffer True
Stereo False
RGBA True
Color Index Size -1
Red Size 8
Green Size 8
Blue Size 8
Alpha Size 8
Accum Red Size 0
Accum Green Size 0
Accum Blue Size 0
Accum Alpha Size 0
Depth Size 16
Stencil Size 0
Auxiliary Buffer Count 0
Frame BufferLevel 0
Window Width 600
Window Height 600
Screen Width 1024
Screen Height 768
PixelMap Color False
PixelMap Stencil False
PixelTransfer Red Scale Factor 1.000000
PixelTransfer Red Bias Factor 0.000000
PixelTransfer Green Scale Factor 1.000000
PixelTransfer Green Bias Factor 0.000000
PixelTransfer Blue Scale Factor 1.000000
PixelTransfer Blue Bias Factor 0.000000
PixelTransfer Alpha Scale Factor 1.000000
PixelTransfer Alpha Bias Factor 0.000000
PixelTransfer Index Shift 0
PixelTransfer Index Offset 0
PixelTransfer Depth Scale Factor 1.000000
PixelTransfer Depth Bias Factor 0.000000
PixelMap R to R Size 1
PixelMap G to G Size 1
PixelMap B to B Size 1
PixelMap A to A Size 1
PixelMap I to R Size 1
PixelMap I to G Size 1
PixelMap I to B Size 1
PixelMap I to A Size 1
PixelMap I to I Size 1
PixelMap S to S Size 1
Image Format GL_RGB
Image Type GL_UNSIGNED_BYTE
Image Alignment 4
Image Swap Bytes False
Image LSB First False
Image Width 16
Image Height 16
Width of ReadPixels 16
Height of ReadPixels 16
Read Buffer GL_FRONT
Order in which Images/Bitmaps/Text are Read Spaced

1580000 pixels per second with ReadPixels -- ReadPixels (Immediate, RGB, ubyte, 32x32)
Image Width 32
Image Height 32
Width of ReadPixels 32
Height of ReadPixels 32

1590000 pixels per second with ReadPixels -- ReadPixels (Immediate, RGB, ubyte, 64x64)
Image Width 64
Image Height 64
Width of ReadPixels 64
Height of ReadPixels 64

1590000 pixels per second with ReadPixels -- ReadPixels (Immediate, RGB, ubyte, 128x128)
Image Width 128
Image Height 128
Width of ReadPixels 128
Height of ReadPixels 128

1590000 pixels per second with ReadPixels -- ReadPixels (Immediate, RGB, ubyte, 256x256)
Image Width 256
Image Height 256
Width of ReadPixels 256
Height of ReadPixels 256

1590000 pixels per second with ReadPixels -- ReadPixels (Immediate, RGB, ubyte, 512x512)
Image Width 512
Image Height 512
Width of ReadPixels 512
Height of ReadPixels 512

1680000 pixels per second with ReadPixels -- ReadPixels (Immediate, RGBA, ubyte, 16x16)
Image Format GL_RGBA
Image Width 16
Image Height 16
Width of ReadPixels 16
Height of ReadPixels 16

1720000 pixels per second with ReadPixels -- ReadPixels (Immediate, RGBA, ubyte, 32x32)
Image Width 32
Image Height 32
Width of ReadPixels 32
Height of ReadPixels 32

1740000 pixels per second with ReadPixels -- ReadPixels (Immediate, RGBA, ubyte, 64x64)
Image Width 64
Image Height 64
Width of ReadPixels 64
Height of ReadPixels 64

1850000 pixels per second with ReadPixels -- ReadPixels (Immediate, RGBA, ubyte, 128x128)
Image Width 128
Image Height 128
Width of ReadPixels 128
Height of ReadPixels 128

1850000 pixels per second with ReadPixels -- ReadPixels (Immediate, RGBA, ubyte, 256x256)
Image Width 256
Image Height 256
Width of ReadPixels 256
Height of ReadPixels 256

1850000 pixels per second with ReadPixels -- ReadPixels (Immediate, RGBA, ubyte, 512x512)
Image Width 512
Image Height 512
Width of ReadPixels 512
Height of ReadPixels 512

Bertl
2002-09-21, 20:07:12
Ich hab schon alle moeglichen und unmoeglichen Pixelformate probiert. RGB ist sowieso keine Option weil ich unbedingt das Alpha brauch! Aber danke fuer die Tips.

an ow: Wenn ich von 1.850.000 Pixel ausgehe, heisst das ich 37.000 Pixel per Frame lesen (bei 50fps) und da mach ich nichts anderes als Pixel in den Hauptspeicher zu schieben :-((( Ich brauchen aber 414.720 Pixel (720x576)! Ich hab dafuer aber nicht den ganzen Frame Zeit, weil ich rendern aus noch muss :-) Ein Overhead von 20% fuer das ReadPixels pro Frame waere gerade noch zu verkraften. Also das heisst, dass ich 20% von 20ms fuer 414.720 Pixel Zeit hab. Das ware dann eine Transferrate von 103.680.000 Pixel pro Sekunde. (etwa 400Mb/sec). Die Wildcat 6210 schafft das!

Wer mir Code beschafft der ein glReadPixel 720x576x32bit auf der Radeon 9700 unter 4ms schafft, bekommt von mir ein Bier (oder auch 2 :-)))

Bertl

ow
2002-09-21, 20:26:20
Naja, der Kyro ist sicher nicht der schnellste bei einer solchen Operation.

Aber ob irgendeine Consumerkarte 103MPix/s ausliest wage ich doch zu bezweifeln.

Pitchfork
2002-09-21, 20:41:10
Das Problem ist, daß die meisten Treiber keinen DMA Transfer initiieren beim Readback von der GPU, sondern Dword für Dword mit der CPU pollen.
Ich weiß jetzt nicht, ob die Karten überhaupt in der Lage sind, einen DMA Transfer in der Richtung auszuführen, aber die AGP Specs sehen das durchaus vor (ist ja nix anderes als eine erweitere PCI Spec, die das durchaus kann).
Es gibt ein paar Leute, die meckern deshalb schon seit Jahren rum (machen auch Video Apps), aber es scheint im Consumerbereich die IHVs nicht genügend zu interessieren.

vogel
2002-09-24, 09:52:18
Originally posted by Pitchfork
Ich weiß jetzt nicht, ob die Karten überhaupt in der Lage sind, einen DMA Transfer in der Richtung auszuführen.
Soweit ich weis, ja. Wird aber von den wenigsten (keinen?) Treibern beschleunigt.

Man sollte auch nicht vergessen, dass bei einem "geswizzelten" Framebuffer dieser "ungeswizzelt" (hehe) werden muss.

-- Daniel, Epic Games Inc.

Bertl
2002-09-24, 17:54:40
Stimmt! Aber das mit dem "geswizzeln" kann man auf der zweiten CPU machen bevor wir das Bild in die Videokarte schieben. Es ist mir eigenlich egal in welchen Format ich den Framebuffer im Ram stehen hab.

Bertl

Demirug
2002-09-24, 18:40:31
Bertl,

was Daniel meint ist das in dem fall das die Daten im Grafikspeicher "geswizzelt" sind der OpenGL die Daten nicht nur aus dem Grafikspeicher ausslesen muss sonder auch noch in das angeforderte Format wandeln muss. Mit zweiter CPU ist da wahrscheinlich nicht viel drin da im RAM immer das angeforderte Format steht.

aths
2002-09-25, 23:01:45
Was ist denn ein geswizzelter Framebuffer?

Demirug
2002-09-25, 23:22:22
aths,

ein Framebuffer ist dann "geswizzelt" wenn die einzelnen RGBA Teile in einer anderen Reihenfolge als RGBA gespeichert sind.

Beispiele:

ARGB
ABGR
BGRA
GRBA

usw.

zeckensack
2002-09-25, 23:26:00
Originally posted by aths
Was ist denn ein geswizzelter Framebuffer? Ein Framebuffer, der nicht Zeilenweise von oben nach unten, und von links nach rechts die rgb-Werte enthält, sondern irgendwie durcheinandergewürfelt ist.

Ich weiß nicht genau wieso sich das lohnt, aber anscheinend machen das einige Grafikchips so.

Bei Texturen ist das übrigens üblich, und im Gegensatz zum Framebuffer kann ich mir da sogar selbst zusammenreimen, warum es vorteilhaft ist.

edit:
Demirug's Variante klingt eigentlich wesentlich plausibler als meine :| =)

Xmas
2002-09-26, 14:23:29
Originally posted by zeckensack
edit:
Demirug's Variante klingt eigentlich wesentlich plausibler als meine :| =)
Nö, sind beide plausibel ;)

Demirug
2002-09-29, 09:48:02
zeckensack,

am Ende ist es ja egal wie die Daten wirklich im Speicher liegen. wenn das Format nicht mit dem gewünschten übereinstimmt und die GPU das bei auslesen nicht ändert muss die CPU ran.

Bertl,

ich habe gerade ein paar neue informationen im Zusammenhang bekommen. Scheinbar hat NVIDIA in den neuen 40.71 Detonatoren jetzt auch einen AGP rückkanal freigegeben. Jemand hat mit einer alten TNT2 und einer TI4200 Messungen gemacht (mit DX 8.1).

TNT2 mit 440BX und Celeron:
Alter Treiber: 9MB/s bei 100% CPU auslastung
40.71 : 135MB/s bei minimaler CPU auslastung

TI4200 mit I815:
Alter Treiber: 9MB/s bei 100% CPU auslastung
40.71 : 175MB/s bei minimaler CPU auslastung

Das ganze war also entgegen meiner bisherigen Meinung nur eine Treiberlimitierung.