7. Grafikkarten 7.1. Ansicht einer Grafikkarte
Transcription
7. Grafikkarten 7.1. Ansicht einer Grafikkarte
7. Grafikkarten 7.1. Ansicht einer Grafikkarte Video RAM Pixeldaten Erw. Bus Oz.-Quarz Grafikchip PCI Bus Pixeladr Systemprogrammierung II, Winter 2002/03, P. Schulthess & M. Schöttner 191 BIOS-ROM 7.2. Organisation einer Grafikkarte • Vereinfachtes Schema: CmdPipe System RAM bzw. GART Systemprogrammierung II, Winter 2002/03, P. Schulthess & M. Schöttner 2D Engine 3D Engine Video RAM CRT Control RGB Stream Engine AUX BusMaster VGABIOS Pixel Bus AGP/PCI Register CPU 192 • VGA Unterstützung: − − − − − − Text- & Grafikmodus. Basis für den Bootvorgang. BIOS-Routinen zur Konfigurierung. Video-RAM als Bild- & Attributspeicher. CRT-Control: Ablenkung & Synchronisierung. Ca. 60 Steuerregister ab Port $3Bx ansprechbar. • Hostschnittstelle (PCI, AGP, …): − − − − − − Speicherfenster in das Video-RAM. Registersteuerung über Port-Adressen. Speicheradressierbare Register (MMIO). GART: Graphics Address Remapping Table. Übernahme von Grafikbefehlen von der CPU. Daten und Befehle als Bus-Master übertragen. • 2D/3D-Objekte & -Befehle: − BitBlt, Linien, Polygone, Dreiecke, Vierecke, − Displaylisten, Vertex-Listen, Dreiecks-Streifen. Systemprogrammierung II, Winter 2002/03, P. Schulthess & M. Schöttner 193 • Stream-Engine: − − − − Hardwarecursor überlagern. YUV nach RGB konvertieren. Mischen attributierter Pixelströme. Horizontale & vertikale Bildskalierung. • Erweiterungsbus für Zusatzmodule: − MPEG-Decoderchip, − Digitizerzusatz, ... • Effekte: − Füllen, schattieren, beleuchten, überblenden, filtern, Nebel, Texturen, Z-Puffer, αBlending, Clipping, Culling. • Referenzen: − ViRGE Integrated 3D Accelerator, S3 Inc., Aug. 1996. − ATI Radeon Device Driver Development Kit, unveröffentlicht. Systemprogrammierung II, Winter 2002/03, P. Schulthess & M. Schöttner 194 7.3. CRT-Steuerung • Default-Initialisierung mit VGA Werten: − Pixelclock 25,175 MHz − 640*480*60 Hz (16 Farben) = 18,432 MPixel/s + Overhead • Overhead: − Strahlenrücklauf (H+V). − Overscan, Underscan & Randbereich. • Zeitpunkte: − − − − − − − h=horizontal; v=vertical. ehd/evd: end h/v display. shb/svb: start h/v blanking. ehb/evb: end h/v blanking. shr/svr: start h/v retrace. ehr/evr: end h/v retrace. toth/totV: total h/v. Systemprogrammierung II, Winter 2002/03, P. Schulthess & M. Schöttner evr ehd shb evb 0 shr ehr ehb evd svr svb 195 • Monitordaten: − Horizontale Sync.frequenz (in kHz): #horizontale Linien pro Sekunde. − Vertikale Sync.frequenz (in Hz): #vertikaler Durchläufe pro Sekunde. − Video-Bandbreite (in MHz): max. Pixelrate (abzüglich Overhead). • Synchronisierungszeitpunkte: − Active time: Pixel zeichnen. − Blanking time: Synchronisierung. front sync back porch time porch 0 active time totH/totV blanking time • Vgl. B. Zulehner, „SVGA – Treiber für Plurix mit Font“, DA, 1998. Systemprogrammierung II, Winter 2002/03, P. Schulthess & M. Schöttner 196 550 +1 EstimatedHPeriod HFrontPorch = BlankingTime − HSyncTime 2 Systemprogrammierung II, Winter 2002/03, P. Schulthess & M. Schöttner HSyncTime = round totH 100 totH = HActiveTime + BlankingTime 197 Xres * IdealDutyCycle * 2 *8 2 * 8 * (100 − IdealDutyCycle BlankingTime = round HActiveTime = Xres HBackPorch = HSyncTime - HFrontPorch TotalLinear = Yres + round 3 * EstimatedHPeriod * EstimatedVFieldRate 10 * Rfresh IdealDutyCycle =30 − 106 EstimatedVFieldRate = EstimatedHPeriod * TotalLinear 106 −1 EstimatedHPeriod = − 550 * (Yres + 1) Rfresh VESA General Timing Formula (GTF) • Näherung für Timing-Werte (siehe auch www.vesa.org). • Eingabe: Xres, Yres und Rfresh (Bildwiederholrate in Hz). • Horizontales Timing: • Vertikales Timing: VFrontPorch = totH (1 line) VBackPorch = SyncAndBP – VSyncTime VSyncTime = 3*totH (3 lines) totV = Yres + VFrontPorch + SyncAndBP (in lines) 550* Rfresh * (Yres + 1) 106 − 550* Rfresh # " !! SyncAndBP = round • Bemerkung: − Formeln vereinfacht, ohne Ränder & Interlace-Mode. − Diverse Konstanten bereits eingesetzt, z.B. VertSyncAndBackPorch = 550 und PixelsPerCharacter = 8. • Beispiele: Refresh=80Hz, H-Werte in Pixel; V-Werte in Lines Auflösung 640x480 800x600 1024x786 Pixel-Clock 33 MHz 50 MHz 66 MHz HFP 32 40 56 HST 64 88 104 HBP 96 128 160 VFP 1 1 1 • Timing-Register beim S3 Virge Chip sehr verstreut für notorische „Bit-Shifter“ Systemprogrammierung II, Winter 2002/03, P. Schulthess & M. Schöttner 198 VST 3 3 3 VBP 19 23 24 7.4. Sequencer für variable Bildformate • Programmieren der Zeitpunkte für die erweiterte CRT Sequenzsteuerung. • Ausführung als PLL – Phase Locked Loop: Fref 1 N+2 Phasen Diskr. 1 M+2 1 2R Fout toth VCO Floop • Konfigurierung über N, M, R: Fref / (N+2) = Fout * 2R / (M+2) 135 MHz < Floop < 270 MHz ∧ R∈{0,1,2,3} • Programmieren der 2 Taktgeneratoren: − − − − MCLK/DCLK für Taktung Video RAM / Strahlablenkung. Sequencer-Register SR10/11, SR12/13. Indexierter Registerzugriff über $3c4. Entsperren vor dem Zugriff (SR8). Systemprogrammierung II, Winter 2002/03, P. Schulthess & M. Schöttner 199 Beispiel: S3 Virge – PLL für Pixel-Takt konfigurieren public class S3Timing { final static int SeqPort=0x3c4; final static int RefFreq=14318; static void setPixelClock( int pixFreq){ int Fout, M, N=0, R=0, tDiv=1; // (P. Schulthess & O. Marquardt) // Sequencer registers ... // is input to the PLLs, in KHz // pixFreq in KHz, compute R,N,M for Pixelclock // tDiv = Tail Divisor (2R) while ( pixFreq*tDiv<135000) { R++; tDiv*=2; } // min. for Floop = 135 MHz! do { N++; M = pixFreq * ( N+2 ) * tDiv / RefFreq - 2; Fout = ( M+2 )* RefFreq / (N+2 ) / tDiv; } while ( (Fout*200 < pixFreq*199) || (pixFreq*200 < Fout*199)); // freq. still to low? // freq. still to high? setPLL( 0x12, R, N, M); // Set PLLRegister } // misc. access: color, mem. & PLL access, … // e.g. R=1,N=0x14 // e.g. M=0x56 // set Bit5 of SR15 // clear Bit5 toggle $ static void setPLL( int pllInx, int R, int N, int M) { p.Out8(0x3c2, 0x6f); p.wrtinx(SeqPort, pllInx, R*32+N); p.wrtinx(SeqPort, pllInx+1, M); p.setinx(SeqPort, 0x15, 0x20); p.clrinx(SeqPort, 0x15, 0x20); } } Systemprogrammierung II, Winter 2002/03, P. Schulthess & M. Schöttner 200 7.5. Linearer Bildspeicher • Unter DOS ist der Bildspeicher nur stückweise adressierbar: − Jeweils 64 bzw. 128 Kbytes Video RAM gemappt, − Organisation in Farb-Ebenen oder indexed Color. • Linearer Framebuffer: − Eventuell gleichzeitig mit Grafikbeschleunigung, − Verlangt ein 32-Bit Betriebssystem, − Teilweise über VESA-Bios einschaltbar, − Erleichtert die Adressierung, blockweise Übertragungen, aber CPU zeichnet! static void setLinearBuffer ( ) { // use after setGraphicsMode only deviceID = PCI.LookForDevice(PCI.DisplayCntl,0x5333,0x8a1); // search S3 Virge linearBase = PCI.getMEMadress(deviceID) // deviceID = 0x8a1 p.wrtinx(CrtPort, 0x59, linearBase>>>24); // linear base high, CrtPort=0x3d4 p.wrtinx(CrtPort, 0x5a, linearBase>>>16); // linear base low p.wrtinx(CrtPort, 0x58, 0x13); // enable linear addressing (MMIO) } • PCI-Konfigurationsraum gestattet die Relozierung des linearen Puffers. • Jenseits des Framebuffers liegen Register der Grafikengine im Speicher. Systemprogrammierung II, Winter 2002/03, P. Schulthess & M. Schöttner 201 7.6. Registergruppen • VGA-Register: − − − − CRT-Kontroller CR0-CR24 Sequencer Register SR0..4, Grafikkontroller GR0..8, Attributregister AR0..14, • Erweiterung der VGA-Register: − − − − − CRT-Kontroller CR2D-CR6E, Sequencer Register SR8..1C, Variable Bildschirmformate, Variable Pixel-Taktung, Variables Pixelformat ... • S3D Engine: − − − − − Entsperren über CR40, 2D & 3D Befehlsregister, 2D-Bitblock-Transfer & Rechteck füllen 2D-Line- & Polyline zeichnen, 3D Dreieck, 3D Linie, ... Systemprogrammierung II, Winter 2002/03, P. Schulthess & M. Schöttner 202 • S3D Engine Effekte: − − − − − Z-Puffer zur Berechnung der Tiefendarstellung, Hinzumischen von Pixeln durch Alpha-Blending, Ausbleichen von Hintergrundobjekten mit Nebel, Texturierung mit variabler Mustergröße, Anpassung der 3D-Perspektive. • S3D Engine Befehlsregister: − − − − − − − Operationscode Bitblock-Transfer … 3D-Dreieck, Rasteroperation (Source, Pattern, Destination), Eventuell Clipping einschalten, Image-Transfer Modus, Bearbeitungsrichtung, Auto-Execute Modus, 2D/3D Operation. Systemprogrammierung II, Winter 2002/03, P. Schulthess & M. Schöttner 203 2D/3D Register Offsets • Mögliche Basisadressen: − ab rel. Adresse $1000 000 im linearen Framebuffer, − ab $a8000/$b8000 (altes MMIO, Trio-64 Style), − ab Portadresse $a8000 im IO-Adressraum. 0xA0xx 0xA4xx 0xA8xx 0xACxx 0xB0xx 0xB4xx $xx PattRegs Bblt/RctFill 2D Line 2D Polygon 3D Line 3D Triangle D4 Source_Base D8 Destination_Base DC Clip_Left_Right E0 Clip_Top_Bottom E4 Destination & Source Stride E8 MonoPattern 0 Z_Stride EC MonoPattern 1 TxBase F0 PatBgColor TxBrdrColor F4 PatFgColor FogClr F8 Src_BgColor Color 0 FC Src_FgColor Color 1 100 PattrnStrt CmdSet CmdSet CmdSet CmdSet CmdSet 104 a100 RWidHgth TBV 108 to RSrc_XY TBU 10C a1bc RDst_XY TdWdX 110 Texturen .. Systemprogrammierung II, Winter 2002/03, P. Schulthess & M. Schöttner 204 7.7. Beispielprogramm S3MMIO // bounces around a coloured rectangle, using memory mapped accelerator of S3-Virge/385 public class TestS3 { static void start() { int blue=0x001f, yellow=0xffc0; int imgX=200, imgY=100; int x=0, y=0, dx=8, dy=4; S3MMIO.init(); S3MMIO.fill(0, 800, imgX, imgY, yellow); S3MMIO.fill(0, 800, imgX/2, imgY, blue); while (true) { S3MMIO.fill( x, y, imgX, imgY, 0); x = x+dx; if ( (x+dx)<0) dx = - dx; if ( (x+dx+imgX)> = 800) { dx = - dx; y = y + dy; if ( (y+dy )< 0) dy= -dy; if ( (y+dy+imgY) >=600) dy= -dy; } S3MMIO.copy(0, 800, x, y , imgX, imgY, 0); S3MMIO.Retrace(); } // 800x600, 64k cols. // now create offscreen images // clear it // increment rarely // from offScreen // wait to avoid flicker }} Systemprogrammierung II, Winter 2002/03, P. Schulthess & M. Schöttner 205 public class S3MMIO { final static int MemMode = 2; final static int CRTC = 0x3D4; final static int BA = 0xa0000; final static int NoOp_2D= 0x78000000; // 2 byte per pixel // for color mode // old MMIO base // 2D NOP static void copy(int srcX, int srcY, int dstX, int dstY, int dx, int dy, int dir) { int command = 0x01980020 + MemMode; if ( dir==0 ) command = command + 0x06000000; WaitForEngineReady(); Magic.Mem32[BA+0xA504] = ((dx-1)<<16) | dy; Magic.Mem32[BA+0xA508] = (srcX << 16) | srcY; Magic.Mem32[BA+0xA50C] = (dstX << 16) | dstY; Magic.Mem32[BA+0xA500] = command; // bblt } static void fill(int xst, int yst, int dx, int dy, int color) { int cmnd = 0x17E00120 + MemMode; WaitForEngineReady(); Magic.Mem32[BA+0xA4F4] = color; Magic.Mem32[BA+0xA504] = ((dx-1)<<16) | dy; Magic.Mem32[BA+0xA50C] = ( xst <<16) | yst; Magic.Mem32[BA+0xA500] = cmnd; // fill ... } Systemprogrammierung II, Winter 2002/03, P. Schulthess & M. Schöttner 206 static void Retrace() { // test for bit3 @ 0x3da while(((int)Magic.In8(0x3DA)& 8) != 0) ; // wait (vsync is active already running) while(((int)Magic.In8(0x3DA)&8)==0); // wait until vsync starts again } static void WaitForEngineReady() { while( (Magic.Mem32[BA+0x8504] & 0x3F00)!=0x3000) ; // accelerator busy } static void UnlockRegisters() { // extended CRC access p.wrinx( CRTC, 0x38, 0x48); p.wrinx( CRTC, 0x39, 0xA5); } static void init() { Magic.Mem32[BIOS.EAX]=0x4F02; // Vesa-BIOS, set mode Magic.Mem32[BIOS.EBX]=0x114; // 800*600, 64k colors (16 Bit pixel) BIOS.Int(0x10); // BIOS Extension UnlockRegisters(); p.setinx(CRTC, 0x53, 0x10) ; // old-mmio, $a8000 p.setinx(CRTC, 0x3E, 0x10); // FiFo start p.setinx(CRTC, 0x66, 2); // reset S3 Engine p.delay( 100000 ); // >100µs p.clrinx(CRTC, 0x66, 2); // toggle p.setinx(CRTC, 0x66, 1); // start S3 Engine Magic.Mem32[BA+0xA500]=NoOp_2D; Magic.Mem32[BA+0xA4D4]=0; // source base Magic.Mem32[BA+0xA4D8]=0; // dest. base Magic.Mem32[BA+0xA4E4]=(1600<<16)+1600; // src & dst. strides, distance of the pixel below }} Systemprogrammierung II, Winter 2002/03, P. Schulthess & M. Schöttner 207