Clone of mesa.
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

glfbdevtest.c 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  1. /* $Id: glfbdevtest.c,v 1.1 2003/08/06 17:47:15 keithw Exp $ */
  2. /*
  3. * Test the GLFBDev interface. Only tested with radeonfb driver!!!!
  4. */
  5. #include <assert.h>
  6. #include <errno.h>
  7. #include <signal.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <fcntl.h>
  12. #include <unistd.h>
  13. #include <sys/ioctl.h>
  14. #include <sys/mman.h>
  15. #include <sys/types.h>
  16. #include <linux/fb.h>
  17. #include <linux/kd.h>
  18. #include <linux/vt.h>
  19. #include <GL/glut.h>
  20. #include "GL/glfbdev.h"
  21. #define DEFAULT_DEPTH 8
  22. static struct fb_fix_screeninfo FixedInfo;
  23. static struct fb_var_screeninfo VarInfo, OrigVarInfo;
  24. static int DesiredDepth = 0;
  25. static int OriginalVT = -1;
  26. static int ConsoleFD = -1;
  27. static int FrameBufferFD = -1;
  28. static caddr_t FrameBuffer = (caddr_t) -1;
  29. static caddr_t MMIOAddress = (caddr_t) -1;
  30. static void
  31. print_fixed_info(const struct fb_fix_screeninfo *fixed, const char *s)
  32. {
  33. static const char *visuals[] = {
  34. "MONO01", "MONO10", "TRUECOLOR", "PSEUDOCOLOR",
  35. "DIRECTCOLOR", "STATIC_PSEUDOCOLOR"
  36. };
  37. printf("%s info -----------------------\n", s);
  38. printf("id = %16s\n", fixed->id);
  39. printf("smem_start = 0x%x\n", fixed->smem_start);
  40. printf("smem_len = %d (0x%x)\n", fixed->smem_len, fixed->smem_len);
  41. printf("type = 0x%x\n", fixed->type);
  42. printf("type_aux = 0x%x\n", fixed->type_aux);
  43. printf("visual = 0x%x (%s)\n", fixed->visual, visuals[fixed->visual]);
  44. printf("xpanstep = %d\n", fixed->xpanstep);
  45. printf("ypanstep = %d\n", fixed->ypanstep);
  46. printf("ywrapstep = %d\n", fixed->ywrapstep);
  47. printf("line_length = %d\n", fixed->line_length);
  48. printf("mmio_start = 0x%x\n", fixed->mmio_start);
  49. printf("mmio_len = %d (0x%x)\n", fixed->mmio_len, fixed->mmio_len);
  50. printf("accel = 0x%x\n", fixed->accel);
  51. }
  52. static void
  53. print_var_info(const struct fb_var_screeninfo *var, const char *s)
  54. {
  55. printf("%s info -----------------------\n", s);
  56. printf("xres = %d\n", var->xres);
  57. printf("yres = %d\n", var->yres);
  58. printf("xres_virtual = %d\n", var->xres_virtual);
  59. printf("yres_virtual = %d\n", var->yres_virtual);
  60. printf("xoffset = %d\n", var->xoffset);
  61. printf("yoffset = %d\n", var->yoffset);
  62. printf("bits_per_pixel = %d\n", var->bits_per_pixel);
  63. printf("grayscale = %d\n", var->grayscale);
  64. printf("red.offset = %d length = %d msb_right = %d\n",
  65. var->red.offset, var->red.length, var->red.msb_right);
  66. printf("green.offset = %d length = %d msb_right = %d\n",
  67. var->green.offset, var->green.length, var->green.msb_right);
  68. printf("blue.offset = %d length = %d msb_right = %d\n",
  69. var->blue.offset, var->blue.length, var->blue.msb_right);
  70. printf("transp.offset = %d length = %d msb_right = %d\n",
  71. var->transp.offset, var->transp.length, var->transp.msb_right);
  72. printf("nonstd = %d\n", var->nonstd);
  73. printf("activate = %d\n", var->activate);
  74. printf("height = %d mm\n", var->height);
  75. printf("width = %d mm\n", var->width);
  76. printf("accel_flags = 0x%x\n", var->accel_flags);
  77. printf("pixclock = %d\n", var->pixclock);
  78. printf("left_margin = %d\n", var->left_margin);
  79. printf("right_margin = %d\n", var->right_margin);
  80. printf("upper_margin = %d\n", var->upper_margin);
  81. printf("lower_margin = %d\n", var->lower_margin);
  82. printf("hsync_len = %d\n", var->hsync_len);
  83. printf("vsync_len = %d\n", var->vsync_len);
  84. printf("sync = %d\n", var->sync);
  85. printf("vmode = %d\n", var->vmode);
  86. }
  87. static void
  88. signal_handler(int signumber)
  89. {
  90. signal(signumber, SIG_IGN); /* prevent recursion! */
  91. fprintf(stderr, "error: got signal %d (exiting)\n", signumber);
  92. exit(1);
  93. }
  94. static void
  95. initialize_fbdev( void )
  96. {
  97. char ttystr[1000];
  98. int fd, vtnumber, ttyfd;
  99. int sz;
  100. if (geteuid()) {
  101. fprintf(stderr, "error: you need to be root\n");
  102. exit(1);
  103. }
  104. #if 1
  105. /* open the framebuffer device */
  106. FrameBufferFD = open("/dev/fb0", O_RDWR);
  107. if (FrameBufferFD < 0) {
  108. fprintf(stderr, "Error opening /dev/fb0: %s\n", strerror(errno));
  109. exit(1);
  110. }
  111. #endif
  112. /* open /dev/tty0 and get the vt number */
  113. if ((fd = open("/dev/tty0", O_WRONLY, 0)) < 0) {
  114. fprintf(stderr, "error opening /dev/tty0\n");
  115. exit(1);
  116. }
  117. if (ioctl(fd, VT_OPENQRY, &vtnumber) < 0 || vtnumber < 0) {
  118. fprintf(stderr, "error: couldn't get a free vt\n");
  119. exit(1);
  120. }
  121. close(fd);
  122. /* open the console tty */
  123. sprintf(ttystr, "/dev/tty%d", vtnumber); /* /dev/tty1-64 */
  124. ConsoleFD = open(ttystr, O_RDWR | O_NDELAY, 0);
  125. if (ConsoleFD < 0) {
  126. fprintf(stderr, "error couldn't open console fd\n");
  127. exit(1);
  128. }
  129. /* save current vt number */
  130. {
  131. struct vt_stat vts;
  132. if (ioctl(ConsoleFD, VT_GETSTATE, &vts) == 0)
  133. OriginalVT = vts.v_active;
  134. }
  135. /* disconnect from controlling tty */
  136. ttyfd = open("/dev/tty", O_RDWR);
  137. if (ttyfd >= 0) {
  138. ioctl(ttyfd, TIOCNOTTY, 0);
  139. close(ttyfd);
  140. }
  141. /* some magic to restore the vt when we exit */
  142. {
  143. struct vt_mode vt;
  144. if (ioctl(ConsoleFD, VT_ACTIVATE, vtnumber) != 0)
  145. printf("ioctl VT_ACTIVATE: %s\n", strerror(errno));
  146. if (ioctl(ConsoleFD, VT_WAITACTIVE, vtnumber) != 0)
  147. printf("ioctl VT_WAITACTIVE: %s\n", strerror(errno));
  148. if (ioctl(ConsoleFD, VT_GETMODE, &vt) < 0) {
  149. fprintf(stderr, "error: ioctl VT_GETMODE: %s\n", strerror(errno));
  150. exit(1);
  151. }
  152. vt.mode = VT_PROCESS;
  153. vt.relsig = SIGUSR1;
  154. vt.acqsig = SIGUSR1;
  155. if (ioctl(ConsoleFD, VT_SETMODE, &vt) < 0) {
  156. fprintf(stderr, "error: ioctl(VT_SETMODE) failed: %s\n",
  157. strerror(errno));
  158. exit(1);
  159. }
  160. }
  161. /* go into graphics mode */
  162. if (ioctl(ConsoleFD, KDSETMODE, KD_GRAPHICS) < 0) {
  163. fprintf(stderr, "error: ioctl(KDSETMODE, KD_GRAPHICS) failed: %s\n",
  164. strerror(errno));
  165. exit(1);
  166. }
  167. #if 0
  168. /* open the framebuffer device */
  169. FrameBufferFD = open("/dev/fb0", O_RDWR);
  170. if (FrameBufferFD < 0) {
  171. fprintf(stderr, "Error opening /dev/fb0: %s\n", strerror(errno));
  172. exit(1);
  173. }
  174. #endif
  175. /* Get the fixed screen info */
  176. if (ioctl(FrameBufferFD, FBIOGET_FSCREENINFO, &FixedInfo)) {
  177. fprintf(stderr, "error: ioctl(FBIOGET_FSCREENINFO) failed: %s\n",
  178. strerror(errno));
  179. exit(1);
  180. }
  181. print_fixed_info(&FixedInfo, "Fixed");
  182. /* get the variable screen info */
  183. if (ioctl(FrameBufferFD, FBIOGET_VSCREENINFO, &OrigVarInfo)) {
  184. fprintf(stderr, "error: ioctl(FBIOGET_VSCREENINFO) failed: %s\n",
  185. strerror(errno));
  186. exit(1);
  187. }
  188. print_var_info(&OrigVarInfo, "Orig Var");
  189. /* operate on a copy */
  190. VarInfo = OrigVarInfo;
  191. /* set the depth, resolution, etc */
  192. DesiredDepth = 32;
  193. if (DesiredDepth)
  194. VarInfo.bits_per_pixel = DesiredDepth;
  195. if (VarInfo.bits_per_pixel == 16) {
  196. VarInfo.red.offset = 11;
  197. VarInfo.green.offset = 5;
  198. VarInfo.blue.offset = 0;
  199. VarInfo.red.length = 5;
  200. VarInfo.green.length = 6;
  201. VarInfo.blue.length = 5;
  202. VarInfo.transp.offset = 0;
  203. VarInfo.transp.length = 0;
  204. }
  205. else if (VarInfo.bits_per_pixel == 32) {
  206. VarInfo.red.offset = 16;
  207. VarInfo.green.offset = 8;
  208. VarInfo.blue.offset = 0;
  209. VarInfo.transp.offset = 24;
  210. VarInfo.red.length = 8;
  211. VarInfo.green.length = 8;
  212. VarInfo.blue.length = 8;
  213. VarInfo.transp.length = 8;
  214. }
  215. /* timing values taken from /etc/fb.modes (1280x1024 @ 75Hz) */
  216. VarInfo.xres_virtual = VarInfo.xres = 1280;
  217. VarInfo.yres_virtual = VarInfo.yres = 1024;
  218. VarInfo.pixclock = 7408;
  219. VarInfo.left_margin = 248;
  220. VarInfo.right_margin = 16;
  221. VarInfo.upper_margin = 38;
  222. VarInfo.lower_margin = 1;
  223. VarInfo.hsync_len = 144;
  224. VarInfo.vsync_len = 3;
  225. VarInfo.xoffset = 0;
  226. VarInfo.yoffset = 0;
  227. VarInfo.nonstd = 0;
  228. VarInfo.vmode &= ~FB_VMODE_YWRAP; /* turn off scrolling */
  229. /* set new variable screen info */
  230. if (ioctl(FrameBufferFD, FBIOPUT_VSCREENINFO, &VarInfo)) {
  231. fprintf(stderr, "ioctl(FBIOPUT_VSCREENINFO failed): %s\n",
  232. strerror(errno));
  233. exit(1);
  234. }
  235. print_var_info(&VarInfo, "New Var");
  236. if (FixedInfo.visual != FB_VISUAL_TRUECOLOR &&
  237. FixedInfo.visual != FB_VISUAL_DIRECTCOLOR) {
  238. fprintf(stderr, "non-TRUE/DIRECT-COLOR visuals (0x%x) not supported by this demo.\n", FixedInfo.visual);
  239. exit(1);
  240. }
  241. /* initialize colormap */
  242. if (FixedInfo.visual == FB_VISUAL_DIRECTCOLOR) {
  243. struct fb_cmap cmap;
  244. unsigned short red[256], green[256], blue[256];
  245. int i;
  246. /* we're assuming 256 entries here */
  247. printf("initializing directcolor colormap\n");
  248. cmap.start = 0;
  249. cmap.len = 256;
  250. cmap.red = red;
  251. cmap.green = green;
  252. cmap.blue = blue;
  253. cmap.transp = NULL;
  254. for (i = 0; i < cmap.len; i++) {
  255. red[i] = green[i] = blue[i] = (i << 8) | i;
  256. }
  257. if (ioctl(FrameBufferFD, FBIOPUTCMAP, (void *) &cmap) < 0) {
  258. fprintf(stderr, "ioctl(FBIOPUTCMAP) failed [%d]\n", i);
  259. }
  260. }
  261. /*
  262. * fbdev says the frame buffer is at offset zero, and the mmio region
  263. * is immediately after.
  264. */
  265. /* mmap the framebuffer into our address space */
  266. FrameBuffer = (caddr_t) mmap(0, /* start */
  267. FixedInfo.smem_len, /* bytes */
  268. PROT_READ | PROT_WRITE, /* prot */
  269. MAP_SHARED, /* flags */
  270. FrameBufferFD, /* fd */
  271. 0 /* offset */);
  272. if (FrameBuffer == (caddr_t) - 1) {
  273. fprintf(stderr, "error: unable to mmap framebuffer: %s\n",
  274. strerror(errno));
  275. exit(1);
  276. }
  277. printf("FrameBuffer = %p\n", FrameBuffer);
  278. #if 1
  279. /* mmap the MMIO region into our address space */
  280. MMIOAddress = (caddr_t) mmap(0, /* start */
  281. FixedInfo.mmio_len, /* bytes */
  282. PROT_READ | PROT_WRITE, /* prot */
  283. MAP_SHARED, /* flags */
  284. FrameBufferFD, /* fd */
  285. FixedInfo.smem_len /* offset */);
  286. if (MMIOAddress == (caddr_t) - 1) {
  287. fprintf(stderr, "error: unable to mmap mmio region: %s\n",
  288. strerror(errno));
  289. }
  290. printf("MMIOAddress = %p\n", MMIOAddress);
  291. /* try out some simple MMIO register reads */
  292. if (1)
  293. {
  294. typedef unsigned int CARD32;
  295. typedef unsigned char CARD8;
  296. #define RADEON_CONFIG_MEMSIZE 0x00f8
  297. #define RADEON_MEM_SDRAM_MODE_REG 0x0158
  298. #define MMIO_IN32(base, offset) \
  299. *(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset))
  300. #define INREG(addr) MMIO_IN32(MMIOAddress, addr)
  301. int sz, type;
  302. const char *typeStr[] = {"SDR", "DDR", "64-bit SDR"};
  303. sz = INREG(RADEON_CONFIG_MEMSIZE);
  304. type = INREG(RADEON_MEM_SDRAM_MODE_REG);
  305. printf("RADEON_CONFIG_MEMSIZE = %d (%d MB)\n", sz, sz / 1024 / 1024);
  306. printf("RADEON_MEM_SDRAM_MODE_REG >> 30 = %d (%s)\n",
  307. type >> 30, typeStr[type>>30]);
  308. }
  309. #endif
  310. }
  311. static void
  312. shutdown_fbdev( void )
  313. {
  314. struct vt_mode VT;
  315. printf("cleaning up...\n");
  316. /* restore original variable screen info */
  317. if (ioctl(FrameBufferFD, FBIOPUT_VSCREENINFO, &OrigVarInfo)) {
  318. fprintf(stderr, "ioctl(FBIOPUT_VSCREENINFO failed): %s\n",
  319. strerror(errno));
  320. exit(1);
  321. }
  322. munmap(MMIOAddress, FixedInfo.mmio_len);
  323. munmap(FrameBuffer, FixedInfo.smem_len);
  324. close(FrameBufferFD);
  325. /* restore text mode */
  326. ioctl(ConsoleFD, KDSETMODE, KD_TEXT);
  327. /* set vt */
  328. if (ioctl(ConsoleFD, VT_GETMODE, &VT) != -1) {
  329. VT.mode = VT_AUTO;
  330. ioctl(ConsoleFD, VT_SETMODE, &VT);
  331. }
  332. /* restore original vt */
  333. if (OriginalVT >= 0) {
  334. ioctl(ConsoleFD, VT_ACTIVATE, OriginalVT);
  335. OriginalVT = -1;
  336. }
  337. close(ConsoleFD);
  338. }
  339. static void
  340. gltest( void )
  341. {
  342. static const int attribs[] = {
  343. GLFBDEV_DOUBLE_BUFFER,
  344. GLFBDEV_DEPTH_SIZE, 16,
  345. GLFBDEV_NONE
  346. };
  347. GLFBDevContextPtr ctx;
  348. GLFBDevBufferPtr buf;
  349. GLFBDevVisualPtr vis;
  350. int bytes, r, g, b, a;
  351. float ang;
  352. printf("GLFBDEV_VENDOR = %s\n", glFBDevGetString(GLFBDEV_VENDOR));
  353. printf("GLFBDEV_VERSION = %s\n", glFBDevGetString(GLFBDEV_VERSION));
  354. /* framebuffer size */
  355. bytes = VarInfo.xres_virtual * VarInfo.yres_virtual * VarInfo.bits_per_pixel / 8;
  356. vis = glFBDevCreateVisual( &FixedInfo, &VarInfo, attribs );
  357. assert(vis);
  358. buf = glFBDevCreateBuffer( &FixedInfo, &VarInfo, vis, FrameBuffer, NULL, bytes );
  359. assert(buf);
  360. ctx = glFBDevCreateContext( vis, NULL );
  361. assert(buf);
  362. b = glFBDevMakeCurrent( ctx, buf, buf );
  363. assert(b);
  364. /*printf("GL_EXTENSIONS: %s\n", glGetString(GL_EXTENSIONS));*/
  365. glGetIntegerv(GL_RED_BITS, &r);
  366. glGetIntegerv(GL_GREEN_BITS, &g);
  367. glGetIntegerv(GL_BLUE_BITS, &b);
  368. glGetIntegerv(GL_ALPHA_BITS, &a);
  369. printf("RED_BITS=%d GREEN_BITS=%d BLUE_BITS=%d ALPHA_BITS=%d\n",
  370. r, g, b, a);
  371. glClearColor(0.5, 0.5, 1.0, 0);
  372. glMatrixMode(GL_PROJECTION);
  373. glLoadIdentity();
  374. glFrustum(-1, 1, -1, 1, 2, 30);
  375. glMatrixMode(GL_MODELVIEW);
  376. glLoadIdentity();
  377. glTranslatef(0, 0, -15);
  378. glViewport(0, 0, VarInfo.xres_virtual, VarInfo.yres_virtual);
  379. glEnable(GL_LIGHTING);
  380. glEnable(GL_LIGHT0);
  381. glEnable(GL_DEPTH_TEST);
  382. for (ang = 0; ang <= 180; ang += 15) {
  383. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  384. glPushMatrix();
  385. glRotatef(ang, 1, 0, 0);
  386. glutSolidTorus(1, 3, 40, 20);
  387. glPopMatrix();
  388. glFBDevSwapBuffers(buf);
  389. }
  390. /* clean up */
  391. b = glFBDevMakeCurrent( NULL, NULL, NULL);
  392. assert(b);
  393. glFBDevDestroyContext(ctx);
  394. glFBDevDestroyBuffer(buf);
  395. glFBDevDestroyVisual(vis);
  396. }
  397. int
  398. main( int argc, char *argv[] )
  399. {
  400. signal(SIGUSR1, signal_handler); /* exit if someone tries a vt switch */
  401. signal(SIGSEGV, signal_handler); /* catch segfaults */
  402. initialize_fbdev();
  403. gltest();
  404. shutdown_fbdev();
  405. return 0;
  406. }