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