Mercurial > mplayer.hg
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 } |