comparison vidix/drivers/mach64_vid.c @ 4872:995ee733e8d4

YVU9 support fixing framesize & alignment setting colorkey at a more correct place
author michael
date Tue, 26 Feb 2002 22:15:08 +0000
parents 550e86ba0390
children 5320e2e683e8
comparison
equal deleted inserted replaced
4871:c156f5f5ef3a 4872:995ee733e8d4
179 } 179 }
180 180
181 static vidix_capability_t mach64_cap = 181 static vidix_capability_t mach64_cap =
182 { 182 {
183 "BES driver for Mach64/3DRage cards", 183 "BES driver for Mach64/3DRage cards",
184 "Nick Kurshev", 184 "Nick Kurshev and Michael Niedermayer",
185 TYPE_OUTPUT, 185 TYPE_OUTPUT,
186 { 0, 0, 0, 0 }, 186 { 0, 0, 0, 0 },
187 2048, 187 2048,
188 2048, 188 2048,
189 4, 189 4,
268 268
269 // lcd_gen_ctrl = ATIGetMach64LCDReg(LCD_GEN_CNTL); 269 // lcd_gen_ctrl = ATIGetMach64LCDReg(LCD_GEN_CNTL);
270 270
271 OUTREG(LCD_INDEX, lcd_index); 271 OUTREG(LCD_INDEX, lcd_index);
272 272
273 if(__verbose>VERBOSE_LEVEL) printf("[mach64] vertical stretching factor= %d\n", ret);
274
273 return ret; 275 return ret;
274 } 276 }
275 277
276 static void mach64_vid_make_default() 278 static void mach64_vid_make_default()
277 { 279 {
278 mach64_fifo_wait(2); 280 mach64_fifo_wait(5);
279 OUTREG(SCALER_COLOUR_CNTL,0x00101000); 281 OUTREG(SCALER_COLOUR_CNTL,0x00101000);
282
283 besr.ckey_on=0;
284 besr.graphics_key_msk=0;
285 besr.graphics_key_clr=0;
286
287 OUTREG(OVERLAY_GRAPHICS_KEY_MSK, besr.graphics_key_msk);
288 OUTREG(OVERLAY_GRAPHICS_KEY_CLR, besr.graphics_key_clr);
289 OUTREG(OVERLAY_KEY_CNTL,VIDEO_KEY_FN_TRUE|GRAPHIC_KEY_FN_EQ|CMP_MIX_AND);
290
280 } 291 }
281 292
282 static void mach64_vid_dump_regs( void ) 293 static void mach64_vid_dump_regs( void )
283 { 294 {
284 size_t i; 295 size_t i;
488 case IMGFMT_YV12: 499 case IMGFMT_YV12:
489 case IMGFMT_I420: 500 case IMGFMT_I420:
490 if(spy > 16 && spu == spy/2 && spv == spy/2) pitch = spy; 501 if(spy > 16 && spu == spy/2 && spv == spy/2) pitch = spy;
491 else pitch = 32; 502 else pitch = 32;
492 break; 503 break;
504 case IMGFMT_YVU9:
505 if(spy > 32 && spu == spy/4 && spv == spy/4) pitch = spy;
506 else pitch = 64;
507 break;
493 default: 508 default:
494 if(spy >= 16) pitch = spy; 509 if(spy >= 16) pitch = spy;
495 else pitch = 16; 510 else pitch = 16;
496 break; 511 break;
497 } 512 }
508 case IMGFMT_YV12: 523 case IMGFMT_YV12:
509 case IMGFMT_IYUV: 524 case IMGFMT_IYUV:
510 awidth = (info->src.w + (pitch-1)) & ~(pitch-1); 525 awidth = (info->src.w + (pitch-1)) & ~(pitch-1);
511 info->frame_size = awidth*(info->src.h+info->src.h/2); 526 info->frame_size = awidth*(info->src.h+info->src.h/2);
512 break; 527 break;
513 case IMGFMT_RGB32: 528 case IMGFMT_YVU9:
529 awidth = (info->src.w + (pitch-1)) & ~(pitch-1);
530 info->frame_size = awidth*(info->src.h+info->src.h/8);
531 break;
532 // case IMGFMT_RGB32:
514 case IMGFMT_BGR32: 533 case IMGFMT_BGR32:
515 awidth = (info->src.w*4 + (pitch-1)) & ~(pitch-1); 534 awidth = (info->src.w*4 + (pitch-1)) & ~(pitch-1);
516 info->frame_size = (awidth*info->src.h); 535 info->frame_size = (awidth*info->src.h);
517 break; 536 break;
518 /* YUY2 YVYU, RGB15, RGB16 */ 537 /* YUY2 YVYU, RGB15, RGB16 */
519 default: 538 default:
520 awidth = (info->src.w*2 + (pitch-1)) & ~(pitch-1); 539 awidth = (info->src.w*2 + (pitch-1)) & ~(pitch-1);
521 info->frame_size = (awidth*info->src.h); 540 info->frame_size = (awidth*info->src.h);
522 break; 541 break;
523 } 542 }
543 info->frame_size+=256; // so we have some space for alignment & such
544 info->frame_size&=~16;
524 } 545 }
525 546
526 static void mach64_vid_stop_video( void ) 547 static void mach64_vid_stop_video( void )
527 { 548 {
528 mach64_fifo_wait(14); 549 mach64_fifo_wait(14);
533 OUTREG(SCALER_H_COEFF1, 0x0D06200D); 554 OUTREG(SCALER_H_COEFF1, 0x0D06200D);
534 OUTREG(SCALER_H_COEFF2, 0x0D0A1C0D); 555 OUTREG(SCALER_H_COEFF2, 0x0D0A1C0D);
535 OUTREG(SCALER_H_COEFF3, 0x0C0E1A0C); 556 OUTREG(SCALER_H_COEFF3, 0x0C0E1A0C);
536 OUTREG(SCALER_H_COEFF4, 0x0C14140C); 557 OUTREG(SCALER_H_COEFF4, 0x0C14140C);
537 OUTREG(VIDEO_FORMAT, 0xB000B); 558 OUTREG(VIDEO_FORMAT, 0xB000B);
538 OUTREG(OVERLAY_GRAPHICS_KEY_MSK, 0);
539 OUTREG(OVERLAY_GRAPHICS_KEY_CLR, 0);
540 OUTREG(OVERLAY_KEY_CNTL, 0x50);
541 OUTREG(OVERLAY_TEST, 0x0); 559 OUTREG(OVERLAY_TEST, 0x0);
542 } 560 }
543 561
544 static void mach64_vid_display_video( void ) 562 static void mach64_vid_display_video( void )
545 { 563 {
567 // bit 5-6 gamma correction 585 // bit 5-6 gamma correction
568 // bit 7 nothing visible if set 586 // bit 7 nothing visible if set
569 // bit 8-27 no effect 587 // bit 8-27 no effect
570 // bit 28-31 nothing interresting just crashed my system when i played with them :( 588 // bit 28-31 nothing interresting just crashed my system when i played with them :(
571 589
572 mach64_fifo_wait(3);
573 OUTREG(OVERLAY_GRAPHICS_KEY_MSK, besr.graphics_key_msk);
574 OUTREG(OVERLAY_GRAPHICS_KEY_CLR, besr.graphics_key_clr);
575 // OUTREG(OVERLAY_VIDEO_KEY_MSK, 0x80);
576 // OUTREG(OVERLAY_VIDEO_KEY_CLR, 0x80);
577 if(besr.ckey_on)
578 OUTREG(OVERLAY_KEY_CNTL,VIDEO_KEY_FN_TRUE|GRAPHIC_KEY_FN_EQ|CMP_MIX_AND);
579 else
580 OUTREG(OVERLAY_KEY_CNTL,VIDEO_KEY_FN_TRUE|GRAPHIC_KEY_FN_TRUE|CMP_MIX_AND);
581
582 mach64_wait_for_idle(); 590 mach64_wait_for_idle();
583 vf = INREG(VIDEO_FORMAT); 591 vf = INREG(VIDEO_FORMAT);
584 592
585 // Bits 16-19 seem to select the format 593 // Bits 16-19 seem to select the format
586 // 0x0 dunno behaves strange 594 // 0x0 dunno behaves strange
611 case IMGFMT_BGR32: OUTREG(VIDEO_FORMAT, 0x00060000); break; 619 case IMGFMT_BGR32: OUTREG(VIDEO_FORMAT, 0x00060000); break;
612 /* 4:2:0 */ 620 /* 4:2:0 */
613 case IMGFMT_IYUV: 621 case IMGFMT_IYUV:
614 case IMGFMT_I420: 622 case IMGFMT_I420:
615 case IMGFMT_YV12: OUTREG(VIDEO_FORMAT, 0x000A0000); break; 623 case IMGFMT_YV12: OUTREG(VIDEO_FORMAT, 0x000A0000); break;
624
625 case IMGFMT_YVU9: OUTREG(VIDEO_FORMAT, 0x00090000); break;
616 /* 4:2:2 */ 626 /* 4:2:2 */
617 case IMGFMT_YVYU: 627 case IMGFMT_YVYU:
618 case IMGFMT_UYVY: OUTREG(VIDEO_FORMAT, 0x000C0000); break; 628 case IMGFMT_UYVY: OUTREG(VIDEO_FORMAT, 0x000C0000); break;
619 case IMGFMT_YUY2: 629 case IMGFMT_YUY2:
620 default: OUTREG(VIDEO_FORMAT, 0x000B0000); break; 630 default: OUTREG(VIDEO_FORMAT, 0x000B0000); break;
626 { 636 {
627 uint32_t src_w,src_h,dest_w,dest_h,pitch,h_inc,v_inc,left,leftUV,top,ecp,y_pos; 637 uint32_t src_w,src_h,dest_w,dest_h,pitch,h_inc,v_inc,left,leftUV,top,ecp,y_pos;
628 int is_420,best_pitch,mpitch; 638 int is_420,best_pitch,mpitch;
629 int src_offset_y, src_offset_u, src_offset_v; 639 int src_offset_y, src_offset_u, src_offset_v;
630 unsigned int i; 640 unsigned int i;
631 641
632 mach64_vid_stop_video(); 642 mach64_vid_stop_video();
633 /* warning, if left or top are != 0 this will fail, as the framesize is too small then */ 643 /* warning, if left or top are != 0 this will fail, as the framesize is too small then */
634 left = config->src.x; 644 left = config->src.x;
635 top = config->src.y; 645 top = config->src.y;
636 src_h = config->src.h; 646 src_h = config->src.h;
641 config->fourcc == IMGFMT_IYUV) is_420 = 1; 651 config->fourcc == IMGFMT_IYUV) is_420 = 1;
642 best_pitch = mach64_query_pitch(config->fourcc,&config->src.pitch); 652 best_pitch = mach64_query_pitch(config->fourcc,&config->src.pitch);
643 mpitch = best_pitch-1; 653 mpitch = best_pitch-1;
644 switch(config->fourcc) 654 switch(config->fourcc)
645 { 655 {
656 case IMGFMT_YVU9:
646 /* 4:2:0 */ 657 /* 4:2:0 */
647 case IMGFMT_IYUV: 658 case IMGFMT_IYUV:
648 case IMGFMT_YV12: 659 case IMGFMT_YV12:
649 case IMGFMT_I420: pitch = (src_w + mpitch) & ~mpitch; 660 case IMGFMT_I420: pitch = (src_w + mpitch) & ~mpitch;
650 config->dest.pitch.y = 661 config->dest.pitch.y =
684 /* keep everything in 16.16 */ 695 /* keep everything in 16.16 */
685 config->offsets[0] = 0; 696 config->offsets[0] = 0;
686 for(i=1; i<config->num_frames; i++) 697 for(i=1; i<config->num_frames; i++)
687 config->offsets[i] = config->offsets[i-1] + config->frame_size; 698 config->offsets[i] = config->offsets[i-1] + config->frame_size;
688 699
700 /*FIXME the left / top stuff is broken (= zoom a src rectangle from a larger one)
701 1. the framesize isnt known as the outer src rectangle dimensions arent known
702 2. the mach64 needs aligned addresses so it cant work anyway
703 -> so we could shift the outer buffer to compensate that but that would mean
704 alignment problems for the code which writes into it
705 */
706
689 if(is_420) 707 if(is_420)
690 { 708 {
691 config->offset.y= 0; 709 config->offset.y= 0;
692 config->offset.u= pitch*src_h; // FIXME wrong? 710 config->offset.u= (pitch*src_h + 15)&~15;
693 config->offset.v= config->offset.u + (pitch*src_h>>2); // FIXME wrong? 711 config->offset.v= (config->offset.u + (pitch*src_h>>2) + 15)&~15;
694 //FIXME align & fix framesize 712
695
696 src_offset_y= config->offset.y + top*pitch + left; 713 src_offset_y= config->offset.y + top*pitch + left;
697 src_offset_u= config->offset.u + (top*pitch>>2) + (left>>1); 714 src_offset_u= config->offset.u + (top*pitch>>2) + (left>>1);
698 src_offset_v= config->offset.v + (top*pitch>>2) + (left>>1); 715 src_offset_v= config->offset.v + (top*pitch>>2) + (left>>1);
699 716
700 if(besr.fourcc == IMGFMT_I420 || besr.fourcc == IMGFMT_IYUV) 717 if(besr.fourcc == IMGFMT_I420 || besr.fourcc == IMGFMT_IYUV)
701 { 718 {
702 uint32_t tmp; 719 uint32_t tmp;
703 tmp = config->offset.u; 720 tmp = config->offset.u;
704 config->offset.u = config->offset.v; 721 config->offset.u = config->offset.v;
705 config->offset.v = tmp; 722 config->offset.v = tmp;
706 } 723 }
707 } 724 }
725 else if(besr.fourcc == IMGFMT_YVU9)
726 {
727 config->offset.y= 0;
728 config->offset.u= (pitch*src_h + 15)&~15;
729 config->offset.v= (config->offset.u + (pitch*src_h>>4) + 15)&~15;
730
731 src_offset_y= config->offset.y + top*pitch + left;
732 src_offset_u= config->offset.u + (top*pitch>>4) + (left>>1);
733 src_offset_v= config->offset.v + (top*pitch>>4) + (left>>1);
734 }
708 else if(besr.fourcc == IMGFMT_BGR32) 735 else if(besr.fourcc == IMGFMT_BGR32)
709 { 736 {
710 config->offset.y = config->offset.u = config->offset.v = 0; 737 config->offset.y = config->offset.u = config->offset.v = 0;
711 src_offset_y= src_offset_u= src_offset_v= (left << 2)&~15; 738 src_offset_y= src_offset_u= src_offset_v= top*pitch + (left << 2);
712 } 739 }
713 else 740 else
714 { 741 {
715 config->offset.y = config->offset.u = config->offset.v = 0; 742 config->offset.y = config->offset.u = config->offset.v = 0;
716 src_offset_y= src_offset_u= src_offset_v= (left << 1)&~15; 743 src_offset_y= src_offset_u= src_offset_v= top*pitch + (left << 1);
717 } 744 }
718 745
719 num_mach64_buffers= config->num_frames; 746 num_mach64_buffers= config->num_frames;
720 for(i=0; i<config->num_frames; i++) 747 for(i=0; i<config->num_frames; i++)
721 { 748 {
737 else 764 else
738 if(mach64_is_interlace()) y_pos/=2; 765 if(mach64_is_interlace()) y_pos/=2;
739 besr.y_x_end = y_pos | ((config->dest.x + dest_w) << 16); 766 besr.y_x_end = y_pos | ((config->dest.x + dest_w) << 16);
740 besr.height_width = ((src_w - left)<<16) | (src_h - top); 767 besr.height_width = ((src_w - left)<<16) | (src_h - top);
741 768
742 if(mach64_grkey.ckey.op == CKEY_TRUE)
743 {
744 besr.ckey_on=1;
745
746 switch(mach64_vid_get_dbpp())
747 {
748 case 15:
749 besr.graphics_key_msk=0x7FFF;
750 besr.graphics_key_clr=
751 ((mach64_grkey.ckey.blue &0xF8)>>3)
752 | ((mach64_grkey.ckey.green&0xF8)<<2)
753 | ((mach64_grkey.ckey.red &0xF8)<<7);
754 break;
755 case 16:
756 besr.graphics_key_msk=0xFFFF;
757 besr.graphics_key_clr=
758 ((mach64_grkey.ckey.blue &0xF8)>>3)
759 | ((mach64_grkey.ckey.green&0xFC)<<3)
760 | ((mach64_grkey.ckey.red &0xF8)<<8);
761 break;
762 case 24:
763 besr.graphics_key_msk=0xFFFFFF;
764 besr.graphics_key_clr=
765 ((mach64_grkey.ckey.blue &0xFF))
766 | ((mach64_grkey.ckey.green&0xFF)<<8)
767 | ((mach64_grkey.ckey.red &0xFF)<<16);
768 break;
769 case 32:
770 besr.graphics_key_msk=0xFFFFFF;
771 besr.graphics_key_clr=
772 ((mach64_grkey.ckey.blue &0xFF))
773 | ((mach64_grkey.ckey.green&0xFF)<<8)
774 | ((mach64_grkey.ckey.red &0xFF)<<16);
775 break;
776 default:
777 besr.ckey_on=0;
778 besr.graphics_key_msk=0;
779 besr.graphics_key_clr=0;
780 }
781 }
782 else
783 {
784 besr.ckey_on=0;
785 besr.graphics_key_msk=0;
786 besr.graphics_key_clr=0;
787 }
788
789 return 0; 769 return 0;
790 } 770 }
791 771
792 772
793 uint32_t supported_fourcc[] = 773 uint32_t supported_fourcc[] =
794 { 774 {
795 IMGFMT_YV12, IMGFMT_I420, IMGFMT_IYUV, 775 IMGFMT_YV12, IMGFMT_I420, IMGFMT_IYUV,
796 IMGFMT_UYVY, IMGFMT_YUY2, IMGFMT_YVYU, 776 IMGFMT_YVU9,
777 IMGFMT_UYVY, IMGFMT_YUY2,
797 IMGFMT_BGR15,IMGFMT_BGR16,IMGFMT_BGR32 778 IMGFMT_BGR15,IMGFMT_BGR16,IMGFMT_BGR32
798 }; 779 };
799 780
800 __inline__ static int is_supported_fourcc(uint32_t fourcc) 781 __inline__ static int is_supported_fourcc(uint32_t fourcc)
801 { 782 {
941 } 922 }
942 923
943 int vixSetGrKeys(const vidix_grkey_t *grkey) 924 int vixSetGrKeys(const vidix_grkey_t *grkey)
944 { 925 {
945 memcpy(&mach64_grkey, grkey, sizeof(vidix_grkey_t)); 926 memcpy(&mach64_grkey, grkey, sizeof(vidix_grkey_t));
927
928 if(mach64_grkey.ckey.op == CKEY_TRUE)
929 {
930 besr.ckey_on=1;
931
932 switch(mach64_vid_get_dbpp())
933 {
934 case 15:
935 besr.graphics_key_msk=0x7FFF;
936 besr.graphics_key_clr=
937 ((mach64_grkey.ckey.blue &0xF8)>>3)
938 | ((mach64_grkey.ckey.green&0xF8)<<2)
939 | ((mach64_grkey.ckey.red &0xF8)<<7);
940 break;
941 case 16:
942 besr.graphics_key_msk=0xFFFF;
943 besr.graphics_key_clr=
944 ((mach64_grkey.ckey.blue &0xF8)>>3)
945 | ((mach64_grkey.ckey.green&0xFC)<<3)
946 | ((mach64_grkey.ckey.red &0xF8)<<8);
947 break;
948 case 24:
949 besr.graphics_key_msk=0xFFFFFF;
950 besr.graphics_key_clr=
951 ((mach64_grkey.ckey.blue &0xFF))
952 | ((mach64_grkey.ckey.green&0xFF)<<8)
953 | ((mach64_grkey.ckey.red &0xFF)<<16);
954 break;
955 case 32:
956 besr.graphics_key_msk=0xFFFFFF;
957 besr.graphics_key_clr=
958 ((mach64_grkey.ckey.blue &0xFF))
959 | ((mach64_grkey.ckey.green&0xFF)<<8)
960 | ((mach64_grkey.ckey.red &0xFF)<<16);
961 break;
962 default:
963 besr.ckey_on=0;
964 besr.graphics_key_msk=0;
965 besr.graphics_key_clr=0;
966 }
967 }
968 else
969 {
970 besr.ckey_on=0;
971 besr.graphics_key_msk=0;
972 besr.graphics_key_clr=0;
973 }
974
975 mach64_fifo_wait(4);
976 OUTREG(OVERLAY_GRAPHICS_KEY_MSK, besr.graphics_key_msk);
977 OUTREG(OVERLAY_GRAPHICS_KEY_CLR, besr.graphics_key_clr);
978 // OUTREG(OVERLAY_VIDEO_KEY_MSK, 0);
979 // OUTREG(OVERLAY_VIDEO_KEY_CLR, 0);
980 if(besr.ckey_on)
981 OUTREG(OVERLAY_KEY_CNTL,VIDEO_KEY_FN_TRUE|GRAPHIC_KEY_FN_EQ|CMP_MIX_AND);
982 else
983 OUTREG(OVERLAY_KEY_CNTL,VIDEO_KEY_FN_TRUE|GRAPHIC_KEY_FN_TRUE|CMP_MIX_AND);
984
946 return(0); 985 return(0);
947 } 986 }