comparison vidix/drivers/nvidia_vid.c @ 10970:de7036f31e5a

Sometimes (especially with big images) reading pitch 0 from card's register returns 0 (probably due to full card's FIFO), which leads to SIGFPE later. Fixed (or workarounded) by rereading pitch0, until it's not zero.
author lumag
date Wed, 01 Oct 2003 21:03:00 +0000
parents 4d4d0c1c7142
children 3da6b1de1c33
comparison
equal deleted inserted replaced
10969:667d39c4dc8c 10970:de7036f31e5a
417 int lwidth=info->d_width, lheight=info->d_height; 417 int lwidth=info->d_width, lheight=info->d_height;
418 int bps; 418 int bps;
419 419
420 /*update depth & dimensions here because it may change with vo vesa or vo fbdev*/ 420 /*update depth & dimensions here because it may change with vo vesa or vo fbdev*/
421 info->chip.lock (&info->chip, 0); 421 info->chip.lock (&info->chip, 0);
422 do {
422 switch (info->chip.arch) { 423 switch (info->chip.arch) {
423 case NV_ARCH_03: 424 case NV_ARCH_03:
424 pitch0 = info->chip.PGRAPH[0x00000650/4]; 425 pitch0 = info->chip.PGRAPH[0x00000650/4];
425 break; 426 break;
426 case NV_ARCH_04: 427 case NV_ARCH_04:
428 case NV_ARCH_20: 429 case NV_ARCH_20:
429 case NV_ARCH_30: 430 case NV_ARCH_30:
430 pitch0 = info->chip.PGRAPH[0x00000670/4]; 431 pitch0 = info->chip.PGRAPH[0x00000670/4];
431 break; 432 break;
432 } 433 }
434 if (pitch0 == 0)
435 printf("[nvidia_vid]: pitch0 = 0!!! Rereading\n");
436 } while (pitch0 == 0);
433 VID_WR08(info->chip.PCIO, 0x03D4, 0x28); 437 VID_WR08(info->chip.PCIO, 0x03D4, 0x28);
434 bpp = VID_RD08(info->chip.PCIO,0x03D5); 438 bpp = VID_RD08(info->chip.PCIO,0x03D5);
435 if(bpp==3)bpp = 4; //fixme do nvidia cards support 24bpp? 439 if(bpp==3)bpp = 4; //fixme do nvidia cards support 24bpp?
436 if((bpp == 2) && (info->chip.PVIDEO[0x00000600/4] & 0x00001000) == 0x0)info->depth=15; //0x00101100 for BGR16 440 if((bpp == 2) && (info->chip.PVIDEO[0x00000600/4] & 0x00001000) == 0x0)info->depth=15; //0x00101100 for BGR16
437 else info->depth = bpp*8; 441 else info->depth = bpp*8;
438 if(!bpp)printf("[nvidia_vid] error invalid bpp\n"); 442 if(!bpp)printf("[nvidia_vid] error invalid bpp\n");
439 else 443 else
440 { 444 {
441 // printf("[nvidia_vid] video mode: %ux%u@%u\n",screen_x = pitch0/bpp,(pitch0/bpp*3)/4,info->depth); 445 // printf("[nvidia_vid] video mode: %ux%u@%u\n",info->screen_x = pitch0/bpp,(pitch0/bpp*3)/4,info->depth);
442 info->screen_x = pitch0/bpp; 446 info->screen_x = pitch0/bpp;
443 } 447 }
444 448
445 bps = info->screen_x * ((info->depth+1)/8); 449 bps = info->screen_x * ((info->depth+1)/8);
446 /* get pan offset of the physical screen */ 450 /* get pan offset of the physical screen */
671 675
672 /*get some info about the screen dimension and depth*/ 676 /*get some info about the screen dimension and depth*/
673 { 677 {
674 uint32_t bpp=0,pitch0=0; 678 uint32_t bpp=0,pitch0=0;
675 info->chip.lock (&info->chip, 0); 679 info->chip.lock (&info->chip, 0);
680 do {
676 switch (info->chip.arch) { 681 switch (info->chip.arch) {
677 case NV_ARCH_03: 682 case NV_ARCH_03:
678 pitch0 = info->chip.PGRAPH[0x00000650/4]; 683 pitch0 = info->chip.PGRAPH[0x00000650/4];
679 break; 684 break;
680 case NV_ARCH_04: 685 case NV_ARCH_04:
682 case NV_ARCH_20: 687 case NV_ARCH_20:
683 case NV_ARCH_30: 688 case NV_ARCH_30:
684 pitch0 = info->chip.PGRAPH[0x00000670/4]; 689 pitch0 = info->chip.PGRAPH[0x00000670/4];
685 break; 690 break;
686 } 691 }
692 if (pitch0 == 0)
693 printf("[nvidia_vid]: pitch0 = 0!!! Rereading\n");
694 } while (pitch0 == 0);
687 VID_WR08(info->chip.PCIO, 0x03D4, 0x28); 695 VID_WR08(info->chip.PCIO, 0x03D4, 0x28);
688 bpp = VID_RD08(info->chip.PCIO,0x03D5); 696 bpp = VID_RD08(info->chip.PCIO,0x03D5);
689 if(bpp==3)bpp = 4; //fixme do nvidia cards support 24bpp? 697 if(bpp==3)bpp = 4; //fixme do nvidia cards support 24bpp?
690 if((bpp == 2) && (info->chip.PVIDEO[0x00000600/4] & 0x00001000) == 0x0)info->depth=15; //0x00101100 for BGR16 698 if((bpp == 2) && (info->chip.PVIDEO[0x00000600/4] & 0x00001000) == 0x0)info->depth=15; //0x00101100 for BGR16
691 else info->depth = bpp*8; 699 else info->depth = bpp*8;