110 likes | 234 Vues
This guide provides a step-by-step approach to revising the ‘wfmodel1.cpp’ prototype for smoother page-flipping animation. It explains the mechanics of page-flipping, where the user interacts with two pages in video memory: the 'visible' page and the 'drawing' page. Learn how to utilize the Radeon graphics adapter's capabilities by accessing the CRTC start address to flip between these pages seamlessly. The tutorial also covers installation checks, initialization for device recognition, and includes a practical exercise to spin a wireframe model using asynchronous keyboard input.
E N D
How to do ‘page-flipping’ The steps needed when revising our ‘wfmodel1.cpp’ prototype to achieve ‘smooth’ animation
How page-flipping works The user sees this part of video memory The ‘visible’ page CRTC START-ADDRESS Your program draws to this part of video memory The ‘drawing’ page When the ‘drawing’ page is ready to be viewed, your program changes the CRTC START-ADDRESS and thus the roles of these two pages are ‘flipped’ VRAM
Use a Radeon-specific register • The CRT Controller’s Start-Address can be accessed via a 32-bit register (called CRTC_START) which is part of the ATI Radeon’s 2D drawing engine -- allowing the Start-Address to be reprogrammed as a single atomic operation #define CRTC_START 0x0224
Installation check • The software must detect the presence of a Radeon X300 graphics adapter, and it must discover which i/o port-address got assigned to the Radeon 2D engine during the Operating System’s startup process #define VENDOR_ID 0x1002 // ATI #define DEVICE_ID 0x5B60 // X300
PCI Find Device service init8086(); // initialization for vm8086 vm.regs.eax = 0x1B02; // PCI Find Device vm.regs.ecx = DEVICE_ID; // X300 vm.regs.edx = VENDOR_ID; // ATI vm.regs.esi = 0; // device index int86( 0x1A, vm ); // invoke PCI BIOS if ( vm.regs.eax & 0xFF00 ) exit(1); // failed
PCI Read Configuration Dword vm.regs.eax = 0x1B0A; // PCI Read Dwd vm.regs.edi = 0x0014; // Resource #1 Adr int86( 0x1A, vm ); // invoke PCI BIOS iobase = vm.regs.ecx & 0xFFFFFFFC;
Global Variables int iobase; // value is filled in at runtime int page_size = (2 << 20); // 2-megabytes int drawing_page = 0; // page 0 or page 1 int visible_page = 0; // page 0 or page 1
Hardware helper-function void set_visible_page( void ) { int start_addr = visible_page * page_size; outl( CRTC_START, iobase + 0 ); outl( start_addr, iobase + 4 ); }
Pixel-drawing helper-function void draw_pixel( int x, int y, int color ) { int offset = drawing_page * page+size; unsigned char *dstn = vram + offset; dstn[ y * vres + x ] = color; }
The ‘page-flipping’ algorithm • Main loop: • Compute the new image • Set drawing_page to (visible_page + 1)%2 • Draw next screen image onto drawing page • Set visible_page to equal the drawing_page
In-class exercise • Create a revision of the ‘wfmodel2’ demo (named ‘wfmodel3.cpp’) to automatically spin the wireframe model contiunuously, until the user hits the <ESCAPE>-key • You will need to use a signal-handler and asynchronous keyboard-input notification (as in our earlier ‘persists.cpp’ demo)