1 /* $Id: glfbdevtest.c,v 1.1 2003/08/06 17:47:15 keithw Exp $ */
4 * Test the GLFBDev interface. Only tested with radeonfb driver!!!!
16 #include <sys/ioctl.h>
18 #include <sys/types.h>
23 #include "GL/glfbdev.h"
25 #define DEFAULT_DEPTH 8
27 static struct fb_fix_screeninfo FixedInfo
;
28 static struct fb_var_screeninfo VarInfo
, OrigVarInfo
;
29 static int DesiredDepth
= 0;
30 static int OriginalVT
= -1;
31 static int ConsoleFD
= -1;
32 static int FrameBufferFD
= -1;
33 static caddr_t FrameBuffer
= (caddr_t
) -1;
34 static caddr_t MMIOAddress
= (caddr_t
) -1;
38 print_fixed_info(const struct fb_fix_screeninfo
*fixed
, const char *s
)
40 static const char *visuals
[] = {
41 "MONO01", "MONO10", "TRUECOLOR", "PSEUDOCOLOR",
42 "DIRECTCOLOR", "STATIC_PSEUDOCOLOR"
45 printf("%s info -----------------------\n", s
);
46 printf("id = %16s\n", fixed
->id
);
47 printf("smem_start = 0x%x\n", fixed
->smem_start
);
48 printf("smem_len = %d (0x%x)\n", fixed
->smem_len
, fixed
->smem_len
);
49 printf("type = 0x%x\n", fixed
->type
);
50 printf("type_aux = 0x%x\n", fixed
->type_aux
);
51 printf("visual = 0x%x (%s)\n", fixed
->visual
, visuals
[fixed
->visual
]);
52 printf("xpanstep = %d\n", fixed
->xpanstep
);
53 printf("ypanstep = %d\n", fixed
->ypanstep
);
54 printf("ywrapstep = %d\n", fixed
->ywrapstep
);
55 printf("line_length = %d\n", fixed
->line_length
);
56 printf("mmio_start = 0x%x\n", fixed
->mmio_start
);
57 printf("mmio_len = %d (0x%x)\n", fixed
->mmio_len
, fixed
->mmio_len
);
58 printf("accel = 0x%x\n", fixed
->accel
);
63 print_var_info(const struct fb_var_screeninfo
*var
, const char *s
)
65 printf("%s info -----------------------\n", s
);
66 printf("xres = %d\n", var
->xres
);
67 printf("yres = %d\n", var
->yres
);
68 printf("xres_virtual = %d\n", var
->xres_virtual
);
69 printf("yres_virtual = %d\n", var
->yres_virtual
);
70 printf("xoffset = %d\n", var
->xoffset
);
71 printf("yoffset = %d\n", var
->yoffset
);
72 printf("bits_per_pixel = %d\n", var
->bits_per_pixel
);
73 printf("grayscale = %d\n", var
->grayscale
);
75 printf("red.offset = %d length = %d msb_right = %d\n",
76 var
->red
.offset
, var
->red
.length
, var
->red
.msb_right
);
77 printf("green.offset = %d length = %d msb_right = %d\n",
78 var
->green
.offset
, var
->green
.length
, var
->green
.msb_right
);
79 printf("blue.offset = %d length = %d msb_right = %d\n",
80 var
->blue
.offset
, var
->blue
.length
, var
->blue
.msb_right
);
81 printf("transp.offset = %d length = %d msb_right = %d\n",
82 var
->transp
.offset
, var
->transp
.length
, var
->transp
.msb_right
);
84 printf("nonstd = %d\n", var
->nonstd
);
85 printf("activate = %d\n", var
->activate
);
86 printf("height = %d mm\n", var
->height
);
87 printf("width = %d mm\n", var
->width
);
88 printf("accel_flags = 0x%x\n", var
->accel_flags
);
89 printf("pixclock = %d\n", var
->pixclock
);
90 printf("left_margin = %d\n", var
->left_margin
);
91 printf("right_margin = %d\n", var
->right_margin
);
92 printf("upper_margin = %d\n", var
->upper_margin
);
93 printf("lower_margin = %d\n", var
->lower_margin
);
94 printf("hsync_len = %d\n", var
->hsync_len
);
95 printf("vsync_len = %d\n", var
->vsync_len
);
96 printf("sync = %d\n", var
->sync
);
97 printf("vmode = %d\n", var
->vmode
);
102 signal_handler(int signumber
)
104 signal(signumber
, SIG_IGN
); /* prevent recursion! */
105 fprintf(stderr
, "error: got signal %d (exiting)\n", signumber
);
111 initialize_fbdev( void )
114 int fd
, vtnumber
, ttyfd
;
118 fprintf(stderr
, "error: you need to be root\n");
123 /* open the framebuffer device */
124 FrameBufferFD
= open("/dev/fb0", O_RDWR
);
125 if (FrameBufferFD
< 0) {
126 fprintf(stderr
, "Error opening /dev/fb0: %s\n", strerror(errno
));
131 /* open /dev/tty0 and get the vt number */
132 if ((fd
= open("/dev/tty0", O_WRONLY
, 0)) < 0) {
133 fprintf(stderr
, "error opening /dev/tty0\n");
136 if (ioctl(fd
, VT_OPENQRY
, &vtnumber
) < 0 || vtnumber
< 0) {
137 fprintf(stderr
, "error: couldn't get a free vt\n");
142 /* open the console tty */
143 sprintf(ttystr
, "/dev/tty%d", vtnumber
); /* /dev/tty1-64 */
144 ConsoleFD
= open(ttystr
, O_RDWR
| O_NDELAY
, 0);
146 fprintf(stderr
, "error couldn't open console fd\n");
150 /* save current vt number */
153 if (ioctl(ConsoleFD
, VT_GETSTATE
, &vts
) == 0)
154 OriginalVT
= vts
.v_active
;
157 /* disconnect from controlling tty */
158 ttyfd
= open("/dev/tty", O_RDWR
);
160 ioctl(ttyfd
, TIOCNOTTY
, 0);
164 /* some magic to restore the vt when we exit */
167 if (ioctl(ConsoleFD
, VT_ACTIVATE
, vtnumber
) != 0)
168 printf("ioctl VT_ACTIVATE: %s\n", strerror(errno
));
169 if (ioctl(ConsoleFD
, VT_WAITACTIVE
, vtnumber
) != 0)
170 printf("ioctl VT_WAITACTIVE: %s\n", strerror(errno
));
172 if (ioctl(ConsoleFD
, VT_GETMODE
, &vt
) < 0) {
173 fprintf(stderr
, "error: ioctl VT_GETMODE: %s\n", strerror(errno
));
177 vt
.mode
= VT_PROCESS
;
180 if (ioctl(ConsoleFD
, VT_SETMODE
, &vt
) < 0) {
181 fprintf(stderr
, "error: ioctl(VT_SETMODE) failed: %s\n",
187 /* go into graphics mode */
188 if (ioctl(ConsoleFD
, KDSETMODE
, KD_GRAPHICS
) < 0) {
189 fprintf(stderr
, "error: ioctl(KDSETMODE, KD_GRAPHICS) failed: %s\n",
196 /* open the framebuffer device */
197 FrameBufferFD
= open("/dev/fb0", O_RDWR
);
198 if (FrameBufferFD
< 0) {
199 fprintf(stderr
, "Error opening /dev/fb0: %s\n", strerror(errno
));
204 /* Get the fixed screen info */
205 if (ioctl(FrameBufferFD
, FBIOGET_FSCREENINFO
, &FixedInfo
)) {
206 fprintf(stderr
, "error: ioctl(FBIOGET_FSCREENINFO) failed: %s\n",
211 print_fixed_info(&FixedInfo
, "Fixed");
214 /* get the variable screen info */
215 if (ioctl(FrameBufferFD
, FBIOGET_VSCREENINFO
, &OrigVarInfo
)) {
216 fprintf(stderr
, "error: ioctl(FBIOGET_VSCREENINFO) failed: %s\n",
221 print_var_info(&OrigVarInfo
, "Orig Var");
223 /* operate on a copy */
224 VarInfo
= OrigVarInfo
;
226 /* set the depth, resolution, etc */
229 VarInfo
.bits_per_pixel
= DesiredDepth
;
231 if (VarInfo
.bits_per_pixel
== 16) {
232 VarInfo
.red
.offset
= 11;
233 VarInfo
.green
.offset
= 5;
234 VarInfo
.blue
.offset
= 0;
235 VarInfo
.red
.length
= 5;
236 VarInfo
.green
.length
= 6;
237 VarInfo
.blue
.length
= 5;
238 VarInfo
.transp
.offset
= 0;
239 VarInfo
.transp
.length
= 0;
241 else if (VarInfo
.bits_per_pixel
== 32) {
242 VarInfo
.red
.offset
= 16;
243 VarInfo
.green
.offset
= 8;
244 VarInfo
.blue
.offset
= 0;
245 VarInfo
.transp
.offset
= 24;
246 VarInfo
.red
.length
= 8;
247 VarInfo
.green
.length
= 8;
248 VarInfo
.blue
.length
= 8;
249 VarInfo
.transp
.length
= 8;
251 /* timing values taken from /etc/fb.modes (1280x1024 @ 75Hz) */
252 VarInfo
.xres_virtual
= VarInfo
.xres
= 1280;
253 VarInfo
.yres_virtual
= VarInfo
.yres
= 1024;
254 VarInfo
.pixclock
= 7408;
255 VarInfo
.left_margin
= 248;
256 VarInfo
.right_margin
= 16;
257 VarInfo
.upper_margin
= 38;
258 VarInfo
.lower_margin
= 1;
259 VarInfo
.hsync_len
= 144;
260 VarInfo
.vsync_len
= 3;
265 VarInfo
.vmode
&= ~FB_VMODE_YWRAP
; /* turn off scrolling */
267 /* set new variable screen info */
268 if (ioctl(FrameBufferFD
, FBIOPUT_VSCREENINFO
, &VarInfo
)) {
269 fprintf(stderr
, "ioctl(FBIOPUT_VSCREENINFO failed): %s\n",
274 print_var_info(&VarInfo
, "New Var");
276 if (FixedInfo
.visual
!= FB_VISUAL_TRUECOLOR
&&
277 FixedInfo
.visual
!= FB_VISUAL_DIRECTCOLOR
) {
278 fprintf(stderr
, "non-TRUE/DIRECT-COLOR visuals (0x%x) not supported by this demo.\n", FixedInfo
.visual
);
282 /* initialize colormap */
283 if (FixedInfo
.visual
== FB_VISUAL_DIRECTCOLOR
) {
285 unsigned short red
[256], green
[256], blue
[256];
288 /* we're assuming 256 entries here */
289 printf("initializing directcolor colormap\n");
296 for (i
= 0; i
< cmap
.len
; i
++) {
297 red
[i
] = green
[i
] = blue
[i
] = (i
<< 8) | i
;
299 if (ioctl(FrameBufferFD
, FBIOPUTCMAP
, (void *) &cmap
) < 0) {
300 fprintf(stderr
, "ioctl(FBIOPUTCMAP) failed [%d]\n", i
);
305 * fbdev says the frame buffer is at offset zero, and the mmio region
306 * is immediately after.
309 /* mmap the framebuffer into our address space */
310 FrameBuffer
= (caddr_t
) mmap(0, /* start */
311 FixedInfo
.smem_len
, /* bytes */
312 PROT_READ
| PROT_WRITE
, /* prot */
313 MAP_SHARED
, /* flags */
314 FrameBufferFD
, /* fd */
316 if (FrameBuffer
== (caddr_t
) - 1) {
317 fprintf(stderr
, "error: unable to mmap framebuffer: %s\n",
321 printf("FrameBuffer = %p\n", FrameBuffer
);
324 /* mmap the MMIO region into our address space */
325 MMIOAddress
= (caddr_t
) mmap(0, /* start */
326 FixedInfo
.mmio_len
, /* bytes */
327 PROT_READ
| PROT_WRITE
, /* prot */
328 MAP_SHARED
, /* flags */
329 FrameBufferFD
, /* fd */
330 FixedInfo
.smem_len
/* offset */);
331 if (MMIOAddress
== (caddr_t
) - 1) {
332 fprintf(stderr
, "error: unable to mmap mmio region: %s\n",
335 printf("MMIOAddress = %p\n", MMIOAddress
);
337 /* try out some simple MMIO register reads */
340 typedef unsigned int CARD32
;
341 typedef unsigned char CARD8
;
342 #define RADEON_CONFIG_MEMSIZE 0x00f8
343 #define RADEON_MEM_SDRAM_MODE_REG 0x0158
344 #define MMIO_IN32(base, offset) \
345 *(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset))
346 #define INREG(addr) MMIO_IN32(MMIOAddress, addr)
348 const char *typeStr
[] = {"SDR", "DDR", "64-bit SDR"};
349 sz
= INREG(RADEON_CONFIG_MEMSIZE
);
350 type
= INREG(RADEON_MEM_SDRAM_MODE_REG
);
351 printf("RADEON_CONFIG_MEMSIZE = %d (%d MB)\n", sz
, sz
/ 1024 / 1024);
352 printf("RADEON_MEM_SDRAM_MODE_REG >> 30 = %d (%s)\n",
353 type
>> 30, typeStr
[type
>>30]);
361 shutdown_fbdev( void )
365 printf("cleaning up...\n");
366 /* restore original variable screen info */
367 if (ioctl(FrameBufferFD
, FBIOPUT_VSCREENINFO
, &OrigVarInfo
)) {
368 fprintf(stderr
, "ioctl(FBIOPUT_VSCREENINFO failed): %s\n",
373 munmap(MMIOAddress
, FixedInfo
.mmio_len
);
374 munmap(FrameBuffer
, FixedInfo
.smem_len
);
375 close(FrameBufferFD
);
377 /* restore text mode */
378 ioctl(ConsoleFD
, KDSETMODE
, KD_TEXT
);
381 if (ioctl(ConsoleFD
, VT_GETMODE
, &VT
) != -1) {
383 ioctl(ConsoleFD
, VT_SETMODE
, &VT
);
386 /* restore original vt */
387 if (OriginalVT
>= 0) {
388 ioctl(ConsoleFD
, VT_ACTIVATE
, OriginalVT
);
399 static const int attribs
[] = {
400 GLFBDEV_DOUBLE_BUFFER
,
401 GLFBDEV_DEPTH_SIZE
, 16,
404 GLFBDevContextPtr ctx
;
405 GLFBDevBufferPtr buf
;
406 GLFBDevVisualPtr vis
;
407 int bytes
, r
, g
, b
, a
;
410 printf("GLFBDEV_VENDOR = %s\n", glFBDevGetString(GLFBDEV_VENDOR
));
411 printf("GLFBDEV_VERSION = %s\n", glFBDevGetString(GLFBDEV_VERSION
));
413 /* framebuffer size */
414 bytes
= VarInfo
.xres_virtual
* VarInfo
.yres_virtual
* VarInfo
.bits_per_pixel
/ 8;
416 vis
= glFBDevCreateVisual( &FixedInfo
, &VarInfo
, attribs
);
419 buf
= glFBDevCreateBuffer( &FixedInfo
, &VarInfo
, vis
, FrameBuffer
, NULL
, bytes
);
422 ctx
= glFBDevCreateContext( vis
, NULL
);
425 b
= glFBDevMakeCurrent( ctx
, buf
, buf
);
428 /*printf("GL_EXTENSIONS: %s\n", glGetString(GL_EXTENSIONS));*/
429 glGetIntegerv(GL_RED_BITS
, &r
);
430 glGetIntegerv(GL_GREEN_BITS
, &g
);
431 glGetIntegerv(GL_BLUE_BITS
, &b
);
432 glGetIntegerv(GL_ALPHA_BITS
, &a
);
433 printf("RED_BITS=%d GREEN_BITS=%d BLUE_BITS=%d ALPHA_BITS=%d\n",
436 glClearColor(0.5, 0.5, 1.0, 0);
437 glMatrixMode(GL_PROJECTION
);
439 glFrustum(-1, 1, -1, 1, 2, 30);
440 glMatrixMode(GL_MODELVIEW
);
442 glTranslatef(0, 0, -15);
443 glViewport(0, 0, VarInfo
.xres_virtual
, VarInfo
.yres_virtual
);
444 glEnable(GL_LIGHTING
);
446 glEnable(GL_DEPTH_TEST
);
448 for (ang
= 0; ang
<= 180; ang
+= 15) {
449 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
451 glRotatef(ang
, 1, 0, 0);
452 glutSolidTorus(1, 3, 40, 20);
454 glFBDevSwapBuffers(buf
);
458 b
= glFBDevMakeCurrent( NULL
, NULL
, NULL
);
461 glFBDevDestroyContext(ctx
);
462 glFBDevDestroyBuffer(buf
);
463 glFBDevDestroyVisual(vis
);
468 main( int argc
, char *argv
[] )
470 signal(SIGUSR1
, signal_handler
); /* exit if someone tries a vt switch */
471 signal(SIGSEGV
, signal_handler
); /* catch segfaults */